Update release

This commit is contained in:
vczh
2023-04-26 03:46:05 -07:00
parent fa48fe465c
commit a863b789bf
12 changed files with 471 additions and 151 deletions
+30
View File
@@ -2086,6 +2086,11 @@ WindowsController
{
callbackService.InvokeClipboardUpdated();
}
void InvokeGlobalShortcutkeyActivated(vint id)
{
callbackService.InvokeGlobalShortcutKeyActivated(id);
}
};
/***********************************************************************
@@ -2119,6 +2124,12 @@ Windows Procedure
case WM_CLIPBOARDUPDATE:
windowsController->InvokeClipboardUpdated();
break;
case WM_HOTKEY:
if (wParam > 0)
{
windowsController->InvokeGlobalShortcutkeyActivated((vint)wParam);
}
break;
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
@@ -14351,6 +14362,25 @@ WindowsInputService
vint index = keys.Keys().IndexOf(name);
return index == -1 ? VKEY::KEY_UNKNOWN : keys.Values()[index];
}
vint WindowsInputService::RegisterGlobalShortcutKey(bool ctrl, bool shift, bool alt, VKEY key)
{
UINT modifier = 0;
if (ctrl) modifier |= MOD_CONTROL;
if (shift) modifier |= MOD_SHIFT;
if (alt) modifier |= MOD_ALT;
vint id = ++usedHotKeys;
BOOL result = RegisterHotKey(ownerHandle, (int)id, modifier, (UINT)key);
if (result == 0) return (vint)NativeGlobalShortcutKeyResult::Occupied;
return id;
}
bool WindowsInputService::UnregisterGlobalShortcutKey(vint id)
{
BOOL result = UnregisterHotKey(ownerHandle, (int)id);
return result != 0;
}
}
}
}
+3
View File
@@ -2112,6 +2112,7 @@ namespace vl
protected:
HWND ownerHandle;
bool isTimerEnabled;
vint usedHotKeys = (vint)NativeGlobalShortcutKeyResult::ValidIdBegins;
collections::Array<WString> keyNames;
collections::Dictionary<WString, VKEY> keys;
@@ -2129,6 +2130,8 @@ namespace vl
bool IsKeyToggled(VKEY code)override;
WString GetKeyName(VKEY code)override;
VKEY GetKey(const WString& name)override;
vint RegisterGlobalShortcutKey(bool ctrl, bool shift, bool alt, VKEY key)override;
bool UnregisterGlobalShortcutKey(vint id)override;
};
extern bool WinIsKeyPressing(VKEY code);
+216 -82
View File
@@ -185,6 +185,52 @@ namespace vl
using namespace theme;
using namespace description;
/***********************************************************************
GuiGlobalShortcutKeyManager
***********************************************************************/
class GuiGlobalShortcutKeyManager : public GuiShortcutKeyManager
{
protected:
Dictionary<vint, GuiShortcutKeyItem*> idToItemsMap;
Dictionary<GuiShortcutKeyItem*, vint> itemToIdsMap;
bool IsGlobal() override
{
return true;
}
bool OnCreatingShortcut(GuiShortcutKeyItem* item) override
{
bool ctrl, shift, alt;
VKEY key;
item->ReadKeyConfig(ctrl, shift, alt, key);
vint id = GetCurrentController()->InputService()->RegisterGlobalShortcutKey(ctrl, shift, alt, key);
if (id < (vint)NativeGlobalShortcutKeyResult::ValidIdBegins) return false;
idToItemsMap.Add(id, item);
itemToIdsMap.Add(item, id);
return true;
}
void OnDestroyingShortcut(GuiShortcutKeyItem* item) override
{
vint id = itemToIdsMap[item];
idToItemsMap.Remove(id);
itemToIdsMap.Remove(item);
GetCurrentController()->InputService()->UnregisterGlobalShortcutKey(id);
}
public:
GuiShortcutKeyItem* TryGetItemFromId(vint id)
{
vint index = idToItemsMap.Keys().IndexOf(id);
return index == -1 ? nullptr : idToItemsMap.Values()[index];
}
};
/***********************************************************************
GuiApplication
***********************************************************************/
@@ -211,9 +257,19 @@ GuiApplication
}
}
void GuiApplication::GlobalShortcutKeyActivated(vint id)
{
auto manager = dynamic_cast<GuiGlobalShortcutKeyManager*>(globalShortcutKeyManager.Obj());
if (auto item = manager->TryGetItemFromId(id))
{
item->Execute();
}
}
GuiApplication::GuiApplication()
:locale(Locale::UserDefault())
{
globalShortcutKeyManager = Ptr(new GuiGlobalShortcutKeyManager);
GetCurrentController()->CallbackService()->InstallListener(this);
}
@@ -425,6 +481,11 @@ GuiApplication
return sharedTooltipOwner;
}
compositions::IGuiShortcutKeyManager* GuiApplication::GetGlobalShortcutKeyManager()
{
return globalShortcutKeyManager.Obj();
}
WString GuiApplication::GetExecutablePath()
{
return GetCurrentController()->GetExecutablePath();
@@ -5438,8 +5499,9 @@ namespace vl
GuiShortcutKeyItem
***********************************************************************/
GuiShortcutKeyItem::GuiShortcutKeyItem(GuiShortcutKeyManager* _shortcutKeyManager, bool _ctrl, bool _shift, bool _alt, VKEY _key)
GuiShortcutKeyItem::GuiShortcutKeyItem(GuiShortcutKeyManager* _shortcutKeyManager, bool _global, bool _ctrl, bool _shift, bool _alt, VKEY _key)
:shortcutKeyManager(_shortcutKeyManager)
,global(_global)
,ctrl(_ctrl)
,shift(_shift)
,alt(_alt)
@@ -5459,13 +5521,23 @@ GuiShortcutKeyItem
WString GuiShortcutKeyItem::GetName()
{
WString name;
if(ctrl) name+=L"Ctrl+";
if(shift) name+=L"Shift+";
if(alt) name+=L"Alt+";
name+=GetCurrentController()->InputService()->GetKeyName(key);
if (global) name += L"{";
if (ctrl) name += L"Ctrl+";
if (shift) name += L"Shift+";
if (alt) name += L"Alt+";
name += GetCurrentController()->InputService()->GetKeyName(key);
if (global) name += L"}";
return name;
}
void GuiShortcutKeyItem::ReadKeyConfig(bool& _ctrl, bool& _shift, bool& _alt, VKEY& _key)
{
_ctrl = ctrl;
_shift = shift;
_alt = alt;
_key = key;
}
bool GuiShortcutKeyItem::CanActivate(const NativeWindowKeyInfo& info)
{
return
@@ -5484,16 +5556,48 @@ GuiShortcutKeyItem
_key==key;
}
void GuiShortcutKeyItem::Execute()
{
GuiEventArgs arguments;
Executed.Execute(arguments);
}
/***********************************************************************
GuiShortcutKeyManager
***********************************************************************/
bool GuiShortcutKeyManager::IsGlobal()
{
return false;
}
bool GuiShortcutKeyManager::OnCreatingShortcut(GuiShortcutKeyItem* item)
{
return true;
}
void GuiShortcutKeyManager::OnDestroyingShortcut(GuiShortcutKeyItem* item)
{
}
IGuiShortcutKeyItem* GuiShortcutKeyManager::CreateShortcutInternal(bool ctrl, bool shift, bool alt, VKEY key)
{
auto item = Ptr(new GuiShortcutKeyItem(this, IsGlobal(), ctrl, shift, alt, key));
if (!OnCreatingShortcut(item.Obj())) return nullptr;
shortcutKeyItems.Add(item);
return item.Obj();
}
GuiShortcutKeyManager::GuiShortcutKeyManager()
{
}
GuiShortcutKeyManager::~GuiShortcutKeyManager()
{
for (auto item : shortcutKeyItems)
{
OnDestroyingShortcut(item.Obj());
}
}
vint GuiShortcutKeyManager::GetItemCount()
@@ -5513,51 +5617,55 @@ GuiShortcutKeyManager
{
if(item->CanActivate(info))
{
GuiEventArgs arguments;
item->Executed.Execute(arguments);
item->Execute();
executed=true;
}
}
return executed;
}
IGuiShortcutKeyItem* GuiShortcutKeyManager::CreateShortcut(bool ctrl, bool shift, bool alt, VKEY key)
{
for (auto item : shortcutKeyItems)
{
if(item->CanActivate(ctrl, shift, alt, key))
{
return item.Obj();
}
}
auto item=Ptr(new GuiShortcutKeyItem(this, ctrl, shift, alt, key));
shortcutKeyItems.Add(item);
return item.Obj();
}
bool GuiShortcutKeyManager::DestroyShortcut(bool ctrl, bool shift, bool alt, VKEY key)
{
for (auto item : shortcutKeyItems)
{
if(item->CanActivate(ctrl, shift, alt, key))
{
shortcutKeyItems.Remove(item.Obj());
return true;
}
}
return false;
}
IGuiShortcutKeyItem* GuiShortcutKeyManager::TryGetShortcut(bool ctrl, bool shift, bool alt, VKEY key)
{
for (auto item : shortcutKeyItems)
{
if(item->CanActivate(ctrl, shift, alt, key))
if (item->CanActivate(ctrl, shift, alt, key))
{
return item.Obj();
}
}
return 0;
return nullptr;
}
IGuiShortcutKeyItem* GuiShortcutKeyManager::CreateNewShortcut(bool ctrl, bool shift, bool alt, VKEY key)
{
CHECK_ERROR(
TryGetShortcut(ctrl, shift, alt, key) == nullptr,
L"vl::presentation::compositions::GuiShortcutKeyManager::CreateNewShortcut(bool, bool, bool, VKEY)#The shortcut key exists."
);
return CreateShortcutInternal(ctrl, shift, alt, key);
}
IGuiShortcutKeyItem* GuiShortcutKeyManager::CreateShortcutIfNotExist(bool ctrl, bool shift, bool alt, VKEY key)
{
if (TryGetShortcut(ctrl, shift, alt, key))
{
return nullptr;
}
return CreateShortcutInternal(ctrl, shift, alt, key);
}
bool GuiShortcutKeyManager::DestroyShortcut(IGuiShortcutKeyItem* item)
{
if (!item) return false;
if (item->GetManager() != this) return false;
auto skItem = dynamic_cast<GuiShortcutKeyItem*>(item);
if (!skItem) return false;
vint index = shortcutKeyItems.IndexOf(skItem);
if (index == -1) return false;
OnDestroyingShortcut(skItem);
return shortcutKeyItems.RemoveAt(index);
}
}
}
@@ -16005,6 +16113,7 @@ GuiVirtualTreeListControl
}
}
break;
default:;
}
}
@@ -18089,7 +18198,7 @@ GuiDocumentCommonInterface
void GuiDocumentCommonInterface::AddShortcutCommand(VKEY key, const Func<void()>& eventHandler)
{
IGuiShortcutKeyItem* item=internalShortcutKeyManager->CreateShortcut(true, false, false, key);
IGuiShortcutKeyItem* item=internalShortcutKeyManager->CreateNewShortcut(true, false, false, key);
item->Executed.AttachLambda([=](GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
eventHandler();
@@ -19712,7 +19821,7 @@ GuiTextBoxCommonInterface
void GuiTextBoxCommonInterface::AddShortcutCommand(VKEY key, const Func<void()>& eventHandler)
{
IGuiShortcutKeyItem* item=internalShortcutKeyManager->CreateShortcut(true, false, false, key);
IGuiShortcutKeyItem* item=internalShortcutKeyManager->CreateNewShortcut(true, false, false, key);
item->Executed.AttachLambda([=](GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
eventHandler();
@@ -26058,25 +26167,37 @@ GuiToolstripCommand
DescriptionChanged.Execute(arguments);
}
void GuiToolstripCommand::ReplaceShortcut(compositions::IGuiShortcutKeyItem* value, Ptr<ShortcutBuilder> builder)
compositions::IGuiShortcutKeyManager* GuiToolstripCommand::GetShortcutManagerFromBuilder(Ptr<ShortcutBuilder> builder)
{
if (builder->global)
{
return GetApplication()->GetGlobalShortcutKeyManager();
}
else
{
if (attachedControlHost)
{
if (!attachedControlHost->GetShortcutKeyManager())
{
attachedControlHost->SetShortcutKeyManager(new GuiShortcutKeyManager());
}
return attachedControlHost->GetShortcutKeyManager();
}
}
return nullptr;
}
void GuiToolstripCommand::ReplaceShortcut(compositions::IGuiShortcutKeyItem* value)
{
if (shortcutKeyItem != value)
{
if (shortcutKeyItem)
{
shortcutKeyItem->Executed.Detach(shortcutKeyItemExecutedHandler);
if (shortcutBuilder)
{
auto manager = dynamic_cast<GuiShortcutKeyManager*>(shortcutOwner->GetShortcutKeyManager());
if (manager)
{
manager->DestroyShortcut(shortcutBuilder->ctrl, shortcutBuilder->shift, shortcutBuilder->alt, shortcutBuilder->key);
}
}
shortcutKeyItem->GetManager()->DestroyShortcut(shortcutKeyItem);
}
shortcutKeyItem = nullptr;
shortcutKeyItemExecutedHandler = nullptr;
shortcutBuilder = value ? builder : nullptr;
if (value)
{
shortcutKeyItem = value;
@@ -26091,30 +26212,15 @@ GuiToolstripCommand
List<glr::ParsingError> errors;
if (auto parser = GetParserManager()->GetParser<ShortcutBuilder>(L"SHORTCUT"))
{
if (Ptr<ShortcutBuilder> builder = parser->ParseInternal(builderText, errors))
if (auto builder = parser->ParseInternal(builderText, errors))
{
if (shortcutOwner)
shortcutBuilder = builder;
if (auto shortcutKeyManager = GetShortcutManagerFromBuilder(builder))
{
if (!shortcutOwner->GetShortcutKeyManager())
if (auto item = shortcutKeyManager->CreateShortcutIfNotExist(builder->ctrl, builder->shift, builder->alt, builder->key))
{
shortcutOwner->SetShortcutKeyManager(new GuiShortcutKeyManager);
ReplaceShortcut(item);
}
if (auto manager = dynamic_cast<GuiShortcutKeyManager*>(shortcutOwner->GetShortcutKeyManager()))
{
IGuiShortcutKeyItem* item = manager->TryGetShortcut(builder->ctrl, builder->shift, builder->alt, builder->key);
if (!item)
{
item = manager->CreateShortcut(builder->ctrl, builder->shift, builder->alt, builder->key);
if (item)
{
ReplaceShortcut(item, builder);
}
}
}
}
else
{
shortcutBuilder = builder;
}
}
}
@@ -26132,16 +26238,15 @@ GuiToolstripCommand
host = composition->GetRelatedControlHost();
}
if (shortcutOwner != host)
if (attachedControlHost != host)
{
if (shortcutOwner)
{
ReplaceShortcut(nullptr, nullptr);
shortcutOwner = nullptr;
}
shortcutOwner = host;
if (shortcutBuilder && !shortcutKeyItem)
attachedControlHost = host;
if (shortcutBuilder && !shortcutBuilder->global)
{
if (shortcutKeyItem)
{
ReplaceShortcut(nullptr);
}
BuildShortcut(shortcutBuilder->text);
}
}
@@ -26153,6 +26258,10 @@ GuiToolstripCommand
GuiToolstripCommand::~GuiToolstripCommand()
{
if (shortcutBuilder && shortcutKeyItem)
{
ReplaceShortcut(nullptr);
}
}
void GuiToolstripCommand::Attach(GuiInstanceRootObject* rootObject)
@@ -26246,11 +26355,6 @@ GuiToolstripCommand
return shortcutKeyItem;
}
void GuiToolstripCommand::SetShortcut(compositions::IGuiShortcutKeyItem* value)
{
ReplaceShortcut(value, 0);
}
WString GuiToolstripCommand::GetShortcutBuilder()
{
return shortcutBuilder ? shortcutBuilder->text : L"";
@@ -26298,13 +26402,15 @@ GuiToolstripCommand::ShortcutBuilder Parser
typedef GuiToolstripCommand::ShortcutBuilder ShortcutBuilder;
public:
Regex regexShortcut;
const vint _global;
const vint _ctrl;
const vint _shift;
const vint _alt;
const vint _key;
GuiToolstripCommandShortcutParser()
: regexShortcut(L"((<ctrl>Ctrl)/+|(<shift>Shift)/+|(<alt>Alt)/+)*(<key>/.+)")
: regexShortcut(L"((<global>global:))?((<ctrl>Ctrl)/+|(<shift>Shift)/+|(<alt>Alt)/+)*(<key>/.+)")
, _global(regexShortcut.CaptureNames().IndexOf(L"global"))
, _ctrl(regexShortcut.CaptureNames().IndexOf(L"ctrl"))
, _shift(regexShortcut.CaptureNames().IndexOf(L"shift"))
, _alt(regexShortcut.CaptureNames().IndexOf(L"alt"))
@@ -26325,6 +26431,7 @@ GuiToolstripCommand::ShortcutBuilder Parser
auto builder = Ptr(new ShortcutBuilder);
builder->text = text;
builder->global = match->Groups().Contains(_global);
builder->ctrl = match->Groups().Contains(_ctrl);
builder->shift = match->Groups().Contains(_shift);
builder->alt = match->Groups().Contains(_alt);
@@ -33793,6 +33900,10 @@ INativeControllerListener
{
}
void INativeControllerListener::GlobalShortcutKeyActivated(vint id)
{
}
void INativeControllerListener::NativeWindowCreated(INativeWindow* window)
{
}
@@ -34207,6 +34318,16 @@ public:
{
CHECK_FAIL(L"Not implemented!");
}
vint RegisterGlobalShortcutKey(bool ctrl, bool shift, bool alt, VKEY key) override
{
CHECK_FAIL(L"Not Implemented!");
}
bool UnregisterGlobalShortcutKey(vint id) override
{
CHECK_FAIL(L"Not Implemented!");
}
};
extern void GuiApplicationMain();
@@ -34974,6 +35095,11 @@ GuiHostedController::INativeControllerListener
callbackService.InvokeClipboardUpdated();
}
void GuiHostedController::GlobalShortcutKeyActivated(vint id)
{
callbackService.InvokeGlobalShortcutKeyActivated(id);
}
void GuiHostedController::NativeWindowDestroying(INativeWindow* window)
{
if (nativeWindow == window)
@@ -54633,6 +54759,14 @@ SharedCallbackService
}
}
void SharedCallbackService::InvokeGlobalShortcutKeyActivated(vint id)
{
for (vint i = 0; i < listeners.Count(); i++)
{
listeners[i]->GlobalShortcutKeyActivated(id);
}
}
void SharedCallbackService::InvokeNativeWindowCreated(INativeWindow* window)
{
for(vint i=0;i<listeners.Count();i++)
+101 -43
View File
@@ -2858,52 +2858,78 @@ INativeWindowService
/***********************************************************************
INativeInputService
***********************************************************************/
enum class NativeGlobalShortcutKeyResult : vint
{
NotSupported = -2,
Occupied = -1,
ValidIdBegins = 0,
};
/// <summary>
/// User input service. To access this service, use [M:vl.presentation.INativeController.InputService].
/// </summary>
class INativeInputService : public virtual IDescriptable, public Description<INativeInputService>
{
public:
public:
/// <summary>
/// Start to reveive global timer message.
/// </summary>
virtual void StartTimer()=0;
virtual void StartTimer()=0;
/// <summary>
/// Stop to receive global timer message.
/// </summary>
virtual void StopTimer()=0;
virtual void StopTimer()=0;
/// <summary>
/// Test is the global timer message receiving enabled.
/// </summary>
/// <returns>Returns true if the global timer message receiving is enabled.</returns>
virtual bool IsTimerEnabled()=0;
virtual bool IsTimerEnabled()=0;
/// <summary>
/// Test is the specified key pressing.
/// </summary>
/// <returns>Returns true if the specified key is pressing.</returns>
/// <param name="code">The key code to test.</param>
virtual bool IsKeyPressing(VKEY code)=0;
virtual bool IsKeyPressing(VKEY code)=0;
/// <summary>
/// Test is the specified key toggled.
/// </summary>
/// <returns>Returns true if the specified key is toggled.</returns>
/// <param name="code">The key code to test.</param>
virtual bool IsKeyToggled(VKEY code)=0;
virtual bool IsKeyToggled(VKEY code)=0;
/// <summary>
/// Get the name of a key.
/// </summary>
/// <returns>The name of a key.</returns>
/// <param name="code">The key code.</param>
virtual WString GetKeyName(VKEY code)=0;
virtual WString GetKeyName(VKEY code)=0;
/// <summary>
/// Get the key from a name.
/// </summary>
/// <returns>The key, returns -1 if the key name doesn't exist.</returns>
/// <param name="name">Key name</param>
virtual VKEY GetKey(const WString& name)=0;
virtual VKEY GetKey(const WString& name)=0;
/// <summary>
/// Register a system-wide shortcut key that doesn't require any window to be foreground window.
/// If the shortcut key is activated, <see cref="INativeControllerListener::GlobalShortcutKeyActivated"/> will be called.
/// </summary>
/// <param name="ctrl">Set to true if the CTRL key is required.</param>
/// <param name="shift">Set to true if the SHIFT key is required.</param>
/// <param name="alt">Set to true if the ALT key is required.</param>
/// <param name="key">The non-control key.</param>
/// <param name="id"></param>
/// <returns>Returns the created id. If it fails, the id equals to one of an item in <see cref="NativeGlobalShortcutKeyResult"/> except "ValidIdBegins".</returns>
virtual vint RegisterGlobalShortcutKey(bool ctrl, bool shift, bool alt, VKEY key)=0;
/// <summary>
/// Unregister a system-wide shortcut key.
/// </summary>
/// <param name="id">The created id.</param>
/// <returns>Returns true if this operation succeeded.</returns>
virtual bool UnregisterGlobalShortcutKey(vint id)=0;
};
/***********************************************************************
@@ -2927,6 +2953,10 @@ INativeCallbackService
/// </summary>
virtual void InvokeClipboardUpdated()=0;
/// <summary>
/// Invoke <see cref="INativeControllerListener::ClipboardUpdated"/> of all installed listeners.
/// </summary>
virtual void InvokeGlobalShortcutKeyActivated(vint id) = 0;
/// <summary>
/// Invoke <see cref="INativeControllerListener::NativeWindowCreated"/> of all installed listeners.
/// </summary>
/// <param name="window">The argument to the callback.</param>
@@ -3249,6 +3279,11 @@ Native Window Controller
/// </summary>
virtual void ClipboardUpdated();
/// <summary>
/// Called when a registered system-wide shortcut key is activated.
/// </summary>
/// <param name="id"></param>
virtual void GlobalShortcutKeyActivated(vint id);
/// <summary>
/// Called when a window is created.
/// </summary>
/// <param name="window">The created window.</param>
@@ -4514,6 +4549,32 @@ Shortcut Key Manager
/// <returns>Returns true if at least one shortcut key item is executed.</returns>
/// <param name="info">The key event info.</param>
virtual bool Execute(const NativeWindowKeyInfo& info)=0;
/// <summary>Get a shortcut key item using a key combination. If the item for the key combination does not exist, this function returns null.</summary>
/// <returns>The shortcut key item.</returns>
/// <param name="ctrl">Set to true if the CTRL key is required.</param>
/// <param name="shift">Set to true if the SHIFT key is required.</param>
/// <param name="alt">Set to true if the ALT key is required.</param>
/// <param name="key">The non-control key.</param>
virtual IGuiShortcutKeyItem* TryGetShortcut(bool ctrl, bool shift, bool alt, VKEY key)=0;
/// <summary>Create a shortcut key item using a key combination. If the item for the key combination exists, this function crashes.</summary>
/// <returns>The created shortcut key item.</returns>
/// <param name="ctrl">Set to true if the CTRL key is required.</param>
/// <param name="shift">Set to true if the SHIFT key is required.</param>
/// <param name="alt">Set to true if the ALT key is required.</param>
/// <param name="key">The non-control key.</param>
virtual IGuiShortcutKeyItem* CreateNewShortcut(bool ctrl, bool shift, bool alt, VKEY key)=0;
/// <summary>Create a shortcut key item using a key combination. If the item for the key combination exists, this function returns the item that is created before.</summary>
/// <returns>The created shortcut key item.</returns>
/// <param name="ctrl">Set to true if the CTRL key is required.</param>
/// <param name="shift">Set to true if the SHIFT key is required.</param>
/// <param name="alt">Set to true if the ALT key is required.</param>
/// <param name="key">The non-control key.</param>
virtual IGuiShortcutKeyItem* CreateShortcutIfNotExist(bool ctrl, bool shift, bool alt, VKEY key)=0;
/// <summary>Destroy a shortcut key item using a key combination</summary>
/// <returns>Returns true if the manager destroyed a existing shortcut key item.</returns>
/// <param name="item">The shortcut key item.</param>
virtual bool DestroyShortcut(IGuiShortcutKeyItem* item)=0;
};
/***********************************************************************
@@ -4526,21 +4587,23 @@ Shortcut Key Manager Helpers
{
protected:
GuiShortcutKeyManager* shortcutKeyManager;
bool global;
bool ctrl;
bool shift;
bool alt;
VKEY key;
void AttachManager(GuiShortcutKeyManager* manager);
void DetachManager(GuiShortcutKeyManager* manager);
public:
GuiShortcutKeyItem(GuiShortcutKeyManager* _shortcutKeyManager, bool _ctrl, bool _shift, bool _alt, VKEY _key);
GuiShortcutKeyItem(GuiShortcutKeyManager* _shortcutKeyManager, bool _global, bool _ctrl, bool _shift, bool _alt, VKEY _key);
~GuiShortcutKeyItem();
IGuiShortcutKeyManager* GetManager()override;
WString GetName()override;
void ReadKeyConfig(bool& _ctrl, bool& _shift, bool& _alt, VKEY& _key);
bool CanActivate(const NativeWindowKeyInfo& info);
bool CanActivate(bool _ctrl, bool _shift, bool _alt, VKEY _key);
void Execute();
};
/// <summary>A default implementation for <see cref="IGuiShortcutKeyManager"/>.</summary>
@@ -4549,7 +4612,11 @@ Shortcut Key Manager Helpers
typedef collections::List<Ptr<GuiShortcutKeyItem>> ShortcutKeyItemList;
protected:
ShortcutKeyItemList shortcutKeyItems;
virtual bool IsGlobal();
virtual bool OnCreatingShortcut(GuiShortcutKeyItem* item);
virtual void OnDestroyingShortcut(GuiShortcutKeyItem* item);
IGuiShortcutKeyItem* CreateShortcutInternal(bool ctrl, bool shift, bool alt, VKEY key);
public:
/// <summary>Create the shortcut key manager.</summary>
GuiShortcutKeyManager();
@@ -4558,28 +4625,11 @@ Shortcut Key Manager Helpers
vint GetItemCount()override;
IGuiShortcutKeyItem* GetItem(vint index)override;
bool Execute(const NativeWindowKeyInfo& info)override;
/// <summary>Create a shortcut key item using a key combination. If the item for the key combination exists, this function returns the item that is created before.</summary>
/// <returns>The created shortcut key item.</returns>
/// <param name="ctrl">Set to true if the CTRL key is required.</param>
/// <param name="shift">Set to true if the SHIFT key is required.</param>
/// <param name="alt">Set to true if the ALT key is required.</param>
/// <param name="key">The non-control key.</param>
IGuiShortcutKeyItem* CreateShortcut(bool ctrl, bool shift, bool alt, VKEY key);
/// <summary>Destroy a shortcut key item using a key combination</summary>
/// <returns>Returns true if the manager destroyed a existing shortcut key item.</returns>
/// <param name="ctrl">Set to true if the CTRL key is required.</param>
/// <param name="shift">Set to true if the SHIFT key is required.</param>
/// <param name="alt">Set to true if the ALT key is required.</param>
/// <param name="key">The non-control key.</param>
bool DestroyShortcut(bool ctrl, bool shift, bool alt, VKEY key);
/// <summary>Get a shortcut key item using a key combination. If the item for the key combination does not exist, this function returns null.</summary>
/// <returns>The shortcut key item.</returns>
/// <param name="ctrl">Set to true if the CTRL key is required.</param>
/// <param name="shift">Set to true if the SHIFT key is required.</param>
/// <param name="alt">Set to true if the ALT key is required.</param>
/// <param name="key">The non-control key.</param>
IGuiShortcutKeyItem* TryGetShortcut(bool ctrl, bool shift, bool alt, VKEY key);
IGuiShortcutKeyItem* TryGetShortcut(bool ctrl, bool shift, bool alt, VKEY key)override;
IGuiShortcutKeyItem* CreateNewShortcut(bool ctrl, bool shift, bool alt, VKEY key)override;
IGuiShortcutKeyItem* CreateShortcutIfNotExist(bool ctrl, bool shift, bool alt, VKEY key)override;
bool DestroyShortcut(IGuiShortcutKeyItem* item)override;
};
}
}
@@ -9783,6 +9833,7 @@ Application
void InvokeClipboardNotify(compositions::GuiGraphicsComposition* composition, compositions::GuiEventArgs& arguments);
void ClipboardUpdated()override;
void GlobalShortcutKeyActivated(vint id)override;
protected:
using WindowMap = collections::Dictionary<INativeWindow*, GuiWindow*>;
@@ -9797,6 +9848,7 @@ Application
collections::List<GuiWindow*> windows;
WindowMap windowMap;
collections::SortedList<GuiPopup*> openingPopups;
Ptr<compositions::GuiShortcutKeyManager> globalShortcutKeyManager;
GuiApplication();
~GuiApplication();
@@ -9853,6 +9905,9 @@ Application
/// <summary>Get the tooltip owner. When the tooltip closed, it returns null.</summary>
/// <returns>The tooltip owner.</returns>
GuiControl* GetTooltipOwner();
/// <summary>Get the <see cref="compositions::IGuiShortcutKeyManager"/> attached with this control host.</summary>
/// <returns>The shortcut key manager.</returns>
compositions::IGuiShortcutKeyManager* GetGlobalShortcutKeyManager();
/// <summary>Get the file path of the current executable.</summary>
/// <returns>The file path of the current executable.</returns>
WString GetExecutablePath();
@@ -10334,6 +10389,7 @@ namespace vl
namespace compositions
{
class IGuiShortcutKeyItem;
class IGuiShortcutKeyManager;
}
namespace controls
@@ -10346,10 +10402,11 @@ namespace vl
{
public:
WString text;
bool ctrl;
bool shift;
bool alt;
VKEY key;
bool global = false;
bool ctrl = false;
bool shift = false;
bool alt = false;
VKEY key = VKEY::KEY_UNKNOWN;
};
protected:
Ptr<GuiImageData> image;
@@ -10362,13 +10419,15 @@ namespace vl
Ptr<ShortcutBuilder> shortcutBuilder;
GuiInstanceRootObject* attachedRootObject = nullptr;
GuiControlHost* attachedControlHost = nullptr;
Ptr<compositions::IGuiGraphicsEventHandler> renderTargetChangedHandler;
GuiControlHost* shortcutOwner = nullptr;
void OnShortcutKeyItemExecuted(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments);
void OnRenderTargetChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments);
void InvokeDescriptionChanged();
void ReplaceShortcut(compositions::IGuiShortcutKeyItem* value, Ptr<ShortcutBuilder> builder);
compositions::IGuiShortcutKeyManager* GetShortcutManagerFromBuilder(Ptr<ShortcutBuilder> builder);
void ReplaceShortcut(compositions::IGuiShortcutKeyItem* value);
void BuildShortcut(const WString& builderText);
void UpdateShortcutOwner();
public:
@@ -10406,9 +10465,6 @@ namespace vl
/// <summary>Get the shortcut key item for this command.</summary>
/// <returns>The shortcut key item for this command.</returns>
compositions::IGuiShortcutKeyItem* GetShortcut();
/// <summary>Set the shortcut key item for this command.</summary>
/// <param name="value">The shortcut key item for this command.</param>
void SetShortcut(compositions::IGuiShortcutKeyItem* value);
/// <summary>Get the shortcut builder for this command.</summary>
/// <returns>The shortcut builder for this command.</returns>
WString GetShortcutBuilder();
@@ -25016,6 +25072,7 @@ namespace vl
void InvokeGlobalTimer() override;
void InvokeClipboardUpdated() override;
void InvokeGlobalShortcutKeyActivated(vint id) override;
void InvokeNativeWindowCreated(INativeWindow* window) override;
void InvokeNativeWindowDestroying(INativeWindow* window) override;
};
@@ -25182,6 +25239,7 @@ GuiHostedController
void GlobalTimer() override;
void ClipboardUpdated() override;
void GlobalShortcutKeyActivated(vint id) override;
void NativeWindowDestroying(INativeWindow* window) override;
// =============================================================
+15 -5
View File
@@ -581,11 +581,20 @@ Type Declaration
CLASS_MEMBER_METHOD_OVERLOAD(GetScreen, {L"window"}, INativeScreen*(INativeScreenService::*)(INativeWindow*))
END_INTERFACE_MEMBER(INativeScreenService)
BEGIN_ENUM_ITEM(NativeGlobalShortcutKeyResult)
ENUM_ITEM_NAMESPACE(NativeGlobalShortcutKeyResult)
ENUM_NAMESPACE_ITEM(NotSupported)
ENUM_NAMESPACE_ITEM(Occupied)
ENUM_NAMESPACE_ITEM(ValidIdBegins)
END_ENUM_ITEM(NativeGlobalShortcutKeyResult)
BEGIN_INTERFACE_MEMBER_NOPROXY(INativeInputService)
CLASS_MEMBER_METHOD(IsKeyPressing, { L"code" })
CLASS_MEMBER_METHOD(IsKeyToggled, { L"code" })
CLASS_MEMBER_METHOD(GetKeyName, { L"code" })
CLASS_MEMBER_METHOD(GetKey, { L"name" })
CLASS_MEMBER_METHOD(RegisterGlobalShortcutKey, { L"ctrl" _ L"shift" _ L"alt" _ L"key" })
CLASS_MEMBER_METHOD(UnregisterGlobalShortcutKey, { L"id" })
END_INTERFACE_MEMBER(INativeInputService)
BEGIN_ENUM_ITEM(INativeDialogService::MessageBoxButtonsInput)
@@ -1204,15 +1213,15 @@ Type Declaration (Extra)
CLASS_MEMBER_PROPERTY_READONLY_FAST(ItemCount)
CLASS_MEMBER_METHOD(GetItem, {L"index"})
CLASS_MEMBER_METHOD(TryGetShortcut, { L"ctrl" _ L"shift" _ L"alt" _ L"ket" })
CLASS_MEMBER_METHOD(CreateNewShortcut, { L"ctrl" _ L"shift" _ L"alt" _ L"ket" })
CLASS_MEMBER_METHOD(CreateShortcutIfNotExist, { L"ctrl" _ L"shift" _ L"alt" _ L"ket" })
CLASS_MEMBER_METHOD(DestroyShortcut, { L"ctrl" _ L"shift" _ L"alt" _ L"ket" })
END_INTERFACE_MEMBER(IGuiShortcutKeyManager)
BEGIN_CLASS_MEMBER(GuiShortcutKeyManager)
CLASS_MEMBER_BASE(IGuiShortcutKeyManager)
CLASS_MEMBER_CONSTRUCTOR(GuiShortcutKeyManager*(), NO_PARAMETER)
CLASS_MEMBER_METHOD(CreateShortcut, {L"ctrl" _ L"shift" _ L"alt" _ L"ket"})
CLASS_MEMBER_METHOD(DestroyShortcut, {L"ctrl" _ L"shift" _ L"alt" _ L"ket"})
CLASS_MEMBER_METHOD(TryGetShortcut, {L"ctrl" _ L"shift" _ L"alt" _ L"ket"})
END_CLASS_MEMBER(GuiShortcutKeyManager)
BEGIN_INTERFACE_MEMBER_NOPROXY(IGuiAltAction)
@@ -1650,6 +1659,7 @@ Type Declaration (Extra)
CLASS_MEMBER_PROPERTY_READONLY_FAST(ExecutablePath)
CLASS_MEMBER_PROPERTY_READONLY_FAST(ExecutableFolder)
CLASS_MEMBER_PROPERTY_READONLY_FAST(Windows)
CLASS_MEMBER_PROPERTY_READONLY_FAST(GlobalShortcutKeyManager)
CLASS_MEMBER_METHOD(Run, {L"mainWindow"})
CLASS_MEMBER_METHOD(RunOneCycle, NO_PARAMETER)
@@ -2095,7 +2105,7 @@ Type Declaration (Extra)
CLASS_MEMBER_PROPERTY_EVENT_FAST(LargeImage, DescriptionChanged)
CLASS_MEMBER_PROPERTY_EVENT_FAST(Image, DescriptionChanged)
CLASS_MEMBER_PROPERTY_EVENT_FAST(Text, DescriptionChanged)
CLASS_MEMBER_PROPERTY_EVENT_FAST(Shortcut, DescriptionChanged)
CLASS_MEMBER_PROPERTY_EVENT_READONLY_FAST(Shortcut, DescriptionChanged)
CLASS_MEMBER_PROPERTY_EVENT_FAST(ShortcutBuilder, DescriptionChanged)
CLASS_MEMBER_PROPERTY_EVENT_FAST(Enabled, DescriptionChanged)
CLASS_MEMBER_PROPERTY_EVENT_FAST(Selected, DescriptionChanged)
+1
View File
@@ -147,6 +147,7 @@ Type List (Basic)
F(presentation::INativeClipboardWriter)\
F(presentation::INativeClipboardService)\
F(presentation::INativeScreenService)\
F(presentation::NativeGlobalShortcutKeyResult)\
F(presentation::INativeInputService)\
F(presentation::INativeDialogService::MessageBoxButtonsInput)\
F(presentation::INativeDialogService::MessageBoxButtonsOutput)\
-1
View File
@@ -4531,7 +4531,6 @@ Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#include <limits.h>
#include <float.h>
namespace vl
{
+105 -20
View File
@@ -2833,6 +2833,9 @@ Licensed under https://github.com/vczh-libraries/License
#ifndef VCZH_REFLECTION_TYPES_TYPEDVALUESERIALIZERPROVIDER
#define VCZH_REFLECTION_TYPES_TYPEDVALUESERIALIZERPROVIDER
#ifdef VCZH_GCC
#include <float.h>
#endif
namespace vl
{
@@ -2841,10 +2844,87 @@ namespace vl
namespace description
{
/***********************************************************************
Constants
***********************************************************************/
template<typename T>
struct TypedValueSerializerMinMax;
template<>
struct TypedValueSerializerMinMax<vint8_t>
{
static constexpr vint8_t Min = _I8_MIN;
static constexpr vint8_t Max = _I8_MAX;
};
template<>
struct TypedValueSerializerMinMax<vint16_t>
{
static constexpr vint16_t Min = _I16_MIN;
static constexpr vint16_t Max = _I16_MAX;
};
template<>
struct TypedValueSerializerMinMax<vint32_t>
{
static constexpr vint32_t Min = _I32_MIN;
static constexpr vint32_t Max = _I32_MAX;
};
template<>
struct TypedValueSerializerMinMax<vint64_t>
{
static constexpr vint64_t Min = _I64_MIN;
static constexpr vint64_t Max = _I64_MAX;
};
template<>
struct TypedValueSerializerMinMax<vuint8_t>
{
static constexpr vuint8_t Min = 0;
static constexpr vuint8_t Max = _UI8_MAX;
};
template<>
struct TypedValueSerializerMinMax<vuint16_t>
{
static constexpr vuint16_t Min = 0;
static constexpr vuint16_t Max = _UI16_MAX;
};
template<>
struct TypedValueSerializerMinMax<vuint32_t>
{
static constexpr vuint32_t Min = 0;
static constexpr vuint32_t Max = _UI32_MAX;
};
template<>
struct TypedValueSerializerMinMax<vuint64_t>
{
static constexpr vuint64_t Min = 0;
static constexpr vuint64_t Max = _UI64_MAX;
};
template<>
struct TypedValueSerializerMinMax<float>
{
static constexpr float Min = (float)-FLT_MAX;
static constexpr float Max = (float)FLT_MAX;
};
template<>
struct TypedValueSerializerMinMax<double>
{
static constexpr double Min = (double)-DBL_MAX;
static constexpr double Max = (double)DBL_MAX;
};
/***********************************************************************
Signed Types
***********************************************************************/
template<typename T, T MinValue, T MaxValue>
template<typename T>
struct TypedValueSerializerProvider_Signed
{
static T GetDefaultValue()
@@ -2860,6 +2940,8 @@ Signed Types
static bool Deserialize(const WString& input, T& output)
{
constexpr T MinValue = TypedValueSerializerMinMax<T>::Min;
constexpr T MaxValue = TypedValueSerializerMinMax<T>::Max;
bool success = false;
vint64_t result = wtoi64_test(input, success);
if (!success) return false;
@@ -2873,7 +2955,7 @@ Signed Types
Unsigned Types
***********************************************************************/
template<typename T, T MaxValue>
template<typename T>
struct TypedValueSerializerProvider_Unsigned
{
static T GetDefaultValue()
@@ -2889,6 +2971,7 @@ Unsigned Types
static bool Deserialize(const WString& input, T& output)
{
constexpr T MaxValue = TypedValueSerializerMinMax<T>::Max;
bool success = false;
vuint64_t result = wtou64_test(input, success);
if (!success) return false;
@@ -2902,7 +2985,7 @@ Unsigned Types
Floating Point Types
***********************************************************************/
template<typename T, T MaxValue>
template<typename T>
struct TypedValueSerializerProvider_FloatingPoint
{
static T GetDefaultValue()
@@ -2919,10 +3002,12 @@ Floating Point Types
static bool Deserialize(const WString& input, T& output)
{
constexpr T MinValue = TypedValueSerializerMinMax<T>::Min;
constexpr T MaxValue = TypedValueSerializerMinMax<T>::Max;
bool success = false;
double result = wtof_test(input, success);
if (!success) return false;
if (result < -MaxValue || result > MaxValue) return false;
if (result < MinValue || result > MaxValue) return false;
output = (T)result;
return true;
}
@@ -2932,29 +3017,29 @@ Floating Point Types
Serializable Types
***********************************************************************/
#define DEFINE_SIGNED_TVSP(TYPENAME, MINVALUE, MAXVALUE)\
template<> struct TypedValueSerializerProvider<TYPENAME> : TypedValueSerializerProvider_Signed<TYPENAME, MINVALUE, MAXVALUE> {};\
#define DEFINE_SIGNED_TVSP(TYPENAME)\
template<> struct TypedValueSerializerProvider<TYPENAME> : TypedValueSerializerProvider_Signed<TYPENAME> {};\
DEFINE_SIGNED_TVSP(vint8_t, _I8_MIN, _I8_MAX)
DEFINE_SIGNED_TVSP(vint16_t, _I16_MIN, _I16_MAX)
DEFINE_SIGNED_TVSP(vint32_t, _I32_MIN, _I32_MAX)
DEFINE_SIGNED_TVSP(vint64_t, _I64_MIN, _I64_MAX)
DEFINE_SIGNED_TVSP(vint8_t)
DEFINE_SIGNED_TVSP(vint16_t)
DEFINE_SIGNED_TVSP(vint32_t)
DEFINE_SIGNED_TVSP(vint64_t)
#undef DEFINE_SIGNED_TVSP
#define DEFINE_UNSIGNED_TVSP(TYPENAME, MAXVALUE)\
template<> struct TypedValueSerializerProvider<TYPENAME> : TypedValueSerializerProvider_Unsigned<TYPENAME, MAXVALUE> {};\
#define DEFINE_UNSIGNED_TVSP(TYPENAME)\
template<> struct TypedValueSerializerProvider<TYPENAME> : TypedValueSerializerProvider_Unsigned<TYPENAME> {};\
DEFINE_UNSIGNED_TVSP(vuint8_t, _UI8_MAX)
DEFINE_UNSIGNED_TVSP(vuint16_t, _UI16_MAX)
DEFINE_UNSIGNED_TVSP(vuint32_t, _UI32_MAX)
DEFINE_UNSIGNED_TVSP(vuint64_t, _UI64_MAX)
DEFINE_UNSIGNED_TVSP(vuint8_t)
DEFINE_UNSIGNED_TVSP(vuint16_t)
DEFINE_UNSIGNED_TVSP(vuint32_t)
DEFINE_UNSIGNED_TVSP(vuint64_t)
#undef DEFINE_UNSIGNED_TVSP
#define DEFINE_FLOAT_TVSP(TYPENAME, MAXVALUE)\
template<> struct TypedValueSerializerProvider<TYPENAME> : TypedValueSerializerProvider_FloatingPoint<TYPENAME, MAXVALUE> {};\
#define DEFINE_FLOAT_TVSP(TYPENAME)\
template<> struct TypedValueSerializerProvider<TYPENAME> : TypedValueSerializerProvider_FloatingPoint<TYPENAME> {};\
DEFINE_FLOAT_TVSP(float, (float)FLT_MAX)
DEFINE_FLOAT_TVSP(double, (double)DBL_MAX)
DEFINE_FLOAT_TVSP(float)
DEFINE_FLOAT_TVSP(double)
#undef DEFINE_FLOAT_TVSP
#define DEFINE_TVSP(TYPENAME)\