From d5cc92e6bac78fdab61b50fb186e97a01db67101 Mon Sep 17 00:00:00 2001 From: TheXamlGuy Date: Sat, 6 Jan 2024 19:21:38 +0000 Subject: [PATCH] Add a factory for populating view models --- .../ContextualWidgetViewModel.cs | 12 +- Hyperbar.Windows.Interopq/HwndExtensions.cs | 94 --- .../Hyperbar.Windows.Interop.csproj | 13 - Hyperbar.Windows.Interopq/IVirtualKeyboard.cs | 7 - Hyperbar.Windows.Interopq/NativeMethods.txt | 59 -- Hyperbar.Windows.Interopq/PInvoke.cs | 559 ------------------ Hyperbar.Windows.Interopq/VirtualKeyboard.cs | 84 --- Hyperbar.Windows.Interopq/WindowStyle.cs | 31 - .../PrimaryWidgetProvider.cs | 2 + .../PrimaryWidgetViewModel.cs | 16 +- .../PrimaryWidgetViewModelFactory.cs | 25 + .../Commands/KeyAcceleratorCommandHandler.cs | 3 +- Hyperbar.Windows/Views/CommandViewModel.cs | 10 +- .../IServiceCollectionExtensions.cs | 44 +- Hyperbar/Views/IViewModelFactory.cs | 6 + .../Views/ObservableCollectionViewModel.cs | 16 +- Hyperbar/Views/WidgetViewModelBase.cs | 10 - 17 files changed, 86 insertions(+), 905 deletions(-) delete mode 100644 Hyperbar.Windows.Interopq/HwndExtensions.cs delete mode 100644 Hyperbar.Windows.Interopq/Hyperbar.Windows.Interop.csproj delete mode 100644 Hyperbar.Windows.Interopq/IVirtualKeyboard.cs delete mode 100644 Hyperbar.Windows.Interopq/NativeMethods.txt delete mode 100644 Hyperbar.Windows.Interopq/PInvoke.cs delete mode 100644 Hyperbar.Windows.Interopq/VirtualKeyboard.cs delete mode 100644 Hyperbar.Windows.Interopq/WindowStyle.cs create mode 100644 Hyperbar.Windows.Primary/PrimaryWidgetViewModelFactory.cs create mode 100644 Hyperbar/Views/IViewModelFactory.cs delete mode 100644 Hyperbar/Views/WidgetViewModelBase.cs diff --git a/Hyperbar.Windows.Contextual/ContextualWidgetViewModel.cs b/Hyperbar.Windows.Contextual/ContextualWidgetViewModel.cs index 31e0af0..7127b49 100644 --- a/Hyperbar.Windows.Contextual/ContextualWidgetViewModel.cs +++ b/Hyperbar.Windows.Contextual/ContextualWidgetViewModel.cs @@ -1,12 +1,16 @@ namespace Hyperbar.Widget.Contextual; public class ContextualWidgetViewModel : - WidgetViewModelBase + ObservableCollectionViewModel, + IWidgetViewModel, + ITemplatedViewModel { public ContextualWidgetViewModel(ITemplateFactory templateFactory, - IServiceFactory serviceFactory) : base(templateFactory, serviceFactory) + IServiceFactory serviceFactory, + IEnumerable items) : base(serviceFactory, items) { - Add(); - Add(); + TemplateFactory = templateFactory; } + + public ITemplateFactory TemplateFactory { get; } } \ No newline at end of file diff --git a/Hyperbar.Windows.Interopq/HwndExtensions.cs b/Hyperbar.Windows.Interopq/HwndExtensions.cs deleted file mode 100644 index 8c323f4..0000000 --- a/Hyperbar.Windows.Interopq/HwndExtensions.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using Windows.Win32; -using Windows.Win32.Foundation; -using Windows.Win32.Graphics.Gdi; -using Windows.Win32.UI.WindowsAndMessaging; - -namespace Hyperbar.Windows.Interop; - -public static class HwndExtensions -{ - [Flags] - private enum WindowStyles - { - WS_EX_LAYERED = 0x80000 - } - - public static void SetWindowOpacity(this IntPtr hWnd, - byte value) - { - HWND hWND = new(hWnd); - WindowStyles windowLong = (WindowStyles)PInvoke.GetWindowLong(hWND, WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE); - if (!windowLong.HasFlag(WindowStyles.WS_EX_LAYERED)) - { - PInvoke.SetWindowLong(hWND, WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)(windowLong | WindowStyles.WS_EX_LAYERED)); - } - - if (!PInvoke.SetLayeredWindowAttributes(hWND, 0u, value, LAYERED_WINDOW_ATTRIBUTES_FLAGS.LWA_ALPHA)) - { - Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error()); - } - } - - public static void SetWindowStyle(this IntPtr hwnd, - WindowStyle newStyle) - { - int windowLong = PInvoke.GetWindowLong(new HWND(hwnd), WINDOW_LONG_PTR_INDEX.GWL_STYLE); - if (PInvoke.SetWindowLong(new HWND(hwnd), WINDOW_LONG_PTR_INDEX.GWL_STYLE, (int)newStyle) != windowLong) - { - Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error()); - } - - PInvoke.SetWindowPos(new HWND(hwnd), new HWND(0), 0, 0, 0, 0, SET_WINDOW_POS_FLAGS.SWP_DRAWFRAME | SET_WINDOW_POS_FLAGS.SWP_NOMOVE | SET_WINDOW_POS_FLAGS.SWP_NOOWNERZORDER | SET_WINDOW_POS_FLAGS.SWP_NOSIZE | SET_WINDOW_POS_FLAGS.SWP_NOZORDER); - } - - public static void SnapWindow(this IntPtr hwnd, - int placement, - double? width = null, - double? height = null) - { - HMONITOR hwndDesktop = PInvoke.MonitorFromWindow(new(hwnd), MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST); - MONITORINFO info = new() - { - cbSize = 40 - }; - - PInvoke.GetMonitorInfo(hwndDesktop, ref info); - - uint dpi = PInvoke.GetDpiForWindow(new HWND(hwnd)); - PInvoke.GetWindowRect(new HWND(hwnd), out RECT windowRect); - - double scalingFactor = dpi / 96d; - int actualWidth = width.HasValue ? (int)(width * scalingFactor) : windowRect.right - windowRect.left; - int actualHeight = height.HasValue ? (int)(height * scalingFactor) : windowRect.bottom - windowRect.top; - - int left = 0; - int top = 0; - - switch (placement) - { - case 0: - left = 0; - top = (info.rcWork.bottom + info.rcWork.top) / 2 - actualHeight / 2; - break; - - case 1: - left = (info.rcWork.left + info.rcWork.right) / 2 - actualWidth / 2; - top = 0; - break; - - case 2: - left = info.rcWork.left + info.rcWork.right - actualWidth; - top = (info.rcWork.bottom + info.rcWork.top) / 2 - actualHeight / 2; - break; - - case 3: - left = (info.rcWork.left + info.rcWork.right) / 2 - actualWidth / 2; - top = info.rcWork.bottom + info.rcWork.top - actualHeight; - break; - } - - PInvoke.SetWindowPos(new HWND(hwnd), new HWND(), left, top, actualWidth, actualHeight, 0); - } -} \ No newline at end of file diff --git a/Hyperbar.Windows.Interopq/Hyperbar.Windows.Interop.csproj b/Hyperbar.Windows.Interopq/Hyperbar.Windows.Interop.csproj deleted file mode 100644 index fa7484f..0000000 --- a/Hyperbar.Windows.Interopq/Hyperbar.Windows.Interop.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - net8.0-windows10.0.19041.0 - enable - enable - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - \ No newline at end of file diff --git a/Hyperbar.Windows.Interopq/IVirtualKeyboard.cs b/Hyperbar.Windows.Interopq/IVirtualKeyboard.cs deleted file mode 100644 index e1c9792..0000000 --- a/Hyperbar.Windows.Interopq/IVirtualKeyboard.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Hyperbar.Windows.Interop -{ - public interface IVirtualKeyboard - { - void Send(int key, params int[] modifierKeys); - } -} \ No newline at end of file diff --git a/Hyperbar.Windows.Interopq/NativeMethods.txt b/Hyperbar.Windows.Interopq/NativeMethods.txt deleted file mode 100644 index 95b59b0..0000000 --- a/Hyperbar.Windows.Interopq/NativeMethods.txt +++ /dev/null @@ -1,59 +0,0 @@ -FindWindow -//SHAppBarMessage -SystemParametersInfo -//Shell_NotifyIcon -CreateWindowEx -DefWindowProc -RegisterClass -RegisterWindowMessage -DestroyWindow -SetForegroundWindow -GetDoubleClickTime -GetPhysicalCursorPos -GetCursorPos -GetActiveWindow -GetDpiForWindow -SetForegroundWindow -GetDpiForWindow -SetWindowPos -MonitorFromWindow -GetWindowRect -GetMonitorInfo -CreateIcon -GetModuleHandle -GetDesktopWindow -GetClientRect -LoadIcon -UpdateLayeredWindow -SetLayeredWindowAttributes -GetDpiForMonitor -ShowWindow -LoadImage -SendMessage -SetWindowLong -GetWindowLong -UpdateLayeredWindow -DestroyIcon -GetSystemMetrics -EnumDisplayMonitors -MONITORINFOEXW -SetWindowSubclass -RemoveWindowSubclass -DefSubclassProc -GetWindowPlacement -SetWindowPlacement -D3D11CreateDevice -D3D11_SDK_VERSION -IDXGIAdapter -IDXGIDevice -IDXGIFactory2 -CreateDirect3D11SurfaceFromDXGISurface -CreateDispatcherQueueController -DwmEnableBlurBehindWindow -DwmExtendFrameIntoClientArea -CreateRectRgn -CreateSolidBrush -FillRect -GetDC -SendInput -MapVirtualKey \ No newline at end of file diff --git a/Hyperbar.Windows.Interopq/PInvoke.cs b/Hyperbar.Windows.Interopq/PInvoke.cs deleted file mode 100644 index ddf9ef7..0000000 --- a/Hyperbar.Windows.Interopq/PInvoke.cs +++ /dev/null @@ -1,559 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using Windows.Win32.Foundation; -using Windows.Win32.UI.WindowsAndMessaging; - -namespace Windows.Win32 -{ - /// - /// Contains extern methods from "Shell32.dll". - /// - internal static partial class PInvoke - { - /// - internal static unsafe nuint SHAppBarMessage(uint dwMessage, ref APPBARDATA32 pData) - { - fixed (APPBARDATA32* pDataLocal = &pData) - { - nuint __result = PInvoke.SHAppBarMessage(dwMessage, pDataLocal); - return __result; - } - } - - /// - internal static unsafe nuint SHAppBarMessage(uint dwMessage, ref APPBARDATA64 pData) - { - fixed (APPBARDATA64* pDataLocal = &pData) - { - nuint __result = PInvoke.SHAppBarMessage(dwMessage, pDataLocal); - return __result; - } - } - - /// Sends an appbar message to the system. - /// Type: DWORD - /// - /// Type: PAPPBARDATA - /// A pointer to an APPBARDATA structure. The content of the structure on entry and on exit depends on the value set in the dwMessage parameter. See the individual message pages for specifics. - /// Read more on docs.microsoft.com. - /// - /// - /// Type: UINT_PTR - /// This function returns a message-dependent value. For more information, see the Windows SDK documentation for the specific appbar message sent. Links to those documents are given in the See Also section. - /// - /// - /// Learn more about this API from docs.microsoft.com. - /// - [DllImport("Shell32", ExactSpelling = true)] - [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] - internal static extern unsafe nuint SHAppBarMessage(uint dwMessage, APPBARDATA32* pData); - - /// Sends an appbar message to the system. - /// Type: DWORD - /// - /// Type: PAPPBARDATA - /// A pointer to an APPBARDATA structure. The content of the structure on entry and on exit depends on the value set in the dwMessage parameter. See the individual message pages for specifics. - /// Read more on docs.microsoft.com. - /// - /// - /// Type: UINT_PTR - /// This function returns a message-dependent value. For more information, see the Windows SDK documentation for the specific appbar message sent. Links to those documents are given in the See Also section. - /// - /// - /// Learn more about this API from docs.microsoft.com. - /// - [DllImport("Shell32", ExactSpelling = true)] - [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] - internal static extern unsafe nuint SHAppBarMessage(uint dwMessage, APPBARDATA64* pData); - - /// - internal static unsafe bool Shell_NotifyIcon(uint dwMessage, in NOTIFYICONDATAW32 lpData) - { - fixed (NOTIFYICONDATAW32* lpDataLocal = &lpData) - { - bool __result = PInvoke.Shell_NotifyIcon(dwMessage, lpDataLocal); - return __result; - } - } - - /// - internal static unsafe bool Shell_NotifyIcon(uint dwMessage, in NOTIFYICONDATAW64 lpData) - { - fixed (NOTIFYICONDATAW64* lpDataLocal = &lpData) - { - bool __result = PInvoke.Shell_NotifyIcon(dwMessage, lpDataLocal); - return __result; - } - } - - /// Sends a message to the taskbar's status area. - /// Type: DWORD - /// - /// Type: PNOTIFYICONDATA - /// A pointer to a NOTIFYICONDATA structure. The content of the structure depends on the value of dwMessage. It can define an icon to add to the notification area, cause that icon to display a notification, or identify an icon to modify or delete. - /// Read more on docs.microsoft.com. - /// - /// - /// Type: BOOL - /// Returns TRUE if successful, or FALSE otherwise. If dwMessage is set to NIM_SETVERSION, the function returns TRUE if the version was successfully changed, or FALSE if the requested version is not supported. - /// - /// - /// Learn more about this API from docs.microsoft.com. - /// - [DllImport("Shell32", ExactSpelling = true, EntryPoint = "Shell_NotifyIconW")] - [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] - internal static extern unsafe bool Shell_NotifyIcon(uint dwMessage, NOTIFYICONDATAW32* lpData); - - /// Sends a message to the taskbar's status area. - /// Type: DWORD - /// - /// Type: PNOTIFYICONDATA - /// A pointer to a NOTIFYICONDATA structure. The content of the structure depends on the value of dwMessage. It can define an icon to add to the notification area, cause that icon to display a notification, or identify an icon to modify or delete. - /// Read more on docs.microsoft.com. - /// - /// - /// Type: BOOL - /// Returns TRUE if successful, or FALSE otherwise. If dwMessage is set to NIM_SETVERSION, the function returns TRUE if the version was successfully changed, or FALSE if the requested version is not supported. - /// - /// - /// Learn more about this API from docs.microsoft.com. - /// - [DllImport("Shell32", ExactSpelling = true, EntryPoint = "Shell_NotifyIconW")] - [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] - internal static extern unsafe bool Shell_NotifyIcon(uint dwMessage, NOTIFYICONDATAW64* lpData); - } - - /// Contains information about a system appbar message. - /// - /// Learn more about this API from docs.microsoft.com. - /// - [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal partial struct APPBARDATA32 - { - /// - /// Type: DWORD - /// The size of the structure, in bytes. - /// Read more on docs.microsoft.com. - /// - internal uint cbSize; - - /// - /// Type: HWND - /// The handle to the appbar window. Not all messages use this member. See the individual message page to see if you need to provide an hWind value. - /// Read more on docs.microsoft.com. - /// - internal HWND hWnd; - - /// - /// Type: UINT - /// An application-defined message identifier. The application uses the specified identifier for notification messages that it sends to the appbar identified by the hWnd member. This member is used when sending the ABM_NEW message. - /// Read more on docs.microsoft.com. - /// - internal uint uCallbackMessage; - - /// - /// Type: UINT A value that specifies an edge of the screen. This member is used when sending one of these messages: - /// This doc was truncated. - /// Read more on docs.microsoft.com. - /// - internal uint uEdge; - - /// - /// Type: RECT A RECT structure whose use varies depending on the message: - /// - /// This doc was truncated. - /// Read more on docs.microsoft.com. - /// - internal RECT rc; - - /// - /// Type: LPARAM A message-dependent value. This member is used with these messages: - /// This doc was truncated. - /// Read more on docs.microsoft.com. - /// - internal LPARAM lParam; - } - - /// Contains information about a system appbar message. - /// - /// Learn more about this API from docs.microsoft.com. - /// - internal partial struct APPBARDATA64 - { - /// - /// Type: DWORD - /// The size of the structure, in bytes. - /// Read more on docs.microsoft.com. - /// - internal uint cbSize; - - /// - /// Type: HWND - /// The handle to the appbar window. Not all messages use this member. See the individual message page to see if you need to provide an hWind value. - /// Read more on docs.microsoft.com. - /// - internal HWND hWnd; - - /// - /// Type: UINT - /// An application-defined message identifier. The application uses the specified identifier for notification messages that it sends to the appbar identified by the hWnd member. This member is used when sending the ABM_NEW message. - /// Read more on docs.microsoft.com. - /// - internal uint uCallbackMessage; - - /// - /// Type: UINT A value that specifies an edge of the screen. This member is used when sending one of these messages: - /// This doc was truncated. - /// Read more on docs.microsoft.com. - /// - internal uint uEdge; - - /// - /// Type: RECT A RECT structure whose use varies depending on the message: - /// - /// This doc was truncated. - /// Read more on docs.microsoft.com. - /// - internal RECT rc; - - /// - /// Type: LPARAM A message-dependent value. This member is used with these messages: - /// This doc was truncated. - /// Read more on docs.microsoft.com. - /// - internal LPARAM lParam; - } - - internal struct __ushort_128 - { - internal ushort _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112, _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127; - - /// Always 128. - internal int Length => 128; - - /// - /// Gets a ref to an individual element of the inline array. - /// ⚠ Important ⚠: When this struct is on the stack, do not let the returned reference outlive the stack frame that defines it. - /// - internal ref ushort this[int index] => ref AsSpan()[index]; - - /// - /// Gets this inline array as a span. - /// - /// - /// ⚠ Important ⚠: When this struct is on the stack, do not let the returned span outlive the stack frame that defines it. - /// - internal Span AsSpan() => MemoryMarshal.CreateSpan(ref _0, 128); - } - - /// Contains information that the system needs to display notifications in the notification area. Used by Shell_NotifyIcon. - /// - /// See Notifications in the Windows User Experience Interaction Guidelines for more information on notification UI and content best practices. - /// If you set the NIF_INFO flag in the uFlags member, the balloon-style notification is used. For more discussion of these notifications, see Balloon tooltips. - /// No more than one balloon notification at a time can be displayed for the taskbar. If an application attempts to display a notification when one is already being displayed, the new notification is queued and displayed when the older notification goes away. In versions of Windows before Windows Vista, the new notification would not appear until the existing notification has been visible for at least the system minimum timeout length, regardless of the original notification's uTimeout value. If the user does not appear to be using the computer, the system does not count this time toward the timeout. - /// Several members of this structure are only supported for Windows 2000 and later. To enable these members, include one of the following lines in your header: - /// - /// This doc was truncated. - /// Read more on docs.microsoft.com. - /// - [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal partial struct NOTIFYICONDATAW32 - { - /// - /// Type: DWORD - /// The size of this structure, in bytes. - /// Read more on docs.microsoft.com. - /// - internal uint cbSize; - - /// - /// Type: HWND - /// A handle to the window that receives notifications associated with an icon in the notification area. - /// Read more on docs.microsoft.com. - /// - internal HWND hWnd; - - /// - /// Type: UINT - /// The application-defined identifier of the taskbar icon. The Shell uses either (hWnd plus uID) or guidItem to identify which icon to operate on when Shell_NotifyIcon is invoked. You can have multiple icons associated with a single hWnd by assigning each a different uID. If guidItem is specified, uID is ignored. - /// Read more on docs.microsoft.com. - /// - internal uint uID; - - /// Type: UINT - internal uint uFlags; - - /// - /// Type: UINT - /// An application-defined message identifier. The system uses this identifier to send notification messages to the window identified in hWnd. These notification messages are sent when a mouse event or hover occurs in the bounding rectangle of the icon, when the icon is selected or activated with the keyboard, or when those actions occur in the balloon notification. - /// When the uVersion member is either 0 or NOTIFYICON_VERSION, the wParam parameter of the message contains the identifier of the taskbar icon in which the event occurred. This identifier can be 32 bits in length. The lParam parameter holds the mouse or keyboard message associated with the event. For example, when the pointer moves over a taskbar icon, lParam is set to WM_MOUSEMOVE. - /// When the uVersion member is NOTIFYICON_VERSION_4, applications continue to receive notification events in the form of application-defined messages through the uCallbackMessage member, but the interpretation of the lParam and wParam parameters of that message is changed as follows: - /// - /// This doc was truncated. - /// Read more on docs.microsoft.com. - /// - internal uint uCallbackMessage; - - /// - /// Type: HICON - /// A handle to the icon to be added, modified, or deleted. Windows XP and later support icons of up to 32 BPP. - /// If only a 16x16 pixel icon is provided, it is scaled to a larger size in a system set to a high dpi value. This can lead to an unattractive result. It is recommended that you provide both a 16x16 pixel icon and a 32x32 icon in your resource file. Use LoadIconMetric to ensure that the correct icon is loaded and scaled appropriately. See Remarks for a code example. - /// Read more on docs.microsoft.com. - /// - internal HICON hIcon; - - /// - /// Type: TCHAR[64] - /// A null-terminated string that specifies the text for a standard tooltip. It can have a maximum of 64 characters, including the terminating null character. - /// For Windows 2000 and later, szTip can have a maximum of 128 characters, including the terminating null character. - /// Read more on docs.microsoft.com. - /// - internal __ushort_128 szTip; - - /// Type: DWORD - internal uint dwState; - - /// - /// Type: DWORD - /// Windows 2000 and later. A value that specifies which bits of the dwState member are retrieved or modified. The possible values are the same as those for dwState. For example, setting this member to NIS_HIDDEN causes only the item's hidden state to be modified while the icon sharing bit is ignored regardless of its value. - /// Read more on docs.microsoft.com. - /// - internal uint dwStateMask; - - /// - /// Type: TCHAR[256] - /// Windows 2000 and later. A null-terminated string that specifies the text to display in a balloon notification. It can have a maximum of 256 characters, including the terminating null character, but should be restricted to 200 characters in English to accommodate localization. To remove the balloon notification from the UI, either delete the icon (with NIM_DELETE) or set the NIF_INFO flag in uFlags and set szInfo to an empty string. - /// Read more on docs.microsoft.com. - /// - internal __ushort_256 szInfo; - - internal _Anonymous_e__Union Anonymous; - - /// - /// Type: TCHAR[64] - /// Windows 2000 and later. A null-terminated string that specifies a title for a balloon notification. This title appears in a larger font immediately above the text. It can have a maximum of 64 characters, including the terminating null character, but should be restricted to 48 characters in English to accommodate localization. - /// Read more on docs.microsoft.com. - /// - internal __ushort_64 szInfoTitle; - - /// - /// Type: DWORD - /// Windows 2000 and later. Flags that can be set to modify the behavior and appearance of a balloon notification. The icon is placed to the left of the title. If the szInfoTitle member is zero-length, the icon is not shown. - /// Read more on docs.microsoft.com. - /// - internal uint dwInfoFlags; - - /// - /// Type: GUID Windows XP and later. - /// - /// This doc was truncated. - /// Read more on docs.microsoft.com. - /// - internal global::System.Guid guidItem; - - /// - /// Type: HICON - /// Windows Vista and later. The handle of a customized notification icon provided by the application that should be used independently of the notification area icon. If this member is non-NULL and the NIIF_USER flag is set in the dwInfoFlags member, this icon is used as the notification icon. If this member is NULL, the legacy behavior is carried out. - /// Read more on docs.microsoft.com. - /// - internal HICON hBalloonIcon; - - internal struct __ushort_256 - { - internal ushort _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112, _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, _128, _129, _130, _131, _132, _133, _134, _135, _136, _137, _138, _139, _140, _141, _142, _143, _144, _145, _146, _147, _148, _149, _150, _151, _152, _153, _154, _155, _156, _157, _158, _159, _160, _161, _162, _163, _164, _165, _166, _167, _168, _169, _170, _171, _172, _173, _174, _175, _176, _177, _178, _179, _180, _181, _182, _183, _184, _185, _186, _187, _188, _189, _190, _191, _192, _193, _194, _195, _196, _197, _198, _199, _200, _201, _202, _203, _204, _205, _206, _207, _208, _209, _210, _211, _212, _213, _214, _215, _216, _217, _218, _219, _220, _221, _222, _223, _224, _225, _226, _227, _228, _229, _230, _231, _232, _233, _234, _235, _236, _237, _238, _239, _240, _241, _242, _243, _244, _245, _246, _247, _248, _249, _250, _251, _252, _253, _254, _255; - - /// Always 256. - internal int Length => 256; - - /// - /// Gets a ref to an individual element of the inline array. - /// ⚠ Important ⚠: When this struct is on the stack, do not let the returned reference outlive the stack frame that defines it. - /// - internal ref ushort this[int index] => ref AsSpan()[index]; - - /// - /// Gets this inline array as a span. - /// - /// - /// ⚠ Important ⚠: When this struct is on the stack, do not let the returned span outlive the stack frame that defines it. - /// - internal Span AsSpan() => MemoryMarshal.CreateSpan(ref _0, 256); - } - - [StructLayout(LayoutKind.Explicit, Pack = 1)] - internal partial struct _Anonymous_e__Union - { - [FieldOffset(0)] - internal uint uTimeout; - - [FieldOffset(0)] - internal uint uVersion; - } - } - - internal struct __ushort_64 - { - internal ushort _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63; - - /// Always 64. - internal int Length => 64; - - /// - /// Gets a ref to an individual element of the inline array. - /// ⚠ Important ⚠: When this struct is on the stack, do not let the returned reference outlive the stack frame that defines it. - /// - internal ref ushort this[int index] => ref AsSpan()[index]; - - /// - /// Gets this inline array as a span. - /// - /// - /// ⚠ Important ⚠: When this struct is on the stack, do not let the returned span outlive the stack frame that defines it. - /// - internal Span AsSpan() => MemoryMarshal.CreateSpan(ref _0, 64); - } - - /// Contains information that the system needs to display notifications in the notification area. Used by Shell_NotifyIcon. - /// - /// See Notifications in the Windows User Experience Interaction Guidelines for more information on notification UI and content best practices. - /// If you set the NIF_INFO flag in the uFlags member, the balloon-style notification is used. For more discussion of these notifications, see Balloon tooltips. - /// No more than one balloon notification at a time can be displayed for the taskbar. If an application attempts to display a notification when one is already being displayed, the new notification is queued and displayed when the older notification goes away. In versions of Windows before Windows Vista, the new notification would not appear until the existing notification has been visible for at least the system minimum timeout length, regardless of the original notification's uTimeout value. If the user does not appear to be using the computer, the system does not count this time toward the timeout. - /// Several members of this structure are only supported for Windows 2000 and later. To enable these members, include one of the following lines in your header: - /// - /// This doc was truncated. - /// Read more on docs.microsoft.com. - /// - internal partial struct NOTIFYICONDATAW64 - { - /// - /// Type: DWORD - /// The size of this structure, in bytes. - /// Read more on docs.microsoft.com. - /// - internal uint cbSize; - - /// - /// Type: HWND - /// A handle to the window that receives notifications associated with an icon in the notification area. - /// Read more on docs.microsoft.com. - /// - internal HWND hWnd; - - /// - /// Type: UINT - /// The application-defined identifier of the taskbar icon. The Shell uses either (hWnd plus uID) or guidItem to identify which icon to operate on when Shell_NotifyIcon is invoked. You can have multiple icons associated with a single hWnd by assigning each a different uID. If guidItem is specified, uID is ignored. - /// Read more on docs.microsoft.com. - /// - internal uint uID; - - /// Type: UINT - internal uint uFlags; - - /// - /// Type: UINT - /// An application-defined message identifier. The system uses this identifier to send notification messages to the window identified in hWnd. These notification messages are sent when a mouse event or hover occurs in the bounding rectangle of the icon, when the icon is selected or activated with the keyboard, or when those actions occur in the balloon notification. - /// When the uVersion member is either 0 or NOTIFYICON_VERSION, the wParam parameter of the message contains the identifier of the taskbar icon in which the event occurred. This identifier can be 32 bits in length. The lParam parameter holds the mouse or keyboard message associated with the event. For example, when the pointer moves over a taskbar icon, lParam is set to WM_MOUSEMOVE. - /// When the uVersion member is NOTIFYICON_VERSION_4, applications continue to receive notification events in the form of application-defined messages through the uCallbackMessage member, but the interpretation of the lParam and wParam parameters of that message is changed as follows: - /// - /// This doc was truncated. - /// Read more on docs.microsoft.com. - /// - internal uint uCallbackMessage; - - /// - /// Type: HICON - /// A handle to the icon to be added, modified, or deleted. Windows XP and later support icons of up to 32 BPP. - /// If only a 16x16 pixel icon is provided, it is scaled to a larger size in a system set to a high dpi value. This can lead to an unattractive result. It is recommended that you provide both a 16x16 pixel icon and a 32x32 icon in your resource file. Use LoadIconMetric to ensure that the correct icon is loaded and scaled appropriately. See Remarks for a code example. - /// Read more on docs.microsoft.com. - /// - internal HICON hIcon; - - /// - /// Type: TCHAR[64] - /// A null-terminated string that specifies the text for a standard tooltip. It can have a maximum of 64 characters, including the terminating null character. - /// For Windows 2000 and later, szTip can have a maximum of 128 characters, including the terminating null character. - /// Read more on docs.microsoft.com. - /// - internal __ushort_128 szTip; - - /// Type: DWORD - internal uint dwState; - - /// - /// Type: DWORD - /// Windows 2000 and later. A value that specifies which bits of the dwState member are retrieved or modified. The possible values are the same as those for dwState. For example, setting this member to NIS_HIDDEN causes only the item's hidden state to be modified while the icon sharing bit is ignored regardless of its value. - /// Read more on docs.microsoft.com. - /// - internal uint dwStateMask; - - /// - /// Type: TCHAR[256] - /// Windows 2000 and later. A null-terminated string that specifies the text to display in a balloon notification. It can have a maximum of 256 characters, including the terminating null character, but should be restricted to 200 characters in English to accommodate localization. To remove the balloon notification from the UI, either delete the icon (with NIM_DELETE) or set the NIF_INFO flag in uFlags and set szInfo to an empty string. - /// Read more on docs.microsoft.com. - /// - internal __ushort_256 szInfo; - - internal _Anonymous_e__Union Anonymous; - - /// - /// Type: TCHAR[64] - /// Windows 2000 and later. A null-terminated string that specifies a title for a balloon notification. This title appears in a larger font immediately above the text. It can have a maximum of 64 characters, including the terminating null character, but should be restricted to 48 characters in English to accommodate localization. - /// Read more on docs.microsoft.com. - /// - internal __ushort_64 szInfoTitle; - - /// - /// Type: DWORD - /// Windows 2000 and later. Flags that can be set to modify the behavior and appearance of a balloon notification. The icon is placed to the left of the title. If the szInfoTitle member is zero-length, the icon is not shown. - /// Read more on docs.microsoft.com. - /// - internal uint dwInfoFlags; - - /// - /// Type: GUID Windows XP and later. - /// - /// This doc was truncated. - /// Read more on docs.microsoft.com. - /// - internal global::System.Guid guidItem; - - /// - /// Type: HICON - /// Windows Vista and later. The handle of a customized notification icon provided by the application that should be used independently of the notification area icon. If this member is non-NULL and the NIIF_USER flag is set in the dwInfoFlags member, this icon is used as the notification icon. If this member is NULL, the legacy behavior is carried out. - /// Read more on docs.microsoft.com. - /// - internal HICON hBalloonIcon; - - internal struct __ushort_256 - { - internal ushort _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112, _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, _128, _129, _130, _131, _132, _133, _134, _135, _136, _137, _138, _139, _140, _141, _142, _143, _144, _145, _146, _147, _148, _149, _150, _151, _152, _153, _154, _155, _156, _157, _158, _159, _160, _161, _162, _163, _164, _165, _166, _167, _168, _169, _170, _171, _172, _173, _174, _175, _176, _177, _178, _179, _180, _181, _182, _183, _184, _185, _186, _187, _188, _189, _190, _191, _192, _193, _194, _195, _196, _197, _198, _199, _200, _201, _202, _203, _204, _205, _206, _207, _208, _209, _210, _211, _212, _213, _214, _215, _216, _217, _218, _219, _220, _221, _222, _223, _224, _225, _226, _227, _228, _229, _230, _231, _232, _233, _234, _235, _236, _237, _238, _239, _240, _241, _242, _243, _244, _245, _246, _247, _248, _249, _250, _251, _252, _253, _254, _255; - - /// Always 256. - internal int Length => 256; - - /// - /// Gets a ref to an individual element of the inline array. - /// ⚠ Important ⚠: When this struct is on the stack, do not let the returned reference outlive the stack frame that defines it. - /// - internal ref ushort this[int index] => ref AsSpan()[index]; - - /// - /// Gets this inline array as a span. - /// - /// - /// ⚠ Important ⚠: When this struct is on the stack, do not let the returned span outlive the stack frame that defines it. - /// - internal Span AsSpan() => MemoryMarshal.CreateSpan(ref _0, 256); - } - - [StructLayout(LayoutKind.Explicit)] - internal partial struct _Anonymous_e__Union - { - [FieldOffset(0)] - internal uint uTimeout; - - [FieldOffset(0)] - internal uint uVersion; - } - } -} \ No newline at end of file diff --git a/Hyperbar.Windows.Interopq/VirtualKeyboard.cs b/Hyperbar.Windows.Interopq/VirtualKeyboard.cs deleted file mode 100644 index 2ef2c9d..0000000 --- a/Hyperbar.Windows.Interopq/VirtualKeyboard.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.Linq; -using System.Runtime.InteropServices; -using Windows.Win32; -using Windows.Win32.UI.KeyboardAndMouseInput; - -namespace Hyperbar.Windows.Interop; - -public class VirtualKeyboard : - IVirtualKeyboard -{ - private readonly int[] extendedKeys = [ - 165, // RightMenu - 164, // LeftMenu - 144, // NumberKeyLock - 45, // Insert - 46, // Delete - 36, // Home - 35, // End - 36, // Up, - 40, // Down, - 37, // Left - 39, // Right, - 93, // Application, - 92, // RightWindows - 91 // LeftWindows - ]; - - public void Send(int key, - params int[] modifierKeys) - { - foreach (int modiferKey in modifierKeys) - { - Press(modiferKey); - } - - Press(key); - Release(key); - - foreach (int modifierKey in modifierKeys.Reverse()) - { - Release(modifierKey); - } - } - - private void Press(int key) => Send(key, true); - - private void Release(int key) => Send(key, false); - - private unsafe void Send(int key, - bool pressed) - { - INPUT input = new() - { - type = INPUT_TYPE.INPUT_KEYBOARD - }; - - input.Anonymous.ki.wVk = (ushort)key; - input.Anonymous.ki.wScan = (ushort)PInvoke.MapVirtualKey(input.Anonymous.ki.wVk, 0); - - KEYBD_EVENT_FLAGS flags = 0; - - if (input.Anonymous.ki.wScan > 0) - { - flags |= KEYBD_EVENT_FLAGS.KEYEVENTF_SCANCODE; - } - - if (!pressed) - { - flags |= KEYBD_EVENT_FLAGS.KEYEVENTF_KEYUP; - } - - if (extendedKeys.Contains((int)key)) - { - flags |= KEYBD_EVENT_FLAGS.KEYEVENTF_EXTENDEDKEY; - } - - input.Anonymous.ki.dwFlags = flags; - input.Anonymous.ki.time = 0; - input.Anonymous.ki.dwExtraInfo = new nuint(); - - PInvoke.SendInput(new Span(ref input), Marshal.SizeOf(input)); - } -} \ No newline at end of file diff --git a/Hyperbar.Windows.Interopq/WindowStyle.cs b/Hyperbar.Windows.Interopq/WindowStyle.cs deleted file mode 100644 index 8a0d564..0000000 --- a/Hyperbar.Windows.Interopq/WindowStyle.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace Hyperbar.Windows.Interop; - -[Flags] -public enum WindowStyle -{ - Border = 0x800000, - Caption = 0xC00000, - Child = 0x40000000, - ChildWindow = 0x40000000, - ChildChildren = 0x2000000, - ClipSiblings = 0x4000000, - Disabled = 0x8000000, - DlgFrame = 0x400000, - Group = 0x20000, - HScroll = 0x100000, - Iconic = 0x20000000, - Maximize = 0x1000000, - MaximizeBox = 0x10000, - Minimize = 0x20000000, - MinimizeBox = 0x20000, - Overlapped = 0, - OverlappedWindow = 0xCF0000, - SizeBox = 0x40000, - SysMenu = 0x80000, - TabStop = 0x10000, - ThickFrame = 0x40000, - Tiled = 0, - TiledWindow = 0xCF0000, - Visible = 0x10000000, - VScroll = 0x200000 -} \ No newline at end of file diff --git a/Hyperbar.Windows.Primary/PrimaryWidgetProvider.cs b/Hyperbar.Windows.Primary/PrimaryWidgetProvider.cs index d0451ee..7cfafc5 100644 --- a/Hyperbar.Windows.Primary/PrimaryWidgetProvider.cs +++ b/Hyperbar.Windows.Primary/PrimaryWidgetProvider.cs @@ -7,5 +7,7 @@ public class PrimaryWidgetProvider : IWidgetProvider { public void Create(IServiceCollection services) => services.AddConfiguration() + .AddTransient() + .AddTransient(provider => provider.GetRequiredService().Create()) .AddWidgetTemplate(); } \ No newline at end of file diff --git a/Hyperbar.Windows.Primary/PrimaryWidgetViewModel.cs b/Hyperbar.Windows.Primary/PrimaryWidgetViewModel.cs index cde7adf..110e49b 100644 --- a/Hyperbar.Windows.Primary/PrimaryWidgetViewModel.cs +++ b/Hyperbar.Windows.Primary/PrimaryWidgetViewModel.cs @@ -1,16 +1,16 @@ namespace Hyperbar.Windows.Primary; public class PrimaryWidgetViewModel : - WidgetViewModelBase + ObservableCollectionViewModel, + IWidgetViewModel, + ITemplatedViewModel { - public PrimaryWidgetViewModel(ITemplateFactory templateFactory, + public PrimaryWidgetViewModel(ITemplateFactory templateFactory, IServiceFactory serviceFactory, - IMediator mediator) : base(templateFactory, serviceFactory) + IEnumerable items) : base(serviceFactory, items) { - Add("Start", new Action(() => mediator.Send(new KeyAcceleratorCommand(VirtualKey.LeftWindows)))); - - //Add("test 2", new Action(() => { })); - //Add("test 4", new Action(() => { })); - //Add("test 5", new Action(() => { })); + TemplateFactory = templateFactory; } + + public ITemplateFactory TemplateFactory { get; } } \ No newline at end of file diff --git a/Hyperbar.Windows.Primary/PrimaryWidgetViewModelFactory.cs b/Hyperbar.Windows.Primary/PrimaryWidgetViewModelFactory.cs new file mode 100644 index 0000000..03db3dc --- /dev/null +++ b/Hyperbar.Windows.Primary/PrimaryWidgetViewModelFactory.cs @@ -0,0 +1,25 @@ +namespace Hyperbar.Windows.Primary; + +public class PrimaryWidgetViewModelFactory : + IViewModelFactory> +{ + private readonly PrimaryWidgetConfiguration configuration; + private readonly IServiceFactory service; + + public PrimaryWidgetViewModelFactory(PrimaryWidgetConfiguration configuration, + IServiceFactory service) + { + this.configuration = configuration; + this.service = service; + } + + public IEnumerable Create() + { + foreach (IPrimaryCommandConfiguration item in configuration) + { + + } + + return Enumerable.Empty(); + } +} diff --git a/Hyperbar.Windows/Commands/KeyAcceleratorCommandHandler.cs b/Hyperbar.Windows/Commands/KeyAcceleratorCommandHandler.cs index b3d3486..548cc0a 100644 --- a/Hyperbar.Windows/Commands/KeyAcceleratorCommandHandler.cs +++ b/Hyperbar.Windows/Commands/KeyAcceleratorCommandHandler.cs @@ -7,7 +7,8 @@ public class KeyAcceleratorCommandHandler(IVirtualKeyboard virtualKeyboard) : { public ValueTask Handle(KeyAcceleratorCommand command, CancellationToken cancellationToken) - { virtualKeyboard.Send((int)command.Key); + { + virtualKeyboard.Send((int)command.Key); return default; } } diff --git a/Hyperbar.Windows/Views/CommandViewModel.cs b/Hyperbar.Windows/Views/CommandViewModel.cs index db5d47d..3319c1a 100644 --- a/Hyperbar.Windows/Views/CommandViewModel.cs +++ b/Hyperbar.Windows/Views/CommandViewModel.cs @@ -1,15 +1,15 @@ -namespace Hyperbar.Windows; + +namespace Hyperbar.Windows; public partial class CommandViewModel : ObservableCollectionViewModel, ITemplatedViewModel { - public CommandViewModel(ITemplateFactory templateFactory, - IServiceFactory serviceFactory, - IEnumerable widgets) : base(serviceFactory) + public CommandViewModel(ITemplateFactory templateFactory, + IServiceFactory serviceFactory, + IEnumerable items) : base(serviceFactory, items) { TemplateFactory = templateFactory; - AddRange(widgets); } public ITemplateFactory TemplateFactory { get; } diff --git a/Hyperbar/Extensions/IServiceCollectionExtensions.cs b/Hyperbar/Extensions/IServiceCollectionExtensions.cs index ca4c387..ec7e909 100644 --- a/Hyperbar/Extensions/IServiceCollectionExtensions.cs +++ b/Hyperbar/Extensions/IServiceCollectionExtensions.cs @@ -101,10 +101,11 @@ public static class IServiceCollectionExtensions where TConfiguration : class, new() { - _ = services.AddOptions(); - _ = services.AddSingleton>(new ConfigureNamedOptions("", args => { })); + services.AddOptions(); + services.AddSingleton>(new ConfigureNamedOptions("", args => { })); + services.AddTransient(provider => provider.GetService>()!.CurrentValue); - _ = services.AddTransient>(provider => + services.AddTransient>(provider => { string? jsonFilePath = null; if (provider.GetService() is IHostEnvironment hostEnvironment) @@ -127,7 +128,7 @@ public static class IServiceCollectionExtensions return new ConfigurationWriter(jsonFilePath, section, defaultSerializerOptions); }); - _ = services.AddTransient, WritableConfiguration>(); + services.AddTransient, WritableConfiguration>(); return services; } @@ -140,18 +141,13 @@ public static class IServiceCollectionExtensions string key = contentType.Name; - _ = services.AddTransient(typeof(IWidgetViewModel), contentType); + services.AddTransient(typeof(IWidgetViewModel), contentType); services.TryAddTransient(templateType, provider => provider.GetService()!); - _ = services.AddKeyedTransient(typeof(IWidgetViewModel), key, contentType); + services.AddKeyedTransient(typeof(IWidgetViewModel), key, contentType); services.TryAddKeyedTransient(key, (provider, key) => provider.GetService()!); - _ = services.AddTransient(provider => new ContentTemplateDescriptor - { - ContentType = contentType, - TemplateType = templateType, - Key = key - }); + services.AddTransient(provider => new ContentTemplateDescriptor { ContentType = contentType, TemplateType = templateType, Key = key }); return services; } @@ -165,18 +161,13 @@ public static class IServiceCollectionExtensions string key = contentType.Name; - _ = services.AddTransient(typeof(IWidgetViewModel), contentType); + services.AddTransient(typeof(IWidgetViewModel), contentType); services.TryAddTransient(templateType); - _ = services.AddKeyedTransient(typeof(IWidgetViewModel), key, contentType); + services.AddKeyedTransient(typeof(IWidgetViewModel), key, contentType); services.TryAddKeyedTransient(templateType, key); - _ = services.AddTransient(provider => new ContentTemplateDescriptor - { - ContentType = contentType, - TemplateType = templateType, - Key = key - }); + services.AddTransient(provider => new ContentTemplateDescriptor { ContentType = contentType, TemplateType = templateType, Key = key }); return services; } @@ -189,18 +180,13 @@ public static class IServiceCollectionExtensions key ??= contentType.Name; - _ = services.AddTransient(contentType); + services.AddTransient(contentType); services.TryAddTransient(templateType); - _ = services.AddKeyedTransient(contentType, key); - _ = services.AddKeyedTransient(templateType, key); + services.AddKeyedTransient(contentType, key); + services.AddKeyedTransient(templateType, key); - _ = services.AddTransient(provider => new ContentTemplateDescriptor - { - ContentType = contentType, - TemplateType = templateType, - Key = key - }); + services.AddTransient(provider => new ContentTemplateDescriptor { ContentType = contentType, TemplateType = templateType, Key = key }); return services; } diff --git a/Hyperbar/Views/IViewModelFactory.cs b/Hyperbar/Views/IViewModelFactory.cs new file mode 100644 index 0000000..ced60dd --- /dev/null +++ b/Hyperbar/Views/IViewModelFactory.cs @@ -0,0 +1,6 @@ +namespace Hyperbar; + +public interface IViewModelFactory +{ + TTo Create(); +} diff --git a/Hyperbar/Views/ObservableCollectionViewModel.cs b/Hyperbar/Views/ObservableCollectionViewModel.cs index 70cd952..cb255f0 100644 --- a/Hyperbar/Views/ObservableCollectionViewModel.cs +++ b/Hyperbar/Views/ObservableCollectionViewModel.cs @@ -2,9 +2,23 @@ namespace Hyperbar; -public class ObservableCollectionViewModel(IServiceFactory serviceFactory) : +public class ObservableCollectionViewModel : ObservableCollection { + private readonly IServiceFactory serviceFactory; + + public ObservableCollectionViewModel(IServiceFactory serviceFactory) + { + this.serviceFactory = serviceFactory; + } + + public ObservableCollectionViewModel(IServiceFactory serviceFactory, + IEnumerable items) + { + this.serviceFactory = serviceFactory; + AddRange(items); + } + public TItem Add() { TItem? item = serviceFactory.Create(); diff --git a/Hyperbar/Views/WidgetViewModelBase.cs b/Hyperbar/Views/WidgetViewModelBase.cs deleted file mode 100644 index 790b1a6..0000000 --- a/Hyperbar/Views/WidgetViewModelBase.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Hyperbar; - -public class WidgetViewModelBase(ITemplateFactory templateFactory, - IServiceFactory serviceFactory) : - ObservableCollectionViewModel(serviceFactory), - IWidgetViewModel, - ITemplatedViewModel -{ - public ITemplateFactory TemplateFactory => templateFactory; -} \ No newline at end of file