diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.cpp b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.cpp index ba0f07e123..151ad504e8 100644 --- a/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.cpp +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.cpp @@ -3,11 +3,28 @@ #include "ZoomItSettings.g.cpp" #include "../ZoomIt/ZoomItSettings.h" #include +#include +#include namespace winrt::PowerToys::ZoomItSettingsInterop::implementation { CRegistry reg(_T("Software\\Sysinternals\\") APPNAME); + const unsigned int SPECIAL_SEMANTICS_SHORTCUT = 1; + const unsigned int SPECIAL_SEMANTICS_COLOR = 2; + + std::map settings_with_special_semantics = { + { L"ToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"LiveZoomToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"DrawToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"RecordToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"SnipToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"BreakTimerKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"DemoTypeToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"PenColor", SPECIAL_SEMANTICS_COLOR }, + { L"BreakPenColor", SPECIAL_SEMANTICS_COLOR }, + }; + hstring ZoomItSettings::LoadSettingsJson() { PowerToysSettings::PowerToyValues _settings(L"ZoomIt",L"ZoomIt"); @@ -18,10 +35,36 @@ namespace winrt::PowerToys::ZoomItSettingsInterop::implementation switch (curSetting->Type) { case SETTING_TYPE_DWORD: - _settings.add_property(curSetting->Valuename, *static_cast(curSetting->Setting)); + { + auto special_semantics = settings_with_special_semantics.find(curSetting->Valuename); + DWORD value = *static_cast(curSetting->Setting); + if (special_semantics == settings_with_special_semantics.end()) + { + _settings.add_property(curSetting->Valuename, value); + } + else + { + if (special_semantics->second == SPECIAL_SEMANTICS_SHORTCUT) + { + auto hotkey = PowerToysSettings::HotkeyObject::from_settings( + value & (HOTKEYF_EXT << 8), //WIN + value & (HOTKEYF_CONTROL << 8), + value & (HOTKEYF_ALT << 8), + value & (HOTKEYF_SHIFT << 8), + value & 0xFF); + _settings.add_property(curSetting->Valuename, hotkey.get_json()); + } + else if (special_semantics->second == SPECIAL_SEMANTICS_COLOR) + { + // PowerToys settings likes colors as #FFFFFF strings. + hstring s = winrt::to_hstring(std::format("#{:02x}{:02x}{:02x}", value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF)); + _settings.add_property(curSetting->Valuename, s); + } + } break; + } case SETTING_TYPE_BOOLEAN: - _settings.add_property(curSetting->Valuename, *static_cast(curSetting->Setting)); + _settings.add_property(curSetting->Valuename, *static_cast(curSetting->Setting)); break; case SETTING_TYPE_DOUBLE: assert(false); // ZoomIt doesn't use this type of setting. diff --git a/src/settings-ui/Settings.UI.Library/Settings.UI.Library.csproj b/src/settings-ui/Settings.UI.Library/Settings.UI.Library.csproj index 37e239ed3b..59eabace17 100644 --- a/src/settings-ui/Settings.UI.Library/Settings.UI.Library.csproj +++ b/src/settings-ui/Settings.UI.Library/Settings.UI.Library.csproj @@ -19,6 +19,7 @@ + diff --git a/src/settings-ui/Settings.UI.Library/ZoomItProperties.cs b/src/settings-ui/Settings.UI.Library/ZoomItProperties.cs new file mode 100644 index 0000000000..2f313bedb5 --- /dev/null +++ b/src/settings-ui/Settings.UI.Library/ZoomItProperties.cs @@ -0,0 +1,108 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Text.Json.Serialization; +using Settings.UI.Library.Attributes; + +namespace Microsoft.PowerToys.Settings.UI.Library +{ + public class ZoomItProperties + { + public ZoomItProperties() + { + } + + [CmdConfigureIgnore] + public static HotkeySettings DefaultToggleKey => new HotkeySettings(false, true, false, false, '1'); // Ctrl+1 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultLiveZoomToggleKey => new HotkeySettings(false, true, false, false, '4'); // Ctrl+4 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultDrawToggleKey => new HotkeySettings(false, true, false, false, '2'); // Ctrl+2 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultRecordToggleKey => new HotkeySettings(false, true, false, false, '5'); // Ctrl+5 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultSnipToggleKey => new HotkeySettings(false, true, false, false, '6'); // Ctrl+6 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultBreakTimerKey => new HotkeySettings(false, true, false, false, '3'); // Ctrl+3 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultDemoTypeToggleKey => new HotkeySettings(false, true, false, false, '7'); // Ctrl+7 + + // TODO: Font + public KeyboardKeysProperty ToggleKey { get; set; } + + public KeyboardKeysProperty LiveZoomToggleKey { get; set; } + + public KeyboardKeysProperty DrawToggleKey { get; set; } + + public KeyboardKeysProperty RecordToggleKey { get; set; } + + public KeyboardKeysProperty SnipToggleKey { get; set; } + + public StringProperty PenColor { get; set; } + + public IntProperty PenWidth { get; set; } + + public BoolProperty OptionsShown { get; set; } + + public StringProperty BreakPenColor { get; set; } + + public KeyboardKeysProperty BreakTimerKey { get; set; } + + public KeyboardKeysProperty DemoTypeToggleKey { get; set; } + + public StringProperty DemoTypeFile { get; set; } + + public IntProperty DemoTypeSpeedSlider { get; set; } + + public BoolProperty DemoTypeUserDrivenMode { get; set; } + + public BoolProperty BreakTimeout { get; set; } + + public IntProperty BreakOpacity { get; set; } + + public BoolProperty BreakPlaySoundFile { get; set; } + + public StringProperty BreakSoundFile { get; set; } + + public BoolProperty BreakShowBackgroundFile { get; set; } + + public BoolProperty BreakBackgroundStretch { get; set; } + + public StringProperty BreakBackgroundFile { get; set; } + + public IntProperty BreakTimerPosition { get; set; } + + public BoolProperty BreakShowDesktop { get; set; } + + public BoolProperty BreakOnSecondary { get; set; } + + public IntProperty FontScale { get; set; } + + public BoolProperty ShowExpiredTime { get; set; } + + public BoolProperty ShowTrayIcon { get; set; } + + public BoolProperty AnimnateZoom { get; set; } + + public BoolProperty TelescopeZoomOut { get; set; } + + public BoolProperty SnapToGrid { get; set; } + + public IntProperty ZoominSliderLevel { get; set; } + + public IntProperty RecordFrameRate { get; set; } + + public IntProperty RecordScaling { get; set; } + + public BoolProperty CaptureAudio { get; set; } + + public StringProperty MicrophoneDeviceId { get; set; } + } +} diff --git a/src/settings-ui/Settings.UI.Library/ZoomItSettings.cs b/src/settings-ui/Settings.UI.Library/ZoomItSettings.cs new file mode 100644 index 0000000000..db3b07f363 --- /dev/null +++ b/src/settings-ui/Settings.UI.Library/ZoomItSettings.cs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Text.Json.Serialization; +using Microsoft.PowerToys.Settings.UI.Library.Interfaces; + +namespace Microsoft.PowerToys.Settings.UI.Library +{ + public class ZoomItSettings : BasePTModuleSettings, ISettingsConfig + { + public const string ModuleName = "ZoomIt"; + + [JsonPropertyName("properties")] + public ZoomItProperties Properties { get; set; } + + public ZoomItSettings() + { + Name = ModuleName; + Properties = new ZoomItProperties(); + Version = "1.0"; + } + + public string GetModuleName() + { + return Name; + } + + // This can be utilized in the future if the settings.json file is to be modified/deleted. + public bool UpgradeSettingsConfiguration() + { + return false; + } + } +} diff --git a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj index f1cf072673..c059211d00 100644 --- a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj +++ b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj @@ -34,7 +34,7 @@ - PowerToys.GPOWrapper + PowerToys.GPOWrapper;PowerToys.ZoomItSettingsInterop $(OutDir) false @@ -81,6 +81,7 @@ + diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/ZoomItPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/ZoomItPage.xaml index 70741583b9..b166add977 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/ZoomItPage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/ZoomItPage.xaml @@ -28,9 +28,50 @@ IsOpen="{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}" IsTabStop="{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}" Severity="Informational" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - diff --git a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw index b2bfe21be1..0e7e229d04 100644 --- a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw @@ -4305,6 +4305,113 @@ Activate by holding the key for the character you want to add an accent to, then Learn more about ZoomIt {Locked="ZoomIt"} + + Behavior + + + Show tray icon + + + Zoom + + + After toggling ZoomIt you can zoom in with the mouse wheel or up and down arrow keys. Exit zoom mode with Escape or by pressing the right mouse button. + +Copy a zoomed screen with Ctrl+C or save it by typing Ctrl+S. Crop the copy or save region by entering Ctrl+Shift instead of Ctrl. + + + Zoom Toggle Hotkey + + + Live Zoom + + + LiveZoom mode supports window updates to show while zoomed. + +Note that in LiveZoom you must use Ctrl+Up and Ctrl+Down to control the zoom level. To enter drawing mode, use the standard zoom-without-draw hotkey and then escape to go back to LiveZoom. + +To enter and exit LiveZoom, enter the hotkey specified below. + + + Live Zoom Toggle Hotkey + + + Draw + + + Once zoomed, toggle drawing mode by pressing the left mouse button. Undo with Ctrl+Z and all drawing by pressing E. Center the cursor with the space bar. Exit drawing mode by pressing the right mouse button. + +Pen Control - Change the pen width by pressing left Ctrl and using the mouse wheel or the up and down arrow keys. + +Colors - Change the pen color by pressing R (red), G (green), B (blue), O (orange), Y (yellow) or P (pink). + +Highlight and Blur - Hold Shift while pressing a color key for a translucent highlighter color. Press X for blur or Shift+X for a stronger blur. + +Shapes - Draw a line by holding down the Shift key, a rectangle with the Ctrl key, an ellipse with the Tab key and an arrow with Shift+Ctrl. + +Screen - Clear the screen for a sketch pad by pressing W (white) or K (black). Copy a zoomed screen with Ctrl+C or save it by typing Ctrl+S. Crop the copy or save region by entering Ctrl+Shift instead of Ctrl. + + + Draw without Zoom Hotkey + + + Type + + + Once in drawing mode, type 't' to enter typing mode or shift+'t' to enter typing mode with right-aligned input. Exit typing mode by pressing escape or the left mouse button. Use the mouse wheel or up and down arrow keys to change the font size. + +The text color is the current drawing color. + + + Demo Type + + + Use DemoType to have ZoomIt type text specified in the input file when you enter the DemoType toggle. You can also pull input from the clipboard if it is prefixed with the [start] keyword. + +Separate snippets with the [end] keyword and insert pauses into the text output with the [pause:n] keyword where 'n' is seconds. Send text via the clipboard with [paste] and [/paste]. Send keystrokes with [enter], [up], [down], [left] and [right]. + +You can have ZoomIt send text automatically, or select the option to drive input with typing. ZoomIt will block keyboard input while sending output. + +When driving input, hit the space bar to unblock keyboard input at the end of a snippet. In auto mode, control will be returned upon completion. + +When you reach the end of the file, ZoomIt will reload the file and start at the beginning. Enter the hotkey with the Shift key in the opposite mode to step back to the last [end]. + + + Demo Type Toggle Hotkey + + + Break + + + Enter timer mode by using the ZoomIt tray icon's Break menu item. Increase and decrease time with the arrow keys. If you Alt-Tab away from the timer window, reactivate it by left-clicking on the ZoomIt tray icon. Exit timer mode with Escape. + +Change the break timer color using the same keys that the drawing color. The break timer font is the same as text font. + + + Start Break Timer Hotkey + + + Record + + + Record video of the unzoomed live screen or a static zoomed session by entering the recording hot key and finish the recording by entering it again. + +To crop the portion of the screen that will be recorded, enter the hotkey with the Shift key in the opposite mode. + +To record a specific window, enter the hotkey with the Alt key in the opposite mode. + + + Record Toggle Hotkey + + + Snip + + + Copy a region of the screen to the clipboard or enter the hotkey with the Shift key in the opposite mode to save it to a file. + + + Snip Toggle Hotkey + Rules defined by your organization diff --git a/src/settings-ui/Settings.UI/ViewModels/ZoomItViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/ZoomItViewModel.cs index 842896ccd9..098acdc845 100644 --- a/src/settings-ui/Settings.UI/ViewModels/ZoomItViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/ZoomItViewModel.cs @@ -6,6 +6,7 @@ using System; using System.Globalization; using System.Runtime.CompilerServices; using System.Text.Json; +using AllExperiments; using global::PowerToys.GPOWrapper; using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; @@ -20,8 +21,16 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels private GeneralSettings GeneralSettingsConfig { get; set; } + private readonly ZoomItSettings _zoomItSettings; + private Func SendConfigMSG { get; } + private static readonly JsonSerializerOptions _serializerOptions = new JsonSerializerOptions + { + MaxDepth = 0, + IncludeFields = true, + }; + public ZoomItViewModel(ISettingsUtils settingsUtils, ISettingsRepository settingsRepository, Func ipcMSGCallBackFunc) { ArgumentNullException.ThrowIfNull(settingsUtils); @@ -33,9 +42,12 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels GeneralSettingsConfig = settingsRepository.SettingsConfig; + var zoomItSettings = global::PowerToys.ZoomItSettingsInterop.ZoomItSettings.LoadSettingsJson(); + _zoomItSettings = JsonSerializer.Deserialize(zoomItSettings, _serializerOptions); + InitializeEnabledValue(); - // set the callback functions value to handle outgoing IPC message. + // set the callback functions value to handle outgoing IPC message for the enabled value. SendConfigMSG = ipcMSGCallBackFunc; } @@ -85,6 +97,130 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels get => _enabledStateIsGPOConfigured; } + public bool ShowTrayIcon + { + get => _zoomItSettings.Properties.ShowTrayIcon.Value; + set + { + if (_zoomItSettings.Properties.ShowTrayIcon.Value != value) + { + _zoomItSettings.Properties.ShowTrayIcon.Value = value; + OnPropertyChanged(nameof(ShowTrayIcon)); + NotifySettingsChanged(); + } + } + } + + public HotkeySettings ZoomToggleKey + { + get => _zoomItSettings.Properties.ToggleKey.Value; + set + { + if (_zoomItSettings.Properties.ToggleKey.Value != value) + { + _zoomItSettings.Properties.ToggleKey.Value = value ?? ZoomItProperties.DefaultToggleKey; + OnPropertyChanged(nameof(ZoomToggleKey)); + NotifySettingsChanged(); + } + } + } + + public HotkeySettings LiveZoomToggleKey + { + get => _zoomItSettings.Properties.LiveZoomToggleKey.Value; + set + { + if (_zoomItSettings.Properties.LiveZoomToggleKey.Value != value) + { + _zoomItSettings.Properties.LiveZoomToggleKey.Value = value ?? ZoomItProperties.DefaultLiveZoomToggleKey; + OnPropertyChanged(nameof(LiveZoomToggleKey)); + NotifySettingsChanged(); + } + } + } + + public HotkeySettings DrawToggleKey + { + get => _zoomItSettings.Properties.DrawToggleKey.Value; + set + { + if (_zoomItSettings.Properties.DrawToggleKey.Value != value) + { + _zoomItSettings.Properties.DrawToggleKey.Value = value ?? ZoomItProperties.DefaultDrawToggleKey; + OnPropertyChanged(nameof(DrawToggleKey)); + NotifySettingsChanged(); + } + } + } + + public HotkeySettings RecordToggleKey + { + get => _zoomItSettings.Properties.RecordToggleKey.Value; + set + { + if (_zoomItSettings.Properties.RecordToggleKey.Value != value) + { + _zoomItSettings.Properties.RecordToggleKey.Value = value ?? ZoomItProperties.DefaultRecordToggleKey; + OnPropertyChanged(nameof(RecordToggleKey)); + NotifySettingsChanged(); + } + } + } + + public HotkeySettings SnipToggleKey + { + get => _zoomItSettings.Properties.SnipToggleKey.Value; + set + { + if (_zoomItSettings.Properties.SnipToggleKey.Value != value) + { + _zoomItSettings.Properties.SnipToggleKey.Value = value ?? ZoomItProperties.DefaultSnipToggleKey; + OnPropertyChanged(nameof(SnipToggleKey)); + NotifySettingsChanged(); + } + } + } + + public HotkeySettings BreakTimerKey + { + get => _zoomItSettings.Properties.BreakTimerKey.Value; + set + { + if (_zoomItSettings.Properties.BreakTimerKey.Value != value) + { + _zoomItSettings.Properties.BreakTimerKey.Value = value ?? ZoomItProperties.DefaultBreakTimerKey; + OnPropertyChanged(nameof(BreakTimerKey)); + NotifySettingsChanged(); + } + } + } + + public HotkeySettings DemoTypeToggleKey + { + get => _zoomItSettings.Properties.DemoTypeToggleKey.Value; + set + { + if (_zoomItSettings.Properties.DemoTypeToggleKey.Value != value) + { + _zoomItSettings.Properties.DemoTypeToggleKey.Value = value ?? ZoomItProperties.DefaultDemoTypeToggleKey; + OnPropertyChanged(nameof(DemoTypeToggleKey)); + NotifySettingsChanged(); + } + } + } + + private void NotifySettingsChanged() + { + // TODO: Send new settings to Adpater. + // Using InvariantCulture as this is an IPC message + /*SendConfigMSG( + string.Format( + CultureInfo.InvariantCulture, + "{{ \"powertoys\": {{ \"{0}\": {1} }} }}", + ZoomItSettings.ModuleName, + JsonSerializer.Serialize(_zoomItSettings)));*/ + } + public void RefreshEnabledState() { InitializeEnabledValue();