Files
GacUI/Import/GacUI.cpp
2025-05-12 11:04:25 -07:00

63855 lines
2.2 MiB

/***********************************************************************
THIS FILE IS AUTOMATICALLY GENERATED. DO NOT MODIFY
DEVELOPER: Zihan Chen(vczh)
***********************************************************************/
#include "GacUI.h"
#ifndef VCZH_DEBUG_NO_REFLECTION
#include "GacUIReflection.h"
#endif
/***********************************************************************
.\GACUIREFLECTIONHELPER.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace helper_types
{
/***********************************************************************
LocalizedStrings
***********************************************************************/
WString LocalizedStrings::FirstOrEmpty(const collections::LazyList<WString>& formats)
{
return formats.First(WString::Empty);
}
}
}
namespace reflection
{
namespace description
{
using namespace glr::xml;
using namespace stream;
using namespace collections;
using namespace presentation;
using namespace presentation::elements;
using namespace presentation::compositions;
using namespace presentation::controls;
using namespace presentation::theme;
using namespace presentation::templates;
/***********************************************************************
Serialization (Color)
***********************************************************************/
Color TypedValueSerializerProvider<Color>::GetDefaultValue()
{
return Color();
}
bool TypedValueSerializerProvider<Color>::Serialize(const Color& input, WString& output)
{
output = input.ToString();
return true;
}
bool TypedValueSerializerProvider<Color>::Deserialize(const WString& input, Color& output)
{
output = Color::Parse(input);
return true;
}
/***********************************************************************
Serialization (DocumentFontSize)
***********************************************************************/
DocumentFontSize TypedValueSerializerProvider<DocumentFontSize>::GetDefaultValue()
{
return DocumentFontSize();
}
bool TypedValueSerializerProvider<DocumentFontSize>::Serialize(const DocumentFontSize& input, WString& output)
{
output = input.ToString();
return true;
}
bool TypedValueSerializerProvider<DocumentFontSize>::Deserialize(const WString& input, DocumentFontSize& output)
{
output = DocumentFontSize::Parse(input);
return true;
}
/***********************************************************************
Serialization (GlobalStringKey)
***********************************************************************/
GlobalStringKey TypedValueSerializerProvider<GlobalStringKey>::GetDefaultValue()
{
return GlobalStringKey();
}
bool TypedValueSerializerProvider<GlobalStringKey>::Serialize(const GlobalStringKey& input, WString& output)
{
output = input.ToString();
return true;
}
bool TypedValueSerializerProvider<GlobalStringKey>::Deserialize(const WString& input, GlobalStringKey& output)
{
output = GlobalStringKey::Get(input);
return true;
}
/***********************************************************************
External Functions (Basic)
***********************************************************************/
Ptr<INativeImage> INativeImage_Constructor(const WString& path)
{
return GetCurrentController()->ImageService()->CreateImageFromFile(path);
}
INativeCursor* INativeCursor_Constructor1()
{
return GetCurrentController()->ResourceService()->GetDefaultSystemCursor();
}
INativeCursor* INativeCursor_Constructor2(INativeCursor::SystemCursorType type)
{
return GetCurrentController()->ResourceService()->GetSystemCursor(type);
}
/***********************************************************************
External Functions (Elements)
***********************************************************************/
text::TextLines* GuiColorizedTextElement_GetLines(GuiColorizedTextElement* thisObject)
{
return &thisObject->GetLines();
}
/***********************************************************************
External Functions (Compositions)
***********************************************************************/
void GuiTableComposition_SetRows(GuiTableComposition* thisObject, vint value)
{
vint columns = thisObject->GetColumns();
if (columns <= 0) columns = 1;
thisObject->SetRowsAndColumns(value, columns);
}
void GuiTableComposition_SetColumns(GuiTableComposition* thisObject, vint value)
{
vint row = thisObject->GetRows();
if (row <= 0) row = 1;
thisObject->SetRowsAndColumns(row, value);
}
void IGuiAltActionHost_CollectAltActions(IGuiAltActionHost* host, List<IGuiAltAction*>& actions)
{
Group<WString, IGuiAltAction*> group;
host->CollectAltActions(group);
// TODO: (enumerable) Linq:SelectMany
for (vint i = 0; i < group.Count(); i++)
{
CopyFrom(actions, group.GetByIndex(i), true);
}
}
}
}
}
/***********************************************************************
.\APPLICATION\CONTROLS\GUIAPPLICATION.CPP
***********************************************************************/
extern void GuiMain();
namespace vl
{
namespace presentation
{
extern void GuiInitializeUtilities();
extern void GuiFinalizeUtilities();
namespace controls
{
using namespace collections;
using namespace compositions;
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
***********************************************************************/
void GuiApplication::InvokeClipboardNotify(compositions::GuiGraphicsComposition* composition, compositions::GuiEventArgs& arguments)
{
if(composition->HasEventReceiver())
{
composition->GetEventReceiver()->clipboardNotify.Execute(arguments);
}
for (auto subComposition : composition->Children())
{
InvokeClipboardNotify(subComposition, arguments);
}
}
void GuiApplication::ClipboardUpdated()
{
for(vint i=0;i<windows.Count();i++)
{
GuiEventArgs arguments=windows[i]->GetNotifyEventArguments();
windows[i]->ClipboardUpdated.Execute(arguments);
InvokeClipboardNotify(windows[i]->GetBoundsComposition(), arguments);
}
}
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);
}
GuiApplication::~GuiApplication()
{
if(sharedTooltipControl)
{
delete sharedTooltipControl;
sharedTooltipControl=0;
}
GetCurrentController()->CallbackService()->UninstallListener(this);
}
INativeWindow* GuiApplication::GetThreadContextNativeWindow(GuiControlHost* controlHost)
{
return nullptr;
}
void GuiApplication::RegisterWindow(GuiWindow* window)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::controls::GuiApplication::RegisterWindow(GuiWindow*)#"
CHECK_ERROR(!window->registeredInApplication, ERROR_MESSAGE_PREFIX L"The window has been registered");
window->registeredInApplication = true;
windows.Add(window);
if (auto nativeWindow = window->GetNativeWindow())
{
windowMap.Add(nativeWindow, window);
}
#undef ERROR_MESSAGE_PREFIX
}
void GuiApplication::UnregisterWindow(GuiWindow* window)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::controls::GuiApplication::UnregisterWindow(GuiWindow*)#"
CHECK_ERROR(window->registeredInApplication, ERROR_MESSAGE_PREFIX L"The window has not been registered");
window->registeredInApplication = false;
if (auto nativeWindow = window->GetNativeWindow())
{
windowMap.Remove(nativeWindow);
}
windows.Remove(window);
#undef ERROR_MESSAGE_PREFIX
}
void GuiApplication::NotifyNativeWindowChanged(GuiControlHost* controlHost, INativeWindow* previousNativeWindow)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::controls::GuiApplication::NotifyNativeWindowChanged(GuiControlsHost*, INativeWindow*)#"
if (auto window = dynamic_cast<GuiWindow*>(controlHost))
{
if (!window->registeredInApplication) return;
if (previousNativeWindow)
{
CHECK_ERROR(windowMap[previousNativeWindow] == window, ERROR_MESSAGE_PREFIX L"Unpaired arguments.");
windowMap.Remove(previousNativeWindow);
}
if (auto nativeWindow = window->GetNativeWindow())
{
windowMap.Add(nativeWindow, window);
}
}
#undef ERROR_MESSAGE_PREFIX
}
void GuiApplication::RegisterPopupOpened(GuiPopup* popup)
{
vint index=openingPopups.IndexOf(popup);
if(index==-1)
{
openingPopups.Add(popup);
}
}
void GuiApplication::RegisterPopupClosed(GuiPopup* popup)
{
if(openingPopups.Remove(popup))
{
}
}
void GuiApplication::TooltipMouseEnter(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
sharedTooltipHovering=true;
}
void GuiApplication::TooltipMouseLeave(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
sharedTooltipHovering=false;
if(sharedTooltipClosing)
{
CloseTooltip();
}
}
Locale GuiApplication::GetLocale()
{
return locale;
}
void GuiApplication::SetLocale(Locale value)
{
if (locale != value)
{
locale = value;
LocaleChanged();
}
}
void GuiApplication::Run(GuiWindow* _mainWindow)
{
if (!mainWindow)
{
mainWindow = _mainWindow;
GetCurrentController()->WindowService()->Run(mainWindow->GetNativeWindow());
mainWindow = nullptr;
}
}
bool GuiApplication::RunOneCycle()
{
return GetCurrentController()->WindowService()->RunOneCycle();
}
GuiWindow* GuiApplication::GetMainWindow()
{
return mainWindow;
}
const collections::List<GuiWindow*>& GuiApplication::GetWindows()
{
return windows;
}
GuiWindow* GuiApplication::GetWindow(NativePoint location)
{
INativeWindow* nativeWindow = GetCurrentController()->WindowService()->GetWindow(location);
if (nativeWindow)
{
// TODO: (enumerable) foreach
for (vint i = 0; i < windows.Count(); i++)
{
GuiWindow* window = windows[i];
if (window->GetNativeWindow() == nativeWindow)
{
return window;
}
}
}
return 0;
}
GuiWindow* GuiApplication::GetWindowFromNative(INativeWindow* nativeWindow)
{
vint index = windowMap.Keys().IndexOf(nativeWindow);
return index == -1 ? nullptr : windowMap.Values()[index];
}
void GuiApplication::ShowTooltip(GuiControl* owner, GuiControl* tooltip, vint preferredContentWidth, Point location)
{
GuiWindow* ownerWindow = dynamic_cast<GuiWindow*>(owner->GetRelatedControlHost());
if (sharedTooltipOwnerWindow != ownerWindow)
{
delete sharedTooltipControl;
sharedTooltipControl = 0;
}
if(!sharedTooltipControl)
{
sharedTooltipControl = new GuiTooltip(theme::ThemeName::Tooltip);
if (ownerWindow)
{
if (auto tooltipStyle = ownerWindow->TypedControlTemplateObject(true)->GetTooltipTemplate())
{
sharedTooltipControl->SetControlTemplate(tooltipStyle);
}
}
sharedTooltipControl->GetBoundsComposition()->GetEventReceiver()->mouseEnter.AttachMethod(this, &GuiApplication::TooltipMouseEnter);
sharedTooltipControl->GetBoundsComposition()->GetEventReceiver()->mouseLeave.AttachMethod(this, &GuiApplication::TooltipMouseLeave);
}
sharedTooltipHovering=false;
sharedTooltipClosing=false;
sharedTooltipOwnerWindow = ownerWindow;
sharedTooltipOwner=owner;
sharedTooltipControl->SetTemporaryContentControl(tooltip);
sharedTooltipControl->SetPreferredContentWidth(preferredContentWidth);
sharedTooltipControl->SetClientSize(Size(10, 10));
sharedTooltipControl->ShowPopup(owner, location);
}
void GuiApplication::CloseTooltip()
{
if(sharedTooltipControl)
{
if(sharedTooltipHovering)
{
sharedTooltipClosing=true;
}
else
{
sharedTooltipClosing=false;
sharedTooltipControl->Close();
}
}
}
GuiControl* GuiApplication::GetTooltipOwner()
{
if(!sharedTooltipControl) return 0;
if(!sharedTooltipControl->GetTemporaryContentControl()) return 0;
return sharedTooltipOwner;
}
compositions::IGuiShortcutKeyManager* GuiApplication::GetGlobalShortcutKeyManager()
{
return globalShortcutKeyManager.Obj();
}
WString GuiApplication::GetExecutablePath()
{
return GetCurrentController()->GetExecutablePath();
}
WString GuiApplication::GetExecutableFolder()
{
WString path=GetExecutablePath();
for(vint i=path.Length()-1;i>=0;i--)
{
if(path[i]==L'\\' || path[i]==L'/')
{
return path.Sub(0, i+1);
}
}
return L"";
}
bool GuiApplication::IsInMainThread(GuiControlHost* controlHost)
{
return GetCurrentController()->AsyncService()->IsInMainThread(GetThreadContextNativeWindow(controlHost));
}
void GuiApplication::InvokeAsync(const Func<void()>& proc)
{
GetCurrentController()->AsyncService()->InvokeAsync(proc);
}
void GuiApplication::InvokeInMainThread(GuiControlHost* controlHost, const Func<void()>& proc)
{
GetCurrentController()->AsyncService()->InvokeInMainThread(GetThreadContextNativeWindow(controlHost), proc);
}
bool GuiApplication::InvokeInMainThreadAndWait(GuiControlHost* controlHost, const Func<void()>& proc, vint milliseconds)
{
CHECK_ERROR(!IsInMainThread(controlHost), L"GuiApplication::InvokeInMainThreadAndWait(GuiControlHost*, const Func<void()>&, vint)#This function cannot be called in UI thread.");
return GetCurrentController()->AsyncService()->InvokeInMainThreadAndWait(GetThreadContextNativeWindow(controlHost), proc, milliseconds);
}
Ptr<INativeDelay> GuiApplication::DelayExecute(const Func<void()>& proc, vint milliseconds)
{
return GetCurrentController()->AsyncService()->DelayExecute(proc, milliseconds);
}
Ptr<INativeDelay> GuiApplication::DelayExecuteInMainThread(const Func<void()>& proc, vint milliseconds)
{
return GetCurrentController()->AsyncService()->DelayExecuteInMainThread(proc, milliseconds);
}
void GuiApplication::RunGuiTask(GuiControlHost* controlHost, const Func<void()>& proc)
{
if (IsInMainThread(controlHost))
{
proc();
}
else
{
InvokeInMainThreadAndWait(controlHost, [&proc]()
{
proc();
});
}
}
/***********************************************************************
Helpers
***********************************************************************/
GuiApplication* application = nullptr;
bool GACUI_UNITTEST_ONLY_SKIP_THREAD_LOCAL_STORAGE_DISPOSE_STORAGES = false;
bool GACUI_UNITTEST_ONLY_SKIP_TYPE_AND_PLUGIN_LOAD_UNLOAD = false;
GuiApplication* GetApplication()
{
return application;
}
/***********************************************************************
GuiApplicationMain
***********************************************************************/
class UIThreadAsyncScheduler :public Object, public IAsyncScheduler, public Description<UIThreadAsyncScheduler>
{
public:
void Execute(const Func<void()>& callback)override
{
GetApplication()->InvokeInMainThread(GetApplication()->GetMainWindow(), callback);
}
void ExecuteInBackground(const Func<void()>& callback)override
{
GetApplication()->InvokeAsync(callback);
}
void DelayExecute(const Func<void()>& callback, vint milliseconds)override
{
GetApplication()->DelayExecuteInMainThread(callback, milliseconds);
}
};
class OtherThreadAsyncScheduler :public Object, public IAsyncScheduler, public Description<UIThreadAsyncScheduler>
{
public:
void Execute(const Func<void()>& callback)override
{
GetApplication()->InvokeAsync(callback);
}
void ExecuteInBackground(const Func<void()>& callback)override
{
GetApplication()->InvokeAsync(callback);
}
void DelayExecute(const Func<void()>& callback, vint milliseconds)override
{
GetApplication()->DelayExecute(callback, milliseconds);
}
};
void GuiApplicationInitialize()
{
theme::InitializeTheme();
if (!GACUI_UNITTEST_ONLY_SKIP_TYPE_AND_PLUGIN_LOAD_UNLOAD)
{
#ifndef VCZH_DEBUG_NO_REFLECTION
GetGlobalTypeManager()->Load();
#endif
GetPluginManager()->Load(true, true);
}
else
{
GetPluginManager()->Load(false, true);
}
GetCurrentController()->InputService()->StartTimer();
{
GuiApplication app;
application = &app;
IAsyncScheduler::RegisterSchedulerForCurrentThread(Ptr(new UIThreadAsyncScheduler));
IAsyncScheduler::RegisterDefaultScheduler(Ptr(new OtherThreadAsyncScheduler));
GuiInitializeUtilities();
GuiMain();
GuiFinalizeUtilities();
IAsyncScheduler::UnregisterDefaultScheduler();
IAsyncScheduler::UnregisterSchedulerForCurrentThread();
application = nullptr;
}
GetCurrentController()->InputService()->StopTimer();
theme::FinalizeTheme();
FinalizeGlobalStorage();
if (!GACUI_UNITTEST_ONLY_SKIP_TYPE_AND_PLUGIN_LOAD_UNLOAD)
{
GetPluginManager()->Unload(true, true);
DestroyPluginManager();
#ifndef VCZH_DEBUG_NO_REFLECTION
ResetGlobalTypeManager();
#endif
}
else
{
GetPluginManager()->Unload(false, true);
}
if (!GACUI_UNITTEST_ONLY_SKIP_THREAD_LOCAL_STORAGE_DISPOSE_STORAGES)
{
ThreadLocalStorage::DisposeStorages();
}
}
void GuiRawInitialize()
{
if (!GACUI_UNITTEST_ONLY_SKIP_TYPE_AND_PLUGIN_LOAD_UNLOAD)
{
#ifndef VCZH_DEBUG_NO_REFLECTION
GetGlobalTypeManager()->Load();
#endif
GetPluginManager()->Load(true, true);
}
else
{
GetPluginManager()->Load(false, true);
}
GetCurrentController()->InputService()->StartTimer();
{
IAsyncScheduler::RegisterSchedulerForCurrentThread(Ptr(new UIThreadAsyncScheduler));
IAsyncScheduler::RegisterDefaultScheduler(Ptr(new OtherThreadAsyncScheduler));
GuiMain();
IAsyncScheduler::UnregisterDefaultScheduler();
IAsyncScheduler::UnregisterSchedulerForCurrentThread();
}
GetCurrentController()->InputService()->StopTimer();
FinalizeGlobalStorage();
if (!GACUI_UNITTEST_ONLY_SKIP_TYPE_AND_PLUGIN_LOAD_UNLOAD)
{
GetPluginManager()->Unload(true, true);
DestroyPluginManager();
#ifndef VCZH_DEBUG_NO_REFLECTION
ResetGlobalTypeManager();
#endif
}
else
{
GetPluginManager()->Unload(false, true);
}
if (!GACUI_UNITTEST_ONLY_SKIP_THREAD_LOCAL_STORAGE_DISPOSE_STORAGES)
{
ThreadLocalStorage::DisposeStorages();
}
}
}
}
}
void GuiRawMain()
{
vl::presentation::controls::GuiRawInitialize();
}
void GuiApplicationMain()
{
vl::presentation::controls::GuiApplicationInitialize();
}
/***********************************************************************
.\APPLICATION\CONTROLS\GUIBASICCONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace elements;
using namespace compositions;
using namespace collections;
using namespace reflection::description;
/***********************************************************************
GuiDisposedFlag
***********************************************************************/
void GuiDisposedFlag::SetDisposed()
{
disposed = true;
}
GuiDisposedFlag::GuiDisposedFlag(GuiControl* _owner)
:owner(_owner)
{
}
GuiDisposedFlag::~GuiDisposedFlag()
{
}
bool GuiDisposedFlag::IsDisposed()
{
return disposed;
}
/***********************************************************************
GuiControl
***********************************************************************/
Ptr<GuiDisposedFlag> GuiControl::GetDisposedFlag()
{
if (!disposedFlag)
{
disposedFlag = Ptr(new GuiDisposedFlag(this));
}
return disposedFlag;
}
void GuiControl::BeforeControlTemplateUninstalled()
{
}
void GuiControl::AfterControlTemplateInstalled(bool initialize)
{
controlTemplateObject->SetText(text);
controlTemplateObject->SetFont(displayFont);
controlTemplateObject->SetContext(context);
controlTemplateObject->SetVisuallyEnabled(isVisuallyEnabled);
controlTemplateObject->SetFocusableComposition(focusableComposition);
controlTemplateObject->SetFocused(isFocused);
}
void GuiControl::CheckAndStoreControlTemplate(templates::GuiControlTemplate* value)
{
controlTemplateObject = value;
}
void GuiControl::EnsureControlTemplateExists()
{
if (!controlTemplateObject)
{
RebuildControlTemplate();
}
}
void GuiControl::RebuildControlTemplate()
{
bool initialize = controlTemplateObject == nullptr;
if (controlTemplateObject)
{
BeforeControlTemplateUninstalled();
containerComposition->GetParent()->RemoveChild(containerComposition);
boundsComposition->AddChild(containerComposition);
SafeDeleteComposition(controlTemplateObject);
controlTemplateObject = nullptr;
}
if (controlTemplate)
{
CheckAndStoreControlTemplate(controlTemplate({}));
}
else
{
CheckAndStoreControlTemplate(theme::GetCurrentTheme()->CreateStyle(controlThemeName)({}));
}
if (controlTemplateObject)
{
controlTemplateObject->SetAlignmentToParent(Margin(0, 0, 0, 0));
containerComposition->GetParent()->RemoveChild(containerComposition);
boundsComposition->AddChild(controlTemplateObject);
controlTemplateObject->GetContainerComposition()->AddChild(containerComposition);
AfterControlTemplateInstalled(initialize);
}
}
void GuiControl::OnChildInserted(GuiControl* control)
{
GuiControl* oldParent=control->parent;
children.Add(control);
control->parent=this;
control->OnParentChanged(oldParent, control->parent);
control->UpdateVisuallyEnabled();
control->UpdateDisplayFont();
if (auto host = boundsComposition->GetRelatedGraphicsHost())
{
host->InvalidateTabOrderCache();
}
}
void GuiControl::OnChildRemoved(GuiControl* control)
{
GuiControl* oldParent=control->parent;
control->parent=0;
children.Remove(control);
control->OnParentChanged(oldParent, control->parent);
if (auto host = boundsComposition->GetRelatedGraphicsHost())
{
host->InvalidateTabOrderCache();
}
}
void GuiControl::OnParentChanged(GuiControl* oldParent, GuiControl* newParent)
{
OnParentLineChanged();
}
void GuiControl::OnParentLineChanged()
{
{
GuiControlSignalEventArgs arguments(boundsComposition);
arguments.controlSignal = ControlSignal::ParentLineChanged;
ControlSignalTrigerred.Execute(arguments);
}
// TODO: (enumerable) foreach
for(vint i=0;i<children.Count();i++)
{
children[i]->OnParentLineChanged();
}
}
void GuiControl::OnServiceAdded()
{
{
GuiControlSignalEventArgs arguments(boundsComposition);
arguments.controlSignal = ControlSignal::ServiceAdded;
ControlSignalTrigerred.Execute(arguments);
}
// TODO: (enumerable) foreach
for(vint i=0;i<children.Count();i++)
{
children[i]->OnParentLineChanged();
}
}
void GuiControl::OnRenderTargetChanged(elements::IGuiGraphicsRenderTarget* renderTarget)
{
GuiControlSignalEventArgs arguments(boundsComposition);
arguments.controlSignal = ControlSignal::RenderTargetChanged;
ControlSignalTrigerred.Execute(arguments);
}
void GuiControl::OnBeforeReleaseGraphicsHost()
{
// TODO: (enumerable) foreach
for(vint i=0;i<children.Count();i++)
{
children[i]->OnBeforeReleaseGraphicsHost();
}
}
void GuiControl::UpdateVisuallyEnabled()
{
bool newValue = isEnabled && (parent == 0 ? true : parent->GetVisuallyEnabled());
if (isVisuallyEnabled != newValue)
{
isVisuallyEnabled = newValue;
if (!isVisuallyEnabled && isFocused)
{
GuiControl* selectedControl = nullptr;
auto current = GetParent();
while (current)
{
if (current->GetFocusableComposition() && current->GetVisuallyEnabled())
{
selectedControl = current;
break;
}
current = current->GetParent();
}
if (selectedControl)
{
selectedControl->SetFocused();
}
else if(auto host = focusableComposition->GetRelatedGraphicsHost())
{
host->ClearFocus();
}
}
if (controlTemplateObject)
{
controlTemplateObject->SetVisuallyEnabled(isVisuallyEnabled);
}
VisuallyEnabledChanged.Execute(GetNotifyEventArguments());
// TODO: (enumerable) foreach
for (vint i = 0; i < children.Count(); i++)
{
children[i]->UpdateVisuallyEnabled();
}
}
}
void GuiControl::UpdateDisplayFont()
{
auto newValue =
font ? font.Value() :
parent ? parent->GetDisplayFont() :
GetCurrentController()->ResourceService()->GetDefaultFont();
if (displayFont != newValue)
{
displayFont = newValue;
if (controlTemplateObject)
{
controlTemplateObject->SetFont(displayFont);
}
DisplayFontChanged.Execute(GetNotifyEventArguments());
// TODO: (enumerable) foreach
for (vint i = 0; i < children.Count(); i++)
{
children[i]->UpdateDisplayFont();
}
}
}
void GuiControl::OnGotFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (!isFocused)
{
isFocused = true;
if (controlTemplateObject)
{
controlTemplateObject->SetFocused(true);
}
FocusedChanged.Execute(GetNotifyEventArguments());
}
}
void GuiControl::OnLostFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (isFocused)
{
isFocused = false;
if (controlTemplateObject)
{
controlTemplateObject->SetFocused(false);
}
FocusedChanged.Execute(GetNotifyEventArguments());
}
}
void GuiControl::SetFocusableComposition(compositions::GuiGraphicsComposition* value)
{
if (focusableComposition != value)
{
if (focusableComposition)
{
focusableComposition->GetEventReceiver()->gotFocus.Detach(gotFocusHandler);
focusableComposition->GetEventReceiver()->lostFocus.Detach(lostFocusHandler);
gotFocusHandler = nullptr;
lostFocusHandler = nullptr;
}
focusableComposition = value;
if (controlTemplateObject)
{
controlTemplateObject->SetFocusableComposition(focusableComposition);
}
if (focusableComposition)
{
gotFocusHandler = focusableComposition->GetEventReceiver()->gotFocus.AttachMethod(this, &GuiControl::OnGotFocus);
lostFocusHandler = focusableComposition->GetEventReceiver()->lostFocus.AttachMethod(this, &GuiControl::OnLostFocus);
}
else
{
GuiEventArgs arguments(boundsComposition);
OnLostFocus(boundsComposition, arguments);
}
}
}
bool GuiControl::IsControlVisibleAndEnabled()
{
GuiControl* control = this;
while (control)
{
if (!control->GetVisible() || !control->GetEnabled())
{
return false;
}
control = control->GetParent();
}
return true;
}
bool GuiControl::IsAltEnabled()
{
return IsControlVisibleAndEnabled();
}
bool GuiControl::IsAltAvailable()
{
return focusableComposition != nullptr && alt != L"";
}
compositions::GuiGraphicsComposition* GuiControl::GetAltComposition()
{
return boundsComposition;
}
compositions::IGuiAltActionHost* GuiControl::GetActivatingAltHost()
{
return activatingAltHost;
}
void GuiControl::OnActiveAlt()
{
SetFocused();
}
bool GuiControl::IsTabEnabled()
{
return IsControlVisibleAndEnabled();
}
bool GuiControl::IsTabAvailable()
{
return focusableComposition != nullptr;
}
bool GuiControl::SharedPtrDestructorProc(DescriptableObject* obj, bool forceDisposing)
{
GuiControl* value=dynamic_cast<GuiControl*>(obj);
if(value->GetBoundsComposition()->GetParent())
{
if (!forceDisposing) return false;
}
SafeDeleteControl(value);
return true;
}
GuiControl::GuiControl(theme::ThemeName themeName)
:controlThemeName(themeName)
{
if (auto controller = GetCurrentController())
{
displayFont = controller->ResourceService()->GetDefaultFont();
}
{
boundsComposition = new GuiBoundsComposition;
boundsComposition->SetAssociatedControl(this);
boundsComposition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
containerComposition = new GuiBoundsComposition;
containerComposition->SetTransparentToMouse(true);
containerComposition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
containerComposition->SetAlignmentToParent(Margin(0, 0, 0, 0));
boundsComposition->AddChild(containerComposition);
}
{
ControlThemeNameChanged.SetAssociatedComposition(boundsComposition);
ControlTemplateChanged.SetAssociatedComposition(boundsComposition);
ControlSignalTrigerred.SetAssociatedComposition(boundsComposition);
VisibleChanged.SetAssociatedComposition(boundsComposition);
EnabledChanged.SetAssociatedComposition(boundsComposition);
FocusedChanged.SetAssociatedComposition(boundsComposition);
VisuallyEnabledChanged.SetAssociatedComposition(boundsComposition);
DisplayFontChanged.SetAssociatedComposition(boundsComposition);
AltChanged.SetAssociatedComposition(boundsComposition);
TextChanged.SetAssociatedComposition(boundsComposition);
FontChanged.SetAssociatedComposition(boundsComposition);
ContextChanged.SetAssociatedComposition(boundsComposition);
}
sharedPtrDestructorProc = &GuiControl::SharedPtrDestructorProc;
}
GuiControl::~GuiControl()
{
if (disposedFlag)
{
disposedFlag->SetDisposed();
}
// prevent a root bounds composition from notifying its dead controls
if (!parent)
{
NotifyFinalizeInstance(boundsComposition);
}
if (tooltipControl)
{
// the only legal parent is the GuiApplication::sharedTooltipWindow
if (tooltipControl->GetBoundsComposition()->GetParent())
{
tooltipControl->GetBoundsComposition()->GetParent()->RemoveChild(tooltipControl->GetBoundsComposition());
}
delete tooltipControl;
}
// TODO: (enumerable) foreach
for (vint i = 0; i < children.Count(); i++)
{
delete children[i];
}
children.Clear();
// let the root control of a control tree delete the whole composition tree
if (!parent)
{
delete boundsComposition;
}
}
void GuiControl::TryDelayExecuteIfNotDeleted(Func<void()> proc)
{
if (auto controlHost = GetRelatedControlHost())
{
auto flag = GetDisposedFlag();
GetApplication()->InvokeInMainThread(controlHost, [=]()
{
if (!flag->IsDisposed())
{
proc();
}
});
}
else
{
proc();
}
}
compositions::GuiEventArgs GuiControl::GetNotifyEventArguments()
{
return GuiEventArgs(boundsComposition);
}
theme::ThemeName GuiControl::GetControlThemeName()
{
return controlThemeName;
}
void GuiControl::SetControlThemeName(theme::ThemeName value)
{
SetControlThemeNameAndTemplate(value, controlTemplate);
}
GuiControl::ControlTemplatePropertyType GuiControl::GetControlTemplate()
{
return controlTemplate;
}
void GuiControl::SetControlTemplate(const ControlTemplatePropertyType& value)
{
SetControlThemeNameAndTemplate(controlThemeName, value);
}
void GuiControl::SetControlThemeNameAndTemplate(theme::ThemeName themeNameValue, const ControlTemplatePropertyType& controlTemplateValue)
{
bool themeChanged = (controlThemeName != themeNameValue);
bool templateChanged = (controlTemplate || controlTemplateValue);
if (themeChanged || templateChanged)
{
controlThemeName = themeNameValue;
controlTemplate = controlTemplateValue;
RebuildControlTemplate();
if (themeChanged)
{
ControlThemeNameChanged.Execute(GetNotifyEventArguments());
}
if (templateChanged)
{
ControlTemplateChanged.Execute(GetNotifyEventArguments());
}
}
}
templates::GuiControlTemplate* GuiControl::GetControlTemplateObject()
{
EnsureControlTemplateExists();
return controlTemplateObject;
}
compositions::GuiBoundsComposition* GuiControl::GetBoundsComposition()
{
EnsureControlTemplateExists();
return boundsComposition;
}
compositions::GuiGraphicsComposition* GuiControl::GetContainerComposition()
{
EnsureControlTemplateExists();
return containerComposition;
}
compositions::GuiGraphicsComposition* GuiControl::GetFocusableComposition()
{
EnsureControlTemplateExists();
return focusableComposition;
}
GuiControl* GuiControl::GetParent()
{
return parent;
}
vint GuiControl::GetChildrenCount()
{
return children.Count();
}
GuiControl* GuiControl::GetChild(vint index)
{
return children[index];
}
bool GuiControl::AddChild(GuiControl* control)
{
return GetContainerComposition()->AddChild(control->GetBoundsComposition());
}
bool GuiControl::HasChild(GuiControl* control)
{
return children.Contains(control);
}
GuiControlHost* GuiControl::GetRelatedControlHost()
{
return parent?parent->GetRelatedControlHost():0;
}
bool GuiControl::GetVisuallyEnabled()
{
return isVisuallyEnabled;
}
bool GuiControl::GetFocused()
{
return isFocused;
}
void GuiControl::SetFocused()
{
if (!focusableComposition) return;
if (!isVisuallyEnabled) return;
if (!focusableComposition->GetEventuallyVisible()) return;
if (auto host = focusableComposition->GetRelatedGraphicsHost())
{
host->SetFocus(focusableComposition);
}
}
bool GuiControl::GetAcceptTabInput()
{
return acceptTabInput;
}
void GuiControl::SetAcceptTabInput(bool value)
{
acceptTabInput = value;
}
vint GuiControl::GetTabPriority()
{
return tabPriority;
}
void GuiControl::SetTabPriority(vint value)
{
vint newTabPriority = value < 0 ? -1 : value;
if (tabPriority != newTabPriority)
{
tabPriority = newTabPriority;
if (auto host = boundsComposition->GetRelatedGraphicsHost())
{
host->InvalidateTabOrderCache();
}
}
}
bool GuiControl::GetEnabled()
{
return isEnabled;
}
void GuiControl::SetEnabled(bool value)
{
if(isEnabled!=value)
{
isEnabled=value;
EnabledChanged.Execute(GetNotifyEventArguments());
UpdateVisuallyEnabled();
}
}
bool GuiControl::GetVisible()
{
return isVisible;
}
void GuiControl::SetVisible(bool value)
{
boundsComposition->SetVisible(value);
if(isVisible!=value)
{
isVisible=value;
VisibleChanged.Execute(GetNotifyEventArguments());
}
}
const WString& GuiControl::GetAlt()
{
return alt;
}
bool GuiControl::SetAlt(const WString& value)
{
if (!IGuiAltAction::IsLegalAlt(value)) return false;
if (alt != value)
{
alt = value;
AltChanged.Execute(GetNotifyEventArguments());
}
return true;
}
void GuiControl::SetActivatingAltHost(compositions::IGuiAltActionHost* host)
{
activatingAltHost = host;
}
const WString& GuiControl::GetText()
{
return text;
}
void GuiControl::SetText(const WString& value)
{
if (text != value)
{
text = value;
if (controlTemplateObject)
{
controlTemplateObject->SetText(text);
}
TextChanged.Execute(GetNotifyEventArguments());
}
}
const Nullable<FontProperties>& GuiControl::GetFont()
{
return font;
}
void GuiControl::SetFont(const Nullable<FontProperties>& value)
{
if (font != value)
{
font = value;
FontChanged.Execute(GetNotifyEventArguments());
UpdateDisplayFont();
}
}
const FontProperties& GuiControl::GetDisplayFont()
{
return displayFont;
}
description::Value GuiControl::GetContext()
{
return context;
}
void GuiControl::SetContext(const description::Value& value)
{
if (context != value)
{
context = value;
if (controlTemplateObject)
{
controlTemplateObject->SetContext(context);
}
ContextChanged.Execute(GetNotifyEventArguments());
}
}
description::Value GuiControl::GetTag()
{
return tag;
}
void GuiControl::SetTag(const description::Value& value)
{
tag=value;
}
GuiControl* GuiControl::GetTooltipControl()
{
return tooltipControl;
}
GuiControl* GuiControl::SetTooltipControl(GuiControl* value)
{
GuiControl* oldTooltipControl=tooltipControl;
tooltipControl=value;
return oldTooltipControl;
}
vint GuiControl::GetTooltipWidth()
{
return tooltipWidth;
}
void GuiControl::SetTooltipWidth(vint value)
{
tooltipWidth=value;
}
bool GuiControl::DisplayTooltip(Point location)
{
if(!tooltipControl) return false;
GetApplication()->ShowTooltip(this, tooltipControl, tooltipWidth, location);
return true;
}
void GuiControl::CloseTooltip()
{
if(GetApplication()->GetTooltipOwner()==this)
{
GetApplication()->CloseTooltip();
}
}
IDescriptable* GuiControl::QueryService(const WString& identifier)
{
if (identifier == IGuiAltAction::Identifier)
{
return (IGuiAltAction*)this;
}
else if (identifier == IGuiAltActionContainer::Identifier)
{
return nullptr;
}
else if (identifier == IGuiTabAction::Identifier)
{
return (IGuiTabAction*)this;
}
else
{
vint index = controlServices.Keys().IndexOf(identifier);
if (index != -1)
{
return controlServices.Values()[index].Obj();
}
if (parent)
{
return parent->QueryService(identifier);
}
}
return nullptr;
}
bool GuiControl::AddService(const WString& identifier, Ptr<IDescriptable> value)
{
if (controlServices.Keys().Contains(identifier))
{
return false;
}
controlServices.Add(identifier, value);
OnServiceAdded();
return true;
}
/***********************************************************************
GuiCustomControl
***********************************************************************/
controls::GuiControlHost* GuiCustomControl::GetControlHostForInstance()
{
return GetRelatedControlHost();
}
void GuiCustomControl::OnParentLineChanged()
{
GuiControl::OnParentLineChanged();
OnControlHostForInstanceChanged();
}
GuiCustomControl::GuiCustomControl(theme::ThemeName themeName)
:GuiControl(themeName)
{
}
GuiCustomControl::~GuiCustomControl()
{
FinalizeAggregation();
FinalizeInstanceRecursively(this);
}
}
}
}
/***********************************************************************
.\APPLICATION\CONTROLS\GUIINSTANCEROOTOBJECT.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace reflection::description;
using namespace compositions;
/***********************************************************************
GuiComponent
***********************************************************************/
GuiComponent::GuiComponent()
{
}
GuiComponent::~GuiComponent()
{
}
void GuiComponent::Attach(GuiInstanceRootObject* rootObject)
{
}
void GuiComponent::Detach(GuiInstanceRootObject* rootObject)
{
}
/***********************************************************************
GuiInstanceRootObject
***********************************************************************/
class RootObjectTimerCallback : public Object, public IGuiGraphicsTimerCallback
{
public:
GuiControlHost* controlHost;
GuiInstanceRootObject* rootObject;
bool alive = true;
RootObjectTimerCallback(GuiInstanceRootObject* _rootObject, GuiControlHost* _controlHost)
:rootObject(_rootObject)
, controlHost(_controlHost)
{
}
bool Play()override
{
if (alive)
{
// TODO: (enumerable) foreach:indexed(alterable(reversed))
for (vint i = rootObject->runningAnimations.Count() - 1; i >= 0; i--)
{
auto animation = rootObject->runningAnimations[i];
animation->Run();
if (animation->GetStopped())
{
rootObject->runningAnimations.RemoveAt(i);
}
}
if (rootObject->runningAnimations.Count() == 0)
{
rootObject->UninstallTimerCallback(nullptr);
return false;
}
}
return alive;
}
};
void GuiInstanceRootObject::InstallTimerCallback(controls::GuiControlHost* controlHost)
{
if (!timerCallback)
{
timerCallback = Ptr(new RootObjectTimerCallback(this, controlHost));
controlHost->GetTimerManager()->AddCallback(timerCallback);
}
}
bool GuiInstanceRootObject::UninstallTimerCallback(controls::GuiControlHost* controlHost)
{
if (timerCallback && timerCallback->controlHost != controlHost)
{
timerCallback->alive = false;
timerCallback = nullptr;
return true;
}
return false;
}
void GuiInstanceRootObject::OnControlHostForInstanceChanged()
{
auto controlHost = GetControlHostForInstance();
if (UninstallTimerCallback(controlHost))
{
for (auto animation : runningAnimations)
{
animation->Pause();
}
}
if (controlHost)
{
InstallTimerCallback(controlHost);
for (auto animation : runningAnimations)
{
animation->Resume();
}
StartPendingAnimations();
}
}
void GuiInstanceRootObject::StartPendingAnimations()
{
for (auto animation : pendingAnimations)
{
animation->Start();
}
CopyFrom(runningAnimations, pendingAnimations, true);
pendingAnimations.Clear();
}
GuiInstanceRootObject::GuiInstanceRootObject()
{
}
GuiInstanceRootObject::~GuiInstanceRootObject()
{
UninstallTimerCallback(nullptr);
}
void GuiInstanceRootObject::FinalizeInstance()
{
if (!finalized)
{
finalized = true;
for (auto subscription : subscriptions)
{
subscription->Close();
}
for (auto component : components)
{
component->Detach(this);
}
subscriptions.Clear();
// TODO: (enumerable) foreach
for (vint i = 0; i<components.Count(); i++)
{
delete components[i];
}
components.Clear();
}
}
bool GuiInstanceRootObject::IsFinalized()
{
return finalized;
}
void GuiInstanceRootObject::FinalizeInstanceRecursively(templates::GuiTemplate* thisObject)
{
if (!finalized)
{
NotifyFinalizeInstance(thisObject);
}
}
void GuiInstanceRootObject::FinalizeInstanceRecursively(GuiCustomControl* thisObject)
{
if (!finalized)
{
NotifyFinalizeInstance(thisObject);
}
}
void GuiInstanceRootObject::FinalizeInstanceRecursively(GuiControlHost* thisObject)
{
if (!finalized)
{
NotifyFinalizeInstance(thisObject);
}
}
void GuiInstanceRootObject::FinalizeGeneralInstance(GuiInstanceRootObject* thisObject)
{
}
void GuiInstanceRootObject::SetResourceResolver(Ptr<GuiResourcePathResolver> resolver)
{
resourceResolver = resolver;
}
Ptr<DescriptableObject> GuiInstanceRootObject::ResolveResource(const WString& protocol, const WString& path, bool ensureExist)
{
Ptr<DescriptableObject> object;
if (resourceResolver)
{
object = resourceResolver->ResolveResource(protocol, path);
}
if (ensureExist && !object)
{
throw ArgumentException(L"Resource \"" + protocol + L"://" + path + L"\" does not exist.");
}
return object;
}
Ptr<description::IValueSubscription> GuiInstanceRootObject::AddSubscription(Ptr<description::IValueSubscription> subscription)
{
CHECK_ERROR(finalized == false, L"GuiInstanceRootObject::AddSubscription(Ptr<IValueSubscription>)#Cannot add subscription after finalizing.");
if (subscriptions.Contains(subscription.Obj()))
{
return nullptr;
}
else
{
subscriptions.Add(subscription);
subscription->Open();
subscription->Update();
return subscription;
}
}
void GuiInstanceRootObject::UpdateSubscriptions()
{
for (auto subscription : subscriptions)
{
subscription->Update();
}
}
bool GuiInstanceRootObject::AddComponent(GuiComponent* component)
{
CHECK_ERROR(finalized == false, L"GuiInstanceRootObject::AddComponent(GuiComponent*)#Cannot add component after finalizing.");
if(components.Contains(component))
{
return false;
}
else
{
components.Add(component);
component->Attach(this);
return true;
}
}
bool GuiInstanceRootObject::AddControlHostComponent(GuiControlHost* controlHost)
{
return AddComponent(new GuiObjectComponent<GuiControlHost>(Ptr(controlHost)));
}
bool GuiInstanceRootObject::AddAnimation(Ptr<IGuiAnimation> animation)
{
CHECK_ERROR(finalized == false, L"GuiInstanceRootObject::AddAnimation(Ptr<IGuiAnimation>)#Cannot add animation after finalizing.");
if (runningAnimations.Contains(animation.Obj()) || pendingAnimations.Contains(animation.Obj()))
{
return false;
}
else
{
pendingAnimations.Add(animation);
if (auto controlHost = GetControlHostForInstance())
{
InstallTimerCallback(controlHost);
StartPendingAnimations();
}
return true;
}
}
bool GuiInstanceRootObject::KillAnimation(Ptr<IGuiAnimation> animation)
{
if (!animation) return false;
if (runningAnimations.Contains(animation.Obj()))
{
runningAnimations.Remove(animation.Obj());
return true;
}
if (pendingAnimations.Contains(animation.Obj()))
{
pendingAnimations.Remove(animation.Obj());
return true;
}
return false;
}
reflection::description::Value GuiInstanceRootObject::GetNamedObject(const WString& name)
{
vint index = namedObjects.Keys().IndexOf(name);
if (index == -1)
{
return {};
}
else
{
return namedObjects.Values()[index];
}
}
void GuiInstanceRootObject::SetNamedObject(const WString& name, const reflection::description::Value& namedObject)
{
namedObjects.Set(name, namedObject);
}
}
}
}
/***********************************************************************
.\APPLICATION\CONTROLS\GUILABELCONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace elements;
using namespace compositions;
using namespace collections;
using namespace reflection::description;
/***********************************************************************
GuiLabel
***********************************************************************/
void GuiLabel::BeforeControlTemplateUninstalled_()
{
auto ct = TypedControlTemplateObject(false);
if (!ct) return;
textColorConsisted = (textColor == ct->GetDefaultTextColor());
}
void GuiLabel::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
if (initialize || textColorConsisted)
{
SetTextColor(ct->GetDefaultTextColor());
}
else
{
ct->SetTextColor(textColor);
}
}
GuiLabel::GuiLabel(theme::ThemeName themeName)
:GuiControl(themeName)
{
}
GuiLabel::~GuiLabel()
{
}
Color GuiLabel::GetTextColor()
{
return textColor;
}
void GuiLabel::SetTextColor(Color value)
{
if (textColor != value)
{
textColor = value;
TypedControlTemplateObject(true)->SetTextColor(textColor);
}
}
}
}
}
/***********************************************************************
.\APPLICATION\CONTROLS\GUITHEMEMANAGER.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace templates
{
/***********************************************************************
GuiTemplate
***********************************************************************/
GuiTemplate_PROPERTIES(GUI_TEMPLATE_PROPERTY_IMPL)
controls::GuiControlHost* GuiTemplate::GetControlHostForInstance()
{
return GetRelatedControlHost();
}
void GuiTemplate::OnParentLineChanged()
{
GuiBoundsComposition::OnParentLineChanged();
OnControlHostForInstanceChanged();
}
GuiTemplate::GuiTemplate()
{
GuiTemplate_PROPERTIES(GUI_TEMPLATE_PROPERTY_EVENT_INIT)
}
GuiTemplate::~GuiTemplate()
{
FinalizeInstanceRecursively(this);
}
/***********************************************************************
Template Declarations
***********************************************************************/
GUI_CORE_CONTROL_TEMPLATE_DECL(GUI_TEMPLATE_CLASS_IMPL)
}
}
}
/***********************************************************************
.\APPLICATION\CONTROLS\GUIWINDOWCONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace elements;
using namespace compositions;
using namespace collections;
using namespace reflection::description;
/***********************************************************************
GuiControlHost
***********************************************************************/
void GuiControlHost::DeleteThis()
{
auto callback = callbackAfterDeleteThis;
delete this;
if (callback)
{
callback();
}
}
void GuiControlHost::OnNativeWindowChanged()
{
}
void GuiControlHost::OnVisualStatusChanged()
{
}
controls::GuiControlHost* GuiControlHost::GetControlHostForInstance()
{
return this;
}
GuiControl* GuiControlHost::GetTooltipOwner(Point location)
{
GuiGraphicsComposition* composition=this->GetBoundsComposition()->FindVisibleComposition(location, true);
if(composition)
{
GuiControl* control=composition->GetRelatedControl();
while(control)
{
if(control->GetTooltipControl())
{
return control;
}
control=control->GetParent();
}
}
return nullptr;
}
void GuiControlHost::MoveIntoTooltipControl(GuiControl* tooltipControl, Point location)
{
if (tooltipLocation != location)
{
tooltipLocation = location;
{
GuiControl* currentOwner = GetApplication()->GetTooltipOwner();
if (currentOwner && currentOwner != tooltipControl)
{
if (tooltipCloseDelay)
{
tooltipCloseDelay->Cancel();
tooltipCloseDelay = 0;
}
GetApplication()->DelayExecuteInMainThread([=]()
{
currentOwner->CloseTooltip();
}, TooltipDelayCloseTime);
}
}
if (!tooltipControl)
{
if (tooltipOpenDelay)
{
tooltipOpenDelay->Cancel();
tooltipOpenDelay = 0;
}
}
else if (tooltipOpenDelay)
{
tooltipOpenDelay->Delay(TooltipDelayOpenTime);
}
else if (GetApplication()->GetTooltipOwner() != tooltipControl)
{
tooltipOpenDelay = GetApplication()->DelayExecuteInMainThread([this]()
{
GuiControl* owner = GetTooltipOwner(tooltipLocation);
if (owner)
{
Point offset = owner->GetBoundsComposition()->GetGlobalBounds().LeftTop();
Point p(tooltipLocation.x - offset.x, tooltipLocation.y - offset.y + 24);
owner->DisplayTooltip(p);
tooltipOpenDelay = 0;
tooltipCloseDelay = GetApplication()->DelayExecuteInMainThread([this, owner]()
{
owner->CloseTooltip();
}, TooltipDelayLifeTime);
}
}, TooltipDelayOpenTime);
}
}
}
void GuiControlHost::MouseMoving(const NativeWindowMouseInfo& info)
{
if (!info.left && !info.middle && !info.right)
{
GuiControl* tooltipControl = GetTooltipOwner(tooltipLocation);
MoveIntoTooltipControl(tooltipControl, Point(host->GetNativeWindow()->Convert(NativePoint(info.x, info.y))));
}
}
void GuiControlHost::MouseLeaved()
{
MoveIntoTooltipControl(0, Point(-1, -1));
}
void GuiControlHost::Moved()
{
OnVisualStatusChanged();
}
void GuiControlHost::Enabled()
{
GuiControl::SetEnabled(true);
OnVisualStatusChanged();
}
void GuiControlHost::Disabled()
{
GuiControl::SetEnabled(false);
OnVisualStatusChanged();
}
void GuiControlHost::GotFocus()
{
WindowGotFocus.Execute(GetNotifyEventArguments());
OnVisualStatusChanged();
}
void GuiControlHost::LostFocus()
{
WindowLostFocus.Execute(GetNotifyEventArguments());
OnVisualStatusChanged();
}
void GuiControlHost::RenderingAsActivated()
{
WindowActivated.Execute(GetNotifyEventArguments());
OnVisualStatusChanged();
}
void GuiControlHost::RenderingAsDeactivated()
{
WindowDeactivated.Execute(GetNotifyEventArguments());
OnVisualStatusChanged();
}
void GuiControlHost::Opened()
{
WindowOpened.Execute(GetNotifyEventArguments());
}
void GuiControlHost::BeforeClosing(bool& cancel)
{
GuiRequestEventArgs arguments(boundsComposition);
arguments.cancel=cancel;
WindowClosing.Execute(arguments);
if(!arguments.handled)
{
cancel=arguments.cancel;
}
}
void GuiControlHost::AfterClosing()
{
WindowReadyToClose.Execute(GetNotifyEventArguments());
}
void GuiControlHost::Closed()
{
WindowClosed.Execute(GetNotifyEventArguments());
}
void GuiControlHost::Destroying()
{
WindowDestroying.Execute(GetNotifyEventArguments());
calledDestroyed = true;
if (deleteWhenDestroyed)
{
GetApplication()->InvokeInMainThread(this, [=]()
{
DeleteThis();
});
}
SetNativeWindow(nullptr);
}
void GuiControlHost::UpdateClientSize(Size value, bool updateNativeWindowOnly)
{
if (auto window = host->GetNativeWindow())
{
host->GetNativeWindow()->SetClientSize(window->Convert(value));
if (!updateNativeWindowOnly)
{
host->RequestUpdateSizeFromNativeWindow();
}
}
}
void GuiControlHost::UpdateClientSizeAfterRendering(Size preferredSize, Size clientSize)
{
auto size = GetClientSize();
if (size != clientSize)
{
UpdateClientSize(clientSize, true);
}
}
GuiControlHost::GuiControlHost(theme::ThemeName themeName, INativeWindow::WindowMode mode)
:GuiControl(themeName)
, windowMode(mode)
{
boundsComposition->SetAlignmentToParent(Margin(0, 0, 0, 0));
WindowGotFocus.SetAssociatedComposition(boundsComposition);
WindowLostFocus.SetAssociatedComposition(boundsComposition);
WindowActivated.SetAssociatedComposition(boundsComposition);
WindowDeactivated.SetAssociatedComposition(boundsComposition);
WindowOpened.SetAssociatedComposition(boundsComposition);
WindowClosing.SetAssociatedComposition(boundsComposition);
WindowReadyToClose.SetAssociatedComposition(boundsComposition);
WindowClosed.SetAssociatedComposition(boundsComposition);
WindowDestroying.SetAssociatedComposition(boundsComposition);
host=new GuiGraphicsHost(this, boundsComposition);
sharedPtrDestructorProc = 0;
}
GuiControlHost::~GuiControlHost()
{
FinalizeInstanceRecursively(this);
OnBeforeReleaseGraphicsHost();
delete host;
}
void GuiControlHost::DeleteAfterProcessingAllEvents(const Func<void()>& callback)
{
CHECK_ERROR(!deleteWhenDestroyed, L"vl::presentation::controls::GuiControlHost::DeleteAfterProcessingAllEvents()#This function cannot be called twice.");
deleteWhenDestroyed = true;
callbackAfterDeleteThis = callback;
auto window = host->GetNativeWindow();
if (calledDestroyed || !window)
{
DeleteThis();
}
else
{
GetApplication()->InvokeInMainThread(this, [window]()
{
GetCurrentController()->WindowService()->DestroyNativeWindow(window);
});
}
}
compositions::GuiGraphicsHost* GuiControlHost::GetGraphicsHost()
{
return host;
}
compositions::GuiGraphicsComposition* GuiControlHost::GetMainComposition()
{
return host->GetMainComposition();
}
INativeWindow* GuiControlHost::GetNativeWindow()
{
return host->GetNativeWindow();
}
void GuiControlHost::SetNativeWindow(INativeWindow* window)
{
auto previousNativeWindow = host->GetNativeWindow();
if(previousNativeWindow)
{
host->GetNativeWindow()->UninstallListener(this);
}
if (window)
{
if (windowMode != window->GetWindowMode())
{
CHECK_FAIL(L"GuiControlHost::SetNativeWindow(INativeWindow*)#Window mode does not match.");
}
}
host->SetNativeWindow(window);
if(host->GetNativeWindow())
{
host->GetNativeWindow()->InstallListener(this);
}
GetApplication()->NotifyNativeWindowChanged(this, previousNativeWindow);
OnNativeWindowChanged();
}
void GuiControlHost::ForceCalculateSizeImmediately()
{
auto size = GetClientSize();
boundsComposition->ForceCalculateSizeImmediately();
SetClientSize(size);
}
bool GuiControlHost::GetEnabled()
{
if(host->GetNativeWindow())
{
return host->GetNativeWindow()->IsEnabled();
}
else
{
return false;
}
}
void GuiControlHost::SetEnabled(bool value)
{
if(host->GetNativeWindow())
{
if(value)
{
host->GetNativeWindow()->Enable();
}
else
{
host->GetNativeWindow()->Disable();
}
}
}
bool GuiControlHost::GetFocused()
{
if(host->GetNativeWindow())
{
return host->GetNativeWindow()->IsActivated();
}
else
{
return false;
}
}
void GuiControlHost::SetFocused()
{
if(host->GetNativeWindow())
{
host->GetNativeWindow()->SetActivate();
}
}
bool GuiControlHost::GetRenderingAsActivated()
{
if(host->GetNativeWindow())
{
return host->GetNativeWindow()->IsRenderingAsActivated();
}
else
{
return false;
}
}
bool GuiControlHost::GetShowInTaskBar()
{
if(host->GetNativeWindow())
{
return host->GetNativeWindow()->IsAppearedInTaskBar();
}
else
{
return false;
}
}
void GuiControlHost::SetShowInTaskBar(bool value)
{
if(host->GetNativeWindow())
{
if(value)
{
host->GetNativeWindow()->ShowInTaskBar();
}
else
{
host->GetNativeWindow()->HideInTaskBar();
}
}
}
bool GuiControlHost::GetEnabledActivate()
{
if(host->GetNativeWindow())
{
return host->GetNativeWindow()->IsEnabledActivate();
}
else
{
return false;
}
}
void GuiControlHost::SetEnabledActivate(bool value)
{
if(host->GetNativeWindow())
{
if(value)
{
host->GetNativeWindow()->EnableActivate();
}
else
{
host->GetNativeWindow()->DisableActivate();
}
}
}
bool GuiControlHost::GetTopMost()
{
if(host->GetNativeWindow())
{
return host->GetNativeWindow()->GetTopMost();
}
else
{
return false;
}
}
void GuiControlHost::SetTopMost(bool topmost)
{
if(host->GetNativeWindow())
{
host->GetNativeWindow()->SetTopMost(topmost);
}
}
compositions::IGuiShortcutKeyManager* GuiControlHost::GetShortcutKeyManager()
{
return host->GetShortcutKeyManager();
}
void GuiControlHost::SetShortcutKeyManager(compositions::IGuiShortcutKeyManager* value)
{
host->SetShortcutKeyManager(value);
}
compositions::GuiGraphicsTimerManager* GuiControlHost::GetTimerManager()
{
return host->GetTimerManager();
}
Size GuiControlHost::GetClientSize()
{
if (auto window = host->GetNativeWindow())
{
return window->Convert(window->GetClientSize());
}
else
{
return Size(0, 0);
}
}
void GuiControlHost::SetClientSize(Size value)
{
UpdateClientSize(value, false);
}
NativePoint GuiControlHost::GetLocation()
{
if(auto window = host->GetNativeWindow())
{
return window->GetBounds().LeftTop();
}
else
{
return NativePoint();
}
}
void GuiControlHost::SetLocation(NativePoint value)
{
if (auto window = host->GetNativeWindow())
{
auto bounds = window->GetBounds();
window->SetBounds(NativeRect(value, bounds.GetSize()));
}
}
void GuiControlHost::SetBounds(NativePoint location, Size size)
{
if (auto window = host->GetNativeWindow())
{
window->SetBounds(NativeRect(location, window->Convert(size)));
}
}
GuiControlHost* GuiControlHost::GetRelatedControlHost()
{
return this;
}
const WString& GuiControlHost::GetText()
{
WString result;
if(host->GetNativeWindow())
{
result=host->GetNativeWindow()->GetTitle();
}
if(result!=GuiControl::GetText())
{
GuiControl::SetText(result);
}
return GuiControl::GetText();
}
void GuiControlHost::SetText(const WString& value)
{
if(host->GetNativeWindow())
{
host->GetNativeWindow()->SetTitle(value);
GuiControl::SetText(value);
}
}
INativeScreen* GuiControlHost::GetRelatedScreen()
{
if(host->GetNativeWindow())
{
return GetCurrentController()->ScreenService()->GetScreen(host->GetNativeWindow());
}
else
{
return 0;
}
}
void GuiControlHost::Show()
{
if(host->GetNativeWindow())
{
host->GetNativeWindow()->Show();
}
}
void GuiControlHost::ShowDeactivated()
{
if(host->GetNativeWindow())
{
host->GetNativeWindow()->ShowDeactivated();
}
}
void GuiControlHost::ShowRestored()
{
if(host->GetNativeWindow())
{
host->GetNativeWindow()->ShowRestored();
}
}
void GuiControlHost::ShowMaximized()
{
if(host->GetNativeWindow())
{
host->GetNativeWindow()->ShowMaximized();
}
}
void GuiControlHost::ShowMinimized()
{
if(host->GetNativeWindow())
{
host->GetNativeWindow()->ShowMinimized();
}
}
void GuiControlHost::Hide()
{
if (auto window = host->GetNativeWindow())
{
window->Hide(false);
}
}
void GuiControlHost::Close()
{
if (auto window = host->GetNativeWindow())
{
window->Hide(true);
// auto mainWindow = GetCurrentController()->WindowService()->GetMainWindow();
// if (mainWindow == window)
// {
// SetNativeWindow(nullptr);
// GetCurrentController()->WindowService()->DestroyNativeWindow(window);
// }
// else
// {
// window->Hide(true);
// }
}
}
bool GuiControlHost::GetOpening()
{
INativeWindow* window=host->GetNativeWindow();
if(window)
{
return window->IsVisible();
}
return false;
}
/***********************************************************************
GuiWindow
***********************************************************************/
void GuiWindow::BeforeControlTemplateUninstalled_()
{
}
void GuiWindow::AfterControlTemplateInstalled_(bool initialize)
{
ApplyFrameConfig();
auto ct = TypedControlTemplateObject(true);
auto window = GetNativeWindow();
SetControlTemplateProperties();
UpdateIcon(window, ct);
UpdateCustomFramePadding(window, ct);
if (window)
{
window->SetIcon(icon);
}
SetNativeWindowFrameProperties();
}
void GuiWindow::UpdateIcon(INativeWindow* window, templates::GuiWindowTemplate* ct)
{
ct->SetIcon(icon ? icon : window ? window->GetIcon() : nullptr);
}
void GuiWindow::UpdateCustomFramePadding(INativeWindow* window, templates::GuiWindowTemplate* ct)
{
if (window)
{
ct->SetCustomFramePadding(window->Convert(window->GetCustomFramePadding()));
}
else
{
ct->SetCustomFramePadding({8, 8, 8, 8});
}
}
bool GuiWindow::IsRenderedAsMaximized()
{
auto nativeWindow = GetNativeWindow();
if (nativeWindow && GetApplication()->GetMainWindow() == this)
{
if (auto hostedApp = GetHostedApplication())
{
nativeWindow = hostedApp->GetNativeWindowHost();
}
}
return nativeWindow ? nativeWindow->GetSizeState() == INativeWindow::Maximized : false;
}
void GuiWindow::SetControlTemplateProperties()
{
if (auto ct = TypedControlTemplateObject(false))
{
ct->SetMaximizedBox(hasMaximizedBox);
ct->SetMinimizedBox(hasMinimizedBox);
ct->SetBorder(hasBorder);
ct->SetSizeBox(hasSizeBox);
ct->SetIconVisible(isIconVisible);
ct->SetTitleBar(hasTitleBar);
ct->SetMaximized(IsRenderedAsMaximized());
ct->SetActivated(GetRenderingAsActivated());
}
}
void GuiWindow::SetNativeWindowFrameProperties()
{
if (auto window = GetNativeWindow())
{
if (TypedControlTemplateObject(true)->GetCustomFrameEnabled())
{
window->EnableCustomFrameMode();
window->SetBorder(false);
}
else
{
window->DisableCustomFrameMode();
window->SetBorder(hasBorder);
}
window->SetMaximizedBox(hasMaximizedBox);
window->SetMinimizedBox(hasMinimizedBox);
window->SetSizeBox(hasSizeBox);
window->SetIconVisible(isIconVisible);
window->SetTitleBar(hasTitleBar);
}
}
bool GuiWindow::ApplyFrameConfigOnVariable(BoolOption frameConfig, BoolOption templateConfig, bool& variable)
{
if (frameConfig == BoolOption::AlwaysTrue && templateConfig == BoolOption::AlwaysFalse)return false;
if (frameConfig == BoolOption::AlwaysFalse && templateConfig == BoolOption::AlwaysTrue) return false;
if (frameConfig == BoolOption::AlwaysTrue || templateConfig == BoolOption::AlwaysTrue)
{
variable = true;
}
else if (frameConfig == BoolOption::AlwaysFalse || templateConfig == BoolOption::AlwaysFalse)
{
variable = false;
}
return true;
}
void GuiWindow::ApplyFrameConfig()
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::controls::GuiWindow::CheckCustomFrameAndControlTemplateCompatibility#"
#define FIX_WINDOW_PROPERTY(VARIABLE, NAME)\
CHECK_ERROR(\
ApplyFrameConfigOnVariable(\
(frameConfig ? frameConfig->NAME ## Option : BoolOption::Customizable),\
(ct ? ct->Get ## NAME ## Option() : BoolOption::Customizable),\
VARIABLE\
),\
ERROR_MESSAGE_PREFIX L"Frame configuration and control template are not compatible on property \"" L ## #NAME L"\"."\
);\
auto ct = TypedControlTemplateObject(false);
if (frameConfig && ct)
{
if (
(frameConfig->CustomFrameEnabled == BoolOption::AlwaysTrue && !ct->GetCustomFrameEnabled()) ||
(frameConfig->CustomFrameEnabled == BoolOption::AlwaysFalse && ct->GetCustomFrameEnabled())
)
{
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Frame configuration and control template are not compatible on property \"CustomFrameEnabled\".");
}
}
FIX_WINDOW_PROPERTY(hasMaximizedBox, MaximizedBox)
FIX_WINDOW_PROPERTY(hasMinimizedBox, MinimizedBox)
FIX_WINDOW_PROPERTY(hasBorder, Border)
FIX_WINDOW_PROPERTY(hasSizeBox, SizeBox)
FIX_WINDOW_PROPERTY(isIconVisible, IconVisible)
FIX_WINDOW_PROPERTY(hasTitleBar, TitleBar)
auto window = GetNativeWindow();
SetControlTemplateProperties();
UpdateCustomFramePadding(window, ct);
SetNativeWindowFrameProperties();
#undef FIX_WINDOW_PROPERTY
#undef ERROR_MESSAGE_PREFIX
}
void GuiWindow::Moved()
{
GuiControlHost::Moved();
TypedControlTemplateObject(true)->SetMaximized(IsRenderedAsMaximized());
}
void GuiWindow::DpiChanged(bool preparing)
{
if (!preparing)
{
if (auto ct = TypedControlTemplateObject(false))
{
UpdateCustomFramePadding(GetNativeWindow(), ct);
}
}
}
void GuiWindow::Opened()
{
GuiControlHost::Opened();
if (auto ct = TypedControlTemplateObject(false))
{
UpdateIcon(GetNativeWindow(), ct);
}
}
void GuiWindow::BeforeClosing(bool& cancel)
{
if (GetHostedApplication() && this == GetApplication()->GetMainWindow())
{
GuiWindow* pickedWindow = nullptr;
if (showModalRecord)
{
pickedWindow = showModalRecord->current;
}
else
{
for (auto window : From(GetApplication()->GetWindows()))
{
if (window->GetVisible() && window->showModalRecord)
{
pickedWindow = window->showModalRecord->current;
break;
}
}
}
if (pickedWindow && pickedWindow != this)
{
if (pickedWindow->GetFocused())
{
pickedWindow->Hide();
}
else
{
pickedWindow->SetFocused();
}
cancel = true;
return;
}
}
GuiControlHost::BeforeClosing(cancel);
}
void GuiWindow::AssignFrameConfig(const NativeWindowFrameConfig& config)
{
frameConfig = &config;
FrameConfigChanged.Execute(GetNotifyEventArguments());
ApplyFrameConfig();
}
void GuiWindow::OnNativeWindowChanged()
{
SetNativeWindowFrameProperties();
GuiControlHost::OnNativeWindowChanged();
}
void GuiWindow::OnVisualStatusChanged()
{
GuiControlHost::OnVisualStatusChanged();
}
void GuiWindow::OnWindowActivated(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (auto ct = TypedControlTemplateObject(false))
{
ct->SetActivated(true);
}
}
void GuiWindow::OnWindowDeactivated(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (auto ct = TypedControlTemplateObject(false))
{
ct->SetActivated(false);
}
}
GuiWindow::GuiWindow(theme::ThemeName themeName, INativeWindow::WindowMode mode)
:GuiControlHost(themeName, mode)
{
SetAltComposition(boundsComposition);
SetAltControl(this, true);
INativeWindow* window = GetCurrentController()->WindowService()->CreateNativeWindow(windowMode);
SetNativeWindow(window);
GetApplication()->RegisterWindow(this);
ClipboardUpdated.SetAssociatedComposition(boundsComposition);
FrameConfigChanged.SetAssociatedComposition(boundsComposition);
WindowActivated.AttachMethod(this, &GuiWindow::OnWindowActivated);
WindowDeactivated.AttachMethod(this, &GuiWindow::OnWindowDeactivated);
}
GuiWindow::GuiWindow(theme::ThemeName themeName)
:GuiWindow(themeName, INativeWindow::Normal)
{
}
GuiWindow::~GuiWindow()
{
FinalizeAggregation();
GetApplication()->UnregisterWindow(this);
INativeWindow* window=host->GetNativeWindow();
if(window)
{
SetNativeWindow(nullptr);
GetCurrentController()->WindowService()->DestroyNativeWindow(window);
}
}
IDescriptable* GuiWindow::QueryService(const WString& identifier)
{
if (identifier == IGuiAltActionHost::Identifier)
{
return (IGuiAltActionHost*)this;
}
else
{
return GuiControlHost::QueryService(identifier);
}
}
void GuiWindow::MoveToScreenCenter()
{
MoveToScreenCenter(GetRelatedScreen());
}
void GuiWindow::MoveToScreenCenter(INativeScreen* screen)
{
if (screen)
{
if (auto window = host->GetNativeWindow())
{
NativeRect screenBounds = screen->GetClientBounds();
NativeSize windowSize = window->GetBounds().GetSize();
SetLocation(
NativePoint(
screenBounds.Left() + (screenBounds.Width() - windowSize.x) / 2,
screenBounds.Top() + (screenBounds.Height() - windowSize.y) / 2
)
);
}
}
}
const NativeWindowFrameConfig& GuiWindow::GetFrameConfig()
{
return frameConfig ? *frameConfig : NativeWindowFrameConfig::Default;
}
#define IMPL_WINDOW_PROPERTY(VARIABLE, NAME, CONDITION_BREAK) \
bool GuiWindow::Get ## NAME() \
{ \
return VARIABLE; \
} \
void GuiWindow::Set ## NAME(bool visible) \
{ \
auto ct = TypedControlTemplateObject(true); \
if (ct->Get ## NAME ## Option() == BoolOption::Customizable) \
{ \
VARIABLE = visible; \
ct->Set ## NAME(visible); \
auto window = GetNativeWindow(); \
if (window) \
{ \
CONDITION_BREAK \
window->Set ## NAME(visible); \
} \
UpdateCustomFramePadding(window, ct); \
} \
} \
#define IMPL_WINDOW_PROPERTY_EMPTY_CONDITION
#define IMPL_WINDOW_PROPERTY_BORDER_CONDITION if (!ct->GetCustomFrameEnabled())
IMPL_WINDOW_PROPERTY(hasMaximizedBox, MaximizedBox, IMPL_WINDOW_PROPERTY_EMPTY_CONDITION)
IMPL_WINDOW_PROPERTY(hasMinimizedBox, MinimizedBox, IMPL_WINDOW_PROPERTY_EMPTY_CONDITION)
IMPL_WINDOW_PROPERTY(hasBorder, Border, IMPL_WINDOW_PROPERTY_BORDER_CONDITION)
IMPL_WINDOW_PROPERTY(hasSizeBox, SizeBox, IMPL_WINDOW_PROPERTY_EMPTY_CONDITION)
IMPL_WINDOW_PROPERTY(isIconVisible, IconVisible, IMPL_WINDOW_PROPERTY_EMPTY_CONDITION)
IMPL_WINDOW_PROPERTY(hasTitleBar, TitleBar, IMPL_WINDOW_PROPERTY_EMPTY_CONDITION)
Ptr<GuiImageData> GuiWindow::GetIcon()
{
return icon;
}
void GuiWindow::SetIcon(Ptr<GuiImageData> value)
{
if (icon != value)
{
icon = value;
auto window = GetNativeWindow();
if (window)
{
window->SetIcon(icon);
}
if (auto ct = TypedControlTemplateObject(false))
{
UpdateIcon(window, ct);
}
}
}
#undef IMPL_WINDOW_PROPERTY_BORDER_CONDITION
#undef IMPL_WINDOW_PROPERTY_EMPTY_CONDITION
#undef IMPL_WINDOW_PROPERTY
void GuiWindow::ShowWithOwner(GuiWindow* owner)
{
auto ownerNativeWindow = owner->GetNativeWindow();
auto nativeWindow = GetNativeWindow();
auto previousParent = nativeWindow->GetParent();
if (ownerNativeWindow != previousParent)
{
nativeWindow->SetParent(ownerNativeWindow);
WindowReadyToClose.AttachLambda([=](GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
nativeWindow->SetParent(previousParent);
});
}
Show();
}
void GuiWindow::ShowModal(GuiWindow* owner, const Func<void()>& callback)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::controls::GuiWindow::ShowModal(GuiWindow*, const Func<void()>&)#"
CHECK_ERROR(!showModalRecord, ERROR_MESSAGE_PREFIX L"Cannot call this function nestedly.");
CHECK_ERROR(owner && owner->GetEnabled(), ERROR_MESSAGE_PREFIX L"The owner should not have been disabled.");
if (!owner->showModalRecord)
{
owner->showModalRecord = Ptr(new ShowModalRecord{ owner,owner });
}
showModalRecord = owner->showModalRecord;
showModalRecord->current = this;
owner->SetEnabled(false);
GetNativeWindow()->SetParent(owner->GetNativeWindow());
auto container = Ptr(new IGuiGraphicsEventHandler::Container);
auto disposeFlag = GetDisposedFlag();
container->handler = WindowReadyToClose.AttachLambda([=](GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
callback();
GetNativeWindow()->SetParent(nullptr);
owner->SetEnabled(true);
owner->SetFocused();
showModalRecord = nullptr;
owner->showModalRecord->current = owner;
if (owner->showModalRecord->current == owner->showModalRecord->origin)
{
owner->showModalRecord = nullptr;
}
GetApplication()->InvokeInMainThread(this, [=]()
{
if (!disposeFlag->IsDisposed())
{
WindowReadyToClose.Detach(container->handler);
}
container->handler = nullptr;
});
});
Show();
#undef ERROR_MESSAGE_PREFIX
}
void GuiWindow::ShowModalAndDelete(GuiWindow* owner, const Func<void()>& callback)
{
ShowModal(owner, [=]()
{
callback();
DeleteAfterProcessingAllEvents({});
});
}
void GuiWindow::ShowModalAndDelete(GuiWindow* owner, const Func<void()>& callbackClosed, const Func<void()>& callbackDeleted)
{
ShowModal(owner, [=]()
{
callbackClosed();
DeleteAfterProcessingAllEvents(callbackDeleted);
});
}
Ptr<reflection::description::IAsync> GuiWindow::ShowModalAsync(GuiWindow* owner)
{
auto future = IFuture::Create();
ShowModal(owner, [promise = future->GetPromise()]()
{
promise->SendResult({});
});
return future;
}
/***********************************************************************
GuiPopup
***********************************************************************/
void GuiPopup::UpdateClientSizeAfterRendering(Size preferredSize, Size clientSize)
{
if (popupType == -1)
{
GuiWindow::UpdateClientSizeAfterRendering(preferredSize, clientSize);
}
else
{
auto window = host->GetNativeWindow();
auto currentClientSize = window->GetClientSize();
auto currentWindowSize = window->GetBounds().GetSize();
auto offsetX = currentWindowSize.x - currentClientSize.x;
auto offsetY = currentWindowSize.y - currentClientSize.y;
auto nativeClientSize = window->Convert(clientSize);
auto position = CalculatePopupPosition(NativeSize(nativeClientSize.x + offsetX, nativeClientSize.y + offsetY), popupType, popupInfo);
if (position != GetLocation() || clientSize != GetClientSize())
{
SetBounds(position, clientSize);
}
}
}
void GuiPopup::PopupOpened(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
GetApplication()->RegisterPopupOpened(this);
}
void GuiPopup::PopupClosed(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
popupType = -1;
GetApplication()->RegisterPopupClosed(this);
if(auto window = GetNativeWindow())
{
window->SetParent(nullptr);
}
}
void GuiPopup::OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments)
{
if (!arguments.handled)
{
Hide();
}
}
bool GuiPopup::IsClippedByScreen(NativeSize size, NativePoint location, INativeScreen* screen)
{
NativeRect screenBounds = screen->GetClientBounds();
NativeRect windowBounds(location, size);
return !screenBounds.Contains(windowBounds.LeftTop()) || !screenBounds.Contains(windowBounds.RightBottom());
}
NativePoint GuiPopup::CalculatePopupPosition(NativeSize windowSize, NativePoint location, INativeScreen* screen)
{
NativeRect screenBounds = screen->GetClientBounds();
if (location.x < screenBounds.x1)
{
location.x = screenBounds.x1;
}
else if (location.x + windowSize.x > screenBounds.x2)
{
location.x = screenBounds.x2 - windowSize.x;
}
if (location.y < screenBounds.y1)
{
location.y = screenBounds.y1;
}
else if (location.y + windowSize.y > screenBounds.y2)
{
location.y = screenBounds.y2 - windowSize.y;
}
return location;
}
NativePoint GuiPopup::CalculatePopupPosition(NativeSize windowSize, GuiControl* control, INativeWindow* controlWindow, Rect bounds, bool preferredTopBottomSide)
{
NativePoint controlClientOffset = controlWindow->Convert(control->GetBoundsComposition()->GetGlobalBounds().LeftTop());
NativePoint controlWindowOffset = controlWindow->GetClientBoundsInScreen().LeftTop();
NativeRect targetBounds(controlWindow->Convert(bounds.LeftTop()), controlWindow->Convert(bounds.GetSize()));
targetBounds.x1 += controlClientOffset.x + controlWindowOffset.x;
targetBounds.x2 += controlClientOffset.x + controlWindowOffset.x;
targetBounds.y1 += controlClientOffset.y + controlWindowOffset.y;
targetBounds.y2 += controlClientOffset.y + controlWindowOffset.y;
NativePoint locations[4];
if (preferredTopBottomSide)
{
locations[0] = NativePoint(targetBounds.x1, targetBounds.y2);
locations[1] = NativePoint(targetBounds.x2 - windowSize.x, targetBounds.y2);
locations[2] = NativePoint(targetBounds.x1, targetBounds.y1 - windowSize.y);
locations[3] = NativePoint(targetBounds.x2 - windowSize.x, targetBounds.y1 - windowSize.y);
}
else
{
locations[0] = NativePoint(targetBounds.x2, targetBounds.y1);
locations[1] = NativePoint(targetBounds.x2, targetBounds.y2 - windowSize.y);
locations[2] = NativePoint(targetBounds.x1 - windowSize.x, targetBounds.y1);
locations[3] = NativePoint(targetBounds.x1 - windowSize.x, targetBounds.y2 - windowSize.y);
}
auto screen = GetCurrentController()->ScreenService()->GetScreen(controlWindow);
for (vint i = 0; i < 4; i++)
{
if (!IsClippedByScreen(windowSize, locations[i], screen))
{
return CalculatePopupPosition(windowSize, locations[i], screen);
}
}
return CalculatePopupPosition(windowSize, locations[0], screen);
}
NativePoint GuiPopup::CalculatePopupPosition(NativeSize windowSize, GuiControl* control, INativeWindow* controlWindow, Point location)
{
NativePoint controlClientOffset = controlWindow->Convert(control->GetBoundsComposition()->GetGlobalBounds().LeftTop());
NativePoint controlWindowOffset = controlWindow->GetClientBoundsInScreen().LeftTop();
NativePoint targetLocation = controlWindow->Convert(location);
NativeCoordinate x = controlClientOffset.x + controlWindowOffset.x + targetLocation.x;
NativeCoordinate y = controlClientOffset.y + controlWindowOffset.y + targetLocation.y;
return CalculatePopupPosition(windowSize, NativePoint(x, y), GetCurrentController()->ScreenService()->GetScreen(controlWindow));
}
NativePoint GuiPopup::CalculatePopupPosition(NativeSize windowSize, GuiControl* control, INativeWindow* controlWindow, bool preferredTopBottomSide)
{
Rect bounds(Point(0, 0), control->GetBoundsComposition()->GetCachedBounds().GetSize());
return CalculatePopupPosition(windowSize, control, controlWindow, bounds, preferredTopBottomSide);
}
NativePoint GuiPopup::CalculatePopupPosition(NativeSize windowSize, vint popupType, const PopupInfo& popupInfo)
{
switch (popupType)
{
case 1:
return CalculatePopupPosition(windowSize, popupInfo._1.location, popupInfo._1.screen);
case 2:
return CalculatePopupPosition(windowSize, popupInfo._2.control, popupInfo._2.controlWindow, popupInfo._2.bounds, popupInfo._2.preferredTopBottomSide);
case 3:
return CalculatePopupPosition(windowSize, popupInfo._3.control, popupInfo._3.controlWindow, popupInfo._3.location);
case 4:
return CalculatePopupPosition(windowSize, popupInfo._4.control, popupInfo._4.controlWindow, popupInfo._4.preferredTopBottomSide);
default:
CHECK_FAIL(L"vl::presentation::controls::GuiPopup::CalculatePopupPosition(Size, const PopupInfo&)#Internal error.");
}
}
void GuiPopup::ShowPopupInternal()
{
auto window = GetNativeWindow();
auto clientSize = window->Convert(window->GetClientSize());
UpdateClientSizeAfterRendering(clientSize, clientSize);
INativeWindow* controlWindow = nullptr;
switch (popupType)
{
case 2: controlWindow = popupInfo._2.controlWindow; break;
case 3: controlWindow = popupInfo._3.controlWindow; break;
case 4: controlWindow = popupInfo._4.controlWindow; break;
}
if (controlWindow)
{
window->SetParent(controlWindow);
SetTopMost(controlWindow->GetTopMost());
}
else
{
SetTopMost(true);
}
SetEnabledActivate(false);
ShowDeactivated();
}
GuiPopup::GuiPopup(theme::ThemeName themeName, INativeWindow::WindowMode mode)
:GuiWindow(themeName, mode)
{
SetMinimizedBox(false);
SetMaximizedBox(false);
SetBorder(false);
SetSizeBox(false);
SetIconVisible(false);
SetTitleBar(false);
SetShowInTaskBar(false);
WindowOpened.AttachMethod(this, &GuiPopup::PopupOpened);
WindowClosed.AttachMethod(this, &GuiPopup::PopupClosed);
boundsComposition->GetEventReceiver()->keyDown.AttachMethod(this, &GuiPopup::OnKeyDown);
}
GuiPopup::GuiPopup(theme::ThemeName themeName)
:GuiPopup(themeName, INativeWindow::Popup)
{
}
GuiPopup::~GuiPopup()
{
GetApplication()->RegisterPopupClosed(this);
}
void GuiPopup::ShowPopup(NativePoint location, INativeScreen* screen)
{
if (auto window = GetNativeWindow())
{
if (!screen)
{
SetBounds(location, GetClientSize());
screen = GetCurrentController()->ScreenService()->GetScreen(window);
}
popupType = 1;
popupInfo._1.location = location;
popupInfo._1.screen = screen;
ShowPopupInternal();
}
}
void GuiPopup::ShowPopup(GuiControl* control, Rect bounds, bool preferredTopBottomSide)
{
if (auto window = GetNativeWindow())
{
if (auto controlHost = control->GetBoundsComposition()->GetRelatedControlHost())
{
if (auto controlWindow = controlHost->GetNativeWindow())
{
popupType = 2;
popupInfo._2.control = control;
popupInfo._2.controlWindow = controlWindow;
popupInfo._2.bounds = bounds;
popupInfo._2.preferredTopBottomSide = preferredTopBottomSide;
ShowPopupInternal();
}
}
}
}
void GuiPopup::ShowPopup(GuiControl* control, Point location)
{
if (auto window = GetNativeWindow())
{
if (auto controlHost = control->GetBoundsComposition()->GetRelatedControlHost())
{
if (auto controlWindow = controlHost->GetNativeWindow())
{
popupType = 3;
popupInfo._3.control = control;
popupInfo._3.controlWindow = controlWindow;
popupInfo._3.location = location;
ShowPopupInternal();
}
}
}
}
void GuiPopup::ShowPopup(GuiControl* control, bool preferredTopBottomSide)
{
if (auto window = GetNativeWindow())
{
if (auto controlHost = control->GetBoundsComposition()->GetRelatedControlHost())
{
if (auto controlWindow = controlHost->GetNativeWindow())
{
popupType = 4;
popupInfo._4.control = control;
popupInfo._4.controlWindow = controlWindow;
popupInfo._4.preferredTopBottomSide = preferredTopBottomSide;
ShowPopupInternal();
}
}
}
}
/***********************************************************************
GuiPopup
***********************************************************************/
void GuiTooltip::GlobalTimer()
{
SetClientSize(GetClientSize());
}
void GuiTooltip::TooltipOpened(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
}
void GuiTooltip::TooltipClosed(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
SetTemporaryContentControl(0);
}
GuiTooltip::GuiTooltip(theme::ThemeName themeName)
: GuiPopup(themeName, INativeWindow::Tooltip)
{
containerComposition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
containerComposition->SetPreferredMinSize(Size(20, 10));
GetCurrentController()->CallbackService()->InstallListener(this);
WindowOpened.AttachMethod(this, &GuiTooltip::TooltipOpened);
WindowClosed.AttachMethod(this, &GuiTooltip::TooltipClosed);
}
GuiTooltip::~GuiTooltip()
{
GetCurrentController()->CallbackService()->UninstallListener(this);
}
vint GuiTooltip::GetPreferredContentWidth()
{
return containerComposition->GetPreferredMinSize().x;
}
void GuiTooltip::SetPreferredContentWidth(vint value)
{
containerComposition->SetPreferredMinSize(Size(value, 10));
}
GuiControl* GuiTooltip::GetTemporaryContentControl()
{
return temporaryContentControl;
}
void GuiTooltip::SetTemporaryContentControl(GuiControl* control)
{
if(temporaryContentControl && HasChild(temporaryContentControl))
{
containerComposition->RemoveChild(temporaryContentControl->GetBoundsComposition());
temporaryContentControl=0;
}
temporaryContentControl=control;
if(control)
{
control->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
AddChild(control);
}
}
}
}
}
/***********************************************************************
.\APPLICATION\GRAPHICSCOMPOSITIONS\GUIGRAPHICSBOUNDSCOMPOSITION.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
using namespace collections;
using namespace elements;
/***********************************************************************
GuiBoundsComposition
***********************************************************************/
Size GuiBoundsComposition::Layout_CalculateMinSize()
{
Size minSize = Layout_CalculateMinSizeHelper();
if (minSize.x < expectedBounds.Width()) minSize.x = expectedBounds.Width();
if (minSize.y < expectedBounds.Height()) minSize.y = expectedBounds.Height();
return minSize;
}
Size GuiBoundsComposition::Layout_CalculateMinClientSizeForParent(Margin parentInternalMargin)
{
vint offsetW = 0;
vint offsetH = 0;
if (alignmentToParent.left == -1 && alignmentToParent.right == -1)
{
offsetW = expectedBounds.x1;
}
else
{
if (alignmentToParent.left != -1)
{
offsetW += alignmentToParent.left - parentInternalMargin.left;
}
if (alignmentToParent.right != -1)
{
offsetW += alignmentToParent.right - parentInternalMargin.right;
}
}
if (alignmentToParent.top == -1 && alignmentToParent.bottom == -1)
{
offsetH = expectedBounds.y1;
}
else
{
if (alignmentToParent.top != -1)
{
offsetH += alignmentToParent.top - parentInternalMargin.top;
}
if (alignmentToParent.bottom != -1)
{
offsetH += alignmentToParent.bottom - parentInternalMargin.bottom;
}
}
return { cachedMinSize.x + offsetW,cachedMinSize.y + offsetH };
}
Rect GuiBoundsComposition::Layout_CalculateBounds(Size parentSize)
{
if (auto parent = GetParent())
{
Rect result;
Rect parentBounds({}, parentSize);
Margin parentInternalMargin = parent->GetInternalMargin();
if (alignmentToParent.left != -1 && alignmentToParent.right != -1)
{
result.x1 = parentBounds.x1 + alignmentToParent.left;
result.x2 = parentBounds.x2 - alignmentToParent.right;
}
else if (alignmentToParent.left != -1)
{
result.x1 = parentBounds.x1 + alignmentToParent.left;
result.x2 = result.x1 + cachedMinSize.x;
}
else if (alignmentToParent.right != -1)
{
result.x2 = parentBounds.x2 - alignmentToParent.right;
result.x1 = result.x2 - cachedMinSize.x;
}
else
{
result.x1 = expectedBounds.x1 + parentInternalMargin.left;
result.x2 = result.x1 + cachedMinSize.x;
}
if (alignmentToParent.top != -1 && alignmentToParent.bottom != -1)
{
result.y1 = parentBounds.y1 + alignmentToParent.top;
result.y2 = parentBounds.y2 - alignmentToParent.bottom;
}
else if (alignmentToParent.top != -1)
{
result.y1 = parentBounds.y1 + alignmentToParent.top;
result.y2 = result.y1 + cachedMinSize.y;
}
else if (alignmentToParent.bottom != -1)
{
result.y2 = parentBounds.y2 - alignmentToParent.bottom;
result.y1 = result.y2 - cachedMinSize.y;
}
else
{
result.y1 = expectedBounds.y1 + parentInternalMargin.top;
result.y2 = result.y1 + cachedMinSize.y;
}
return result;
}
else
{
return Rect(expectedBounds.LeftTop(), cachedMinSize);
}
}
Rect GuiBoundsComposition::GetExpectedBounds()
{
return expectedBounds;
}
void GuiBoundsComposition::SetExpectedBounds(Rect value)
{
if (value.x2 < value.x1) value.x2 = value.x1;
if (value.y2 < value.y1) value.y2 = value.y1;
if (expectedBounds != value)
{
expectedBounds = value;
InvokeOnCompositionStateChanged();
}
}
Margin GuiBoundsComposition::GetAlignmentToParent()
{
return alignmentToParent;
}
void GuiBoundsComposition::SetAlignmentToParent(Margin value)
{
if (alignmentToParent != value)
{
alignmentToParent = value;
InvokeOnCompositionStateChanged();
}
}
bool GuiBoundsComposition::IsAlignedToParent()
{
return alignmentToParent != Margin(-1, -1, -1, -1);
}
}
}
}
/***********************************************************************
.\APPLICATION\GRAPHICSCOMPOSITIONS\GUIGRAPHICSCOMPOSITION.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
using namespace elements;
void InvokeOnCompositionStateChanged(compositions::GuiGraphicsComposition* composition)
{
composition->InvokeOnCompositionStateChanged();
}
/***********************************************************************
GuiGraphicsComposition
***********************************************************************/
void GuiGraphicsComposition::OnControlParentChanged(controls::GuiControl* control)
{
if (associatedControl && associatedControl != control)
{
if (associatedControl->GetParent())
{
associatedControl->GetParent()->OnChildRemoved(associatedControl);
}
if (control)
{
control->OnChildInserted(associatedControl);
}
}
else
{
for (auto child : children)
{
child->OnControlParentChanged(control);
}
}
}
void GuiGraphicsComposition::OnChildInserted(GuiGraphicsComposition* child)
{
child->OnControlParentChanged(GetRelatedControl());
}
void GuiGraphicsComposition::OnChildRemoved(GuiGraphicsComposition* child)
{
child->OnControlParentChanged(nullptr);
}
void GuiGraphicsComposition::OnParentChanged(GuiGraphicsComposition* oldParent, GuiGraphicsComposition* newParent)
{
OnParentLineChanged();
}
void GuiGraphicsComposition::OnParentLineChanged()
{
for (auto child : children)
{
child->OnParentLineChanged();
}
}
void GuiGraphicsComposition::OnCompositionStateChanged()
{
}
void GuiGraphicsComposition::OnRenderContextChanged()
{
}
void GuiGraphicsComposition::UpdateRelatedHostRecord(GraphicsHostRecord* record)
{
relatedHostRecord = record;
auto renderTarget = GetRenderTarget();
if (ownedElement)
{
if (auto renderer = ownedElement->GetRenderer())
{
renderer->SetRenderTarget(renderTarget);
}
}
for (auto child : children)
{
child->UpdateRelatedHostRecord(record);
}
if (HasEventReceiver())
{
GetEventReceiver()->renderTargetChanged.Execute(GuiEventArgs(this));
}
if (associatedControl)
{
associatedControl->OnRenderTargetChanged(renderTarget);
}
OnRenderContextChanged();
}
void GuiGraphicsComposition::SetAssociatedControl(controls::GuiControl* control)
{
if (associatedControl)
{
for (auto child : children)
{
child->OnControlParentChanged(nullptr);
}
}
associatedControl = control;
if (associatedControl)
{
for (auto child : children)
{
child->OnControlParentChanged(associatedControl);
}
}
}
void GuiGraphicsComposition::InvokeOnCompositionStateChanged(bool forceRequestRender)
{
OnCompositionStateChanged();
if (relatedHostRecord && (forceRequestRender || GetEventuallyVisible()))
{
relatedHostRecord->host->RequestRender();
}
}
bool GuiGraphicsComposition::SharedPtrDestructorProc(DescriptableObject* obj, bool forceDisposing)
{
GuiGraphicsComposition* value=dynamic_cast<GuiGraphicsComposition*>(obj);
if(value->parent)
{
if (!forceDisposing) return false;
}
SafeDeleteComposition(value);
return true;
}
GuiGraphicsComposition::GuiGraphicsComposition()
{
sharedPtrDestructorProc = &GuiGraphicsComposition::SharedPtrDestructorProc;
CachedMinSizeChanged.SetAssociatedComposition(this);
CachedBoundsChanged.SetAssociatedComposition(this);
}
GuiGraphicsComposition::~GuiGraphicsComposition()
{
for (auto child : children)
{
delete child;
}
}
bool GuiGraphicsComposition::IsRendering()
{
return isRendering;
}
GuiGraphicsComposition* GuiGraphicsComposition::GetParent()
{
return parent;
}
const GuiGraphicsComposition::CompositionList& GuiGraphicsComposition::Children()
{
return children;
}
bool GuiGraphicsComposition::AddChild(GuiGraphicsComposition* child)
{
return InsertChild(children.Count(), child);
}
bool GuiGraphicsComposition::InsertChild(vint index, GuiGraphicsComposition* child)
{
CHECK_ERROR(!isRendering, L"GuiGraphicsComposition::InsertChild(vint, GuiGraphicsComposition*)#Cannot modify composition tree during rendering.");
if (!child) return false;
if (child->GetParent()) return false;
children.Insert(index, child);
// composition parent changed -> control parent changed -> related host changed
child->parent = this;
child->OnParentChanged(nullptr, this);
OnChildInserted(child);
child->UpdateRelatedHostRecord(relatedHostRecord);
InvokeOnCompositionStateChanged();
return true;
}
bool GuiGraphicsComposition::RemoveChild(GuiGraphicsComposition* child)
{
CHECK_ERROR(!isRendering, L"GuiGraphicsComposition::InsertChild(vint, GuiGraphicsComposition*)#Cannot modify composition tree during rendering.");
if (!child) return false;
vint index = children.IndexOf(child);
if (index == -1) return false;
// composition parent changed -> control parent changed -> related host changed
child->parent = nullptr;
child->OnParentChanged(this, nullptr);
OnChildRemoved(child);
child->UpdateRelatedHostRecord(nullptr);
GuiGraphicsHost* host = GetRelatedGraphicsHost();
if (host)
{
host->DisconnectComposition(child);
}
children.RemoveAt(index);
InvokeOnCompositionStateChanged();
return true;
}
bool GuiGraphicsComposition::MoveChild(GuiGraphicsComposition* child, vint newIndex)
{
if(!child) return false;
vint index=children.IndexOf(child);
if(index==-1) return false;
if(index==newIndex) return true;
children.RemoveAt(index);
children.Insert(newIndex, child);
InvokeOnCompositionStateChanged();
return true;
}
Ptr<IGuiGraphicsElement> GuiGraphicsComposition::GetOwnedElement()
{
return ownedElement;
}
void GuiGraphicsComposition::SetOwnedElement(Ptr<IGuiGraphicsElement> element)
{
if (ownedElement != element)
{
if (ownedElement)
{
if (auto renderer = ownedElement->GetRenderer())
{
renderer->SetRenderTarget(nullptr);
}
ownedElement->SetOwnerComposition(nullptr);
}
ownedElement = element;
if (ownedElement)
{
if (auto renderer = ownedElement->GetRenderer())
{
renderer->SetRenderTarget(GetRenderTarget());
}
ownedElement->SetOwnerComposition(this);
}
InvokeOnCompositionStateChanged();
}
}
bool GuiGraphicsComposition::GetVisible()
{
return visible;
}
void GuiGraphicsComposition::SetVisible(bool value)
{
if (visible != value)
{
visible = value;
InvokeOnCompositionStateChanged(true);
}
}
bool GuiGraphicsComposition::GetEventuallyVisible()
{
auto current = this;
while (current)
{
if (!current->visible) return false;
current = current->parent;
}
return true;
}
GuiGraphicsComposition::MinSizeLimitation GuiGraphicsComposition::GetMinSizeLimitation()
{
return minSizeLimitation;
}
void GuiGraphicsComposition::SetMinSizeLimitation(MinSizeLimitation value)
{
if (minSizeLimitation != value)
{
minSizeLimitation = value;
InvokeOnCompositionStateChanged();
}
}
elements::IGuiGraphicsRenderTarget* GuiGraphicsComposition::GetRenderTarget()
{
return relatedHostRecord ? relatedHostRecord->renderTarget : nullptr;
}
void GuiGraphicsComposition::Render(Size offset)
{
auto renderTarget = GetRenderTarget();
if (visible && renderTarget && !renderTarget->IsClipperCoverWholeTarget())
{
Rect bounds = GetCachedBounds();
if (bounds.x1 <= bounds.x2 && bounds.y1 <= bounds.y2)
{
bounds.x1 += offset.x;
bounds.x2 += offset.x;
bounds.y1 += offset.y;
bounds.y2 += offset.y;
isRendering = true;
if (ownedElement)
{
IGuiGraphicsRenderer* renderer = ownedElement->GetRenderer();
if (renderer)
{
renderer->Render(bounds);
}
}
if (children.Count() > 0 || associatedHitTestResult != INativeWindowListener::NoDecision || associatedCursor)
{
renderTarget->PushClipper(bounds, this);
if (!renderTarget->IsClipperCoverWholeTarget())
{
for (auto child : children)
{
child->Render(Size(bounds.x1, bounds.y1));
}
}
renderTarget->PopClipper(this);
}
isRendering = false;
}
}
}
GuiGraphicsEventReceiver* GuiGraphicsComposition::GetEventReceiver()
{
if(!eventReceiver)
{
eventReceiver=Ptr(new GuiGraphicsEventReceiver(this));
}
return eventReceiver.Obj();
}
bool GuiGraphicsComposition::HasEventReceiver()
{
return eventReceiver;
}
GuiGraphicsComposition* GuiGraphicsComposition::FindVisibleComposition(Point location, bool forMouseEvent)
{
if (!visible) return 0;
Rect bounds = GetCachedBounds();
Rect relativeBounds = Rect(Point(0, 0), bounds.GetSize());
if (relativeBounds.Contains(location))
{
// TODO: (enumerable) foreach:reversed
for (vint i = children.Count() - 1; i >= 0; i--)
{
GuiGraphicsComposition* child = children[i];
Rect childBounds = child->GetCachedBounds();
Point newLocation = location - Size(childBounds.x1, childBounds.y1);
GuiGraphicsComposition* childResult = child->FindVisibleComposition(newLocation, forMouseEvent);
if (childResult)
{
return childResult;
}
}
if (!forMouseEvent || !transparentToMouse)
{
return this;
}
}
return nullptr;
}
bool GuiGraphicsComposition::GetTransparentToMouse()
{
return transparentToMouse;
}
void GuiGraphicsComposition::SetTransparentToMouse(bool value)
{
transparentToMouse = value;
}
controls::GuiControl* GuiGraphicsComposition::GetAssociatedControl()
{
return associatedControl;
}
GuiGraphicsHost* GuiGraphicsComposition::GetAssociatedHost()
{
if (relatedHostRecord && relatedHostRecord->host->GetMainComposition() == this)
{
return relatedHostRecord->host;
}
else
{
return nullptr;
}
}
INativeCursor* GuiGraphicsComposition::GetAssociatedCursor()
{
return associatedCursor;
}
void GuiGraphicsComposition::SetAssociatedCursor(INativeCursor* cursor)
{
associatedCursor = cursor;
}
INativeWindowListener::HitTestResult GuiGraphicsComposition::GetAssociatedHitTestResult()
{
return associatedHitTestResult;
}
void GuiGraphicsComposition::SetAssociatedHitTestResult(INativeWindowListener::HitTestResult value)
{
associatedHitTestResult = value;
}
controls::GuiControl* GuiGraphicsComposition::GetRelatedControl()
{
GuiGraphicsComposition* composition = this;
while (composition)
{
if (composition->GetAssociatedControl())
{
return composition->GetAssociatedControl();
}
else
{
composition = composition->GetParent();
}
}
return nullptr;
}
GuiGraphicsHost* GuiGraphicsComposition::GetRelatedGraphicsHost()
{
return relatedHostRecord ? relatedHostRecord->host : nullptr;
}
controls::GuiControlHost* GuiGraphicsComposition::GetRelatedControlHost()
{
if (auto control = GetRelatedControl())
{
return control->GetRelatedControlHost();
}
return nullptr;
}
INativeCursor* GuiGraphicsComposition::GetRelatedCursor()
{
GuiGraphicsComposition* composition = this;
while (composition)
{
if (composition->GetAssociatedCursor())
{
return composition->GetAssociatedCursor();
}
else
{
composition = composition->GetParent();
}
}
return nullptr;
}
INativeWindowListener::HitTestResult GuiGraphicsComposition::GetRelatedHitTestResult()
{
GuiGraphicsComposition* composition = this;
while (composition)
{
INativeWindowListener::HitTestResult result = composition->GetAssociatedHitTestResult();
if (result == INativeWindowListener::NoDecision)
{
composition = composition->GetParent();
}
else
{
return result;
}
}
return INativeWindowListener::NoDecision;
}
Margin GuiGraphicsComposition::GetInternalMargin()
{
return internalMargin;
}
void GuiGraphicsComposition::SetInternalMargin(Margin value)
{
if (value.left < 0) value.left = 0;
if (value.top < 0) value.top = 0;
if (value.right < 0) value.right = 0;
if (value.bottom < 0) value.bottom = 0;
if (internalMargin != value)
{
internalMargin = value;
InvokeOnCompositionStateChanged();
}
}
Size GuiGraphicsComposition::GetPreferredMinSize()
{
return preferredMinSize;
}
void GuiGraphicsComposition::SetPreferredMinSize(Size value)
{
if (value.x < 0) value.x = 0;
if (value.y < 0) value.y = 0;
if (preferredMinSize != value)
{
preferredMinSize = value;
InvokeOnCompositionStateChanged();
}
}
}
}
}
/***********************************************************************
.\APPLICATION\GRAPHICSCOMPOSITIONS\GUIGRAPHICSCOMPOSITION_HELPERS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
using namespace controls;
/***********************************************************************
Helper Functions
***********************************************************************/
void NotifyFinalizeInstance(controls::GuiControl* value)
{
if (value)
{
NotifyFinalizeInstance(value->GetBoundsComposition());
}
}
void NotifyFinalizeInstance(GuiGraphicsComposition* value)
{
if (value)
{
bool finalized = false;
if (auto root = dynamic_cast<GuiInstanceRootObject*>(value))
{
if (root->IsFinalized())
{
finalized = true;
}
else
{
root->FinalizeInstance();
}
}
if (auto control = value->GetAssociatedControl())
{
if (auto root = dynamic_cast<GuiInstanceRootObject*>(control))
{
if (root->IsFinalized())
{
finalized = true;
}
else
{
root->FinalizeInstance();
}
}
}
if (!finalized)
{
for (auto child : value->Children())
{
NotifyFinalizeInstance(child);
}
}
}
}
void SafeDeleteControlInternal(controls::GuiControl* value)
{
if(value)
{
if (value->GetRelatedControlHost() != value)
{
GuiGraphicsComposition* bounds = value->GetBoundsComposition();
if (bounds->GetParent())
{
bounds->GetParent()->RemoveChild(bounds);
}
}
delete value;
}
}
void SafeDeleteCompositionInternal(GuiGraphicsComposition* value)
{
if (value)
{
if (value->GetParent())
{
value->GetParent()->RemoveChild(value);
}
if (value->GetAssociatedControl())
{
SafeDeleteControlInternal(value->GetAssociatedControl());
}
else
{
// TODO: (enumerable) foreach:reversed
for (vint i = value->Children().Count() - 1; i >= 0; i--)
{
SafeDeleteCompositionInternal(value->Children().Get(i));
}
delete value;
}
}
}
void SafeDeleteControl(controls::GuiControl* value)
{
if (auto controlHost = dynamic_cast<controls::GuiControlHost*>(value))
{
controlHost->DeleteAfterProcessingAllEvents({});
}
else
{
NotifyFinalizeInstance(value);
SafeDeleteControlInternal(value);
}
}
void SafeDeleteComposition(GuiGraphicsComposition* value)
{
NotifyFinalizeInstance(value);
SafeDeleteCompositionInternal(value);
}
}
}
}
/***********************************************************************
.\APPLICATION\GRAPHICSCOMPOSITIONS\GUIGRAPHICSCOMPOSITION_LAYOUT.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
using namespace elements;
/***********************************************************************
GuiGraphicsComposition
***********************************************************************/
Size GuiGraphicsComposition::Layout_CalculateMinSizeHelper()
{
Size minSize;
if (minSize.x < preferredMinSize.x) minSize.x = preferredMinSize.x;
if (minSize.y < preferredMinSize.y) minSize.y = preferredMinSize.y;
if (minSizeLimitation != GuiGraphicsComposition::NoLimit)
{
if (ownedElement)
{
IGuiGraphicsRenderer* renderer = ownedElement->GetRenderer();
if (renderer)
{
auto elementSize = renderer->GetMinSize();
if (minSize.x < elementSize.x) minSize.x = elementSize.x;
if (minSize.y < elementSize.y) minSize.y = elementSize.y;
}
}
}
vint offsetW = internalMargin.left + internalMargin.right;
vint offsetH = internalMargin.top + internalMargin.bottom;
minSize.x += offsetW;
minSize.y += offsetH;
for (auto child : children)
{
child->Layout_UpdateMinSize();
}
if (minSizeLimitation == GuiGraphicsComposition::LimitToElementAndChildren)
{
for (auto child : children)
{
Size minClientSize = child->Layout_CalculateMinClientSizeForParent(internalMargin);
Size minBoundsSize(minClientSize.x + offsetW, minClientSize.y + offsetH);
if (minSize.x < minBoundsSize.x) minSize.x = minBoundsSize.x;
if (minSize.y < minBoundsSize.y) minSize.y = minBoundsSize.y;
}
}
return minSize;
}
void GuiGraphicsComposition::Layout_SetCachedMinSize(Size value)
{
if (value.x < 0) value.x = 0;
if (value.y < 0) value.y = 0;
if (cachedMinSize != value)
{
cachedMinSize = value;
CachedMinSizeChanged.Execute(GuiEventArgs(this));
InvokeOnCompositionStateChanged();
}
}
void GuiGraphicsComposition::Layout_SetCachedBounds(Rect value)
{
if (value.x2 < value.x1) value.x2 = value.x1;
if (value.y2 < value.y1) value.y2 = value.y1;
if (cachedBounds != value)
{
cachedBounds = value;
CachedBoundsChanged.Execute(GuiEventArgs(this));
InvokeOnCompositionStateChanged();
}
}
void GuiGraphicsComposition::Layout_UpdateMinSize()
{
Layout_SetCachedMinSize(Layout_CalculateMinSize());
}
void GuiGraphicsComposition::Layout_UpdateBounds(Size parentSize)
{
Layout_SetCachedBounds(Layout_CalculateBounds(parentSize));
for (auto child : children)
{
child->Layout_UpdateBounds(cachedBounds.GetSize());
}
}
Size GuiGraphicsComposition::GetCachedMinSize()
{
return cachedMinSize;
}
Size GuiGraphicsComposition::GetCachedMinClientSize()
{
auto minSize = cachedMinSize;
minSize.x -= internalMargin.left + internalMargin.right;
minSize.y -= internalMargin.top + internalMargin.bottom;
return minSize;
}
Rect GuiGraphicsComposition::GetCachedBounds()
{
return cachedBounds;
}
Rect GuiGraphicsComposition::GetCachedClientArea()
{
Rect bounds = cachedBounds;
bounds.x1 += internalMargin.left;
bounds.y1 += internalMargin.top;
bounds.x2 -= internalMargin.right;
bounds.y2 -= internalMargin.bottom;
if (bounds.x2 < bounds.x1) bounds.x2 = bounds.x1;
if (bounds.y2 < bounds.y1) bounds.y2 = bounds.y1;
return bounds;
}
Rect GuiGraphicsComposition::GetGlobalBounds()
{
Rect bounds = cachedBounds;
GuiGraphicsComposition* composition = parent;
while (composition)
{
Point offset = composition->cachedBounds.LeftTop();
bounds.x1 += offset.x;
bounds.x2 += offset.x;
bounds.y1 += offset.y;
bounds.y2 += offset.y;
composition = composition->parent;
}
return bounds;
}
void GuiGraphicsComposition::ForceCalculateSizeImmediately()
{
Size parentSize;
if (parent)
{
parentSize = parent->cachedBounds.GetSize();
}
Layout_UpdateMinSize();
Layout_UpdateBounds(parentSize);
}
}
}
}
/***********************************************************************
.\APPLICATION\GRAPHICSCOMPOSITIONS\GUIGRAPHICSEVENTRECEIVER.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
/***********************************************************************
Event Receiver
***********************************************************************/
GuiGraphicsEventReceiver::GuiGraphicsEventReceiver(GuiGraphicsComposition* _sender)
:sender(_sender)
,leftButtonDown(_sender)
,leftButtonUp(_sender)
,leftButtonDoubleClick(_sender)
,middleButtonDown(_sender)
,middleButtonUp(_sender)
,middleButtonDoubleClick(_sender)
,rightButtonDown(_sender)
,rightButtonUp(_sender)
,rightButtonDoubleClick(_sender)
,horizontalWheel(_sender)
,verticalWheel(_sender)
,mouseMove(_sender)
,mouseEnter(_sender)
,mouseLeave(_sender)
,previewKey(_sender)
,keyDown(_sender)
,keyUp(_sender)
,previewCharInput(_sender)
,charInput(_sender)
,gotFocus(_sender)
,lostFocus(_sender)
,caretNotify(_sender)
,clipboardNotify(_sender)
,renderTargetChanged(_sender)
{
}
GuiGraphicsEventReceiver::~GuiGraphicsEventReceiver()
{
}
GuiGraphicsComposition* GuiGraphicsEventReceiver::GetAssociatedComposition()
{
return sender;
}
}
}
}
/***********************************************************************
.\APPLICATION\GRAPHICSCOMPOSITIONS\GUIGRAPHICSWINDOWCOMPOSITION.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
/***********************************************************************
GuiWindowComposition
***********************************************************************/
Rect GuiWindowComposition::Layout_CalculateBounds(Size parentSize)
{
Rect bounds;
if (relatedHostRecord)
{
if (auto window = relatedHostRecord->host->GetNativeWindow())
{
bounds = Rect(Point(0, 0), window->Convert(window->GetClientSize()));
}
}
return bounds;
}
}
}
}
/***********************************************************************
.\APPLICATION\GRAPHICSHOST\GUIGRAPHICSHOST.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
using namespace collections;
using namespace controls;
using namespace elements;
/***********************************************************************
GuiGraphicsTimerManager
***********************************************************************/
GuiGraphicsTimerManager::GuiGraphicsTimerManager()
{
}
GuiGraphicsTimerManager::~GuiGraphicsTimerManager()
{
}
void GuiGraphicsTimerManager::AddCallback(Ptr<IGuiGraphicsTimerCallback> callback)
{
callbacks.Add(callback);
}
void GuiGraphicsTimerManager::Play()
{
// TODO: (enumerable) foreach:indexed(alterable(reversed))
for (vint i = callbacks.Count() - 1; i >= 0; i--)
{
auto callback = callbacks[i];
if (!callback->Play())
{
callbacks.RemoveAt(i);
}
}
}
/***********************************************************************
GuiGraphicsHost
***********************************************************************/
void GuiGraphicsHost::RefreshRelatedHostRecord(INativeWindow* nativeWindow)
{
hostRecord.nativeWindow = nativeWindow;
hostRecord.renderTarget = nativeWindow ? GetGuiGraphicsResourceManager()->GetRenderTarget(nativeWindow) : nullptr;
windowComposition->UpdateRelatedHostRecord(&hostRecord);
}
void GuiGraphicsHost::SetFocusInternal(GuiGraphicsComposition* composition)
{
if (focusedComposition && focusedComposition->HasEventReceiver())
{
GuiEventArgs arguments;
arguments.compositionSource = focusedComposition;
arguments.eventSource = focusedComposition;
focusedComposition->GetEventReceiver()->lostFocus.Execute(arguments);
}
focusedComposition = composition;
SetCaretPoint(Point(0, 0));
if (focusedComposition && focusedComposition->HasEventReceiver())
{
GuiEventArgs arguments;
arguments.compositionSource = focusedComposition;
arguments.eventSource = focusedComposition;
focusedComposition->GetEventReceiver()->gotFocus.Execute(arguments);
}
}
void GuiGraphicsHost::DisconnectCompositionInternal(GuiGraphicsComposition* composition)
{
// TODO: (enumerable) foreach
for(vint i=0;i<composition->Children().Count();i++)
{
DisconnectCompositionInternal(composition->Children().Get(i));
}
if(mouseCaptureComposition==composition)
{
if(hostRecord.nativeWindow)
{
hostRecord.nativeWindow->ReleaseCapture();
}
mouseCaptureComposition=0;
}
if(focusedComposition==composition)
{
focusedComposition=0;
}
mouseEnterCompositions.Remove(composition);
}
void GuiGraphicsHost::MouseCapture(const NativeWindowMouseInfo& info)
{
if (hostRecord.nativeWindow && (info.left || info.middle || info.right))
{
if (!hostRecord.nativeWindow->IsCapturing() && !info.nonClient)
{
hostRecord.nativeWindow->RequireCapture();
auto point = hostRecord.nativeWindow->Convert(NativePoint(info.x, info.y));
mouseCaptureComposition = windowComposition->FindVisibleComposition(point, true);
}
}
}
void GuiGraphicsHost::MouseUncapture(const NativeWindowMouseInfo& info)
{
if(hostRecord.nativeWindow && !(info.left || info.middle || info.right))
{
hostRecord.nativeWindow->ReleaseCapture();
mouseCaptureComposition=0;
}
}
void GuiGraphicsHost::OnCharInput(const NativeWindowCharInfo& info, GuiGraphicsComposition* composition, GuiCharEvent GuiGraphicsEventReceiver::* eventReceiverEvent)
{
List<GuiGraphicsComposition*> compositions;
GuiCharEventArgs arguments(composition);
(NativeWindowCharInfo&)arguments = info;
while (composition)
{
if (composition->HasEventReceiver())
{
if (!arguments.eventSource)
{
arguments.eventSource = composition;
}
compositions.Add(composition);
}
composition = composition->GetParent();
}
// TODO: (enumerable) foreach:reversed
for(vint i=compositions.Count()-1;i>=0;i--)
{
compositions[i]->GetEventReceiver()->previewCharInput.Execute(arguments);
if(arguments.handled)
{
return;
}
}
// TODO: (enumerable) foreach
for(vint i=0;i<compositions.Count();i++)
{
(compositions[i]->GetEventReceiver()->*eventReceiverEvent).Execute(arguments);
if(arguments.handled)
{
return;
}
}
}
void GuiGraphicsHost::OnKeyInput(const NativeWindowKeyInfo& info, GuiGraphicsComposition* composition, GuiKeyEvent GuiGraphicsEventReceiver::* eventReceiverEvent)
{
List<GuiGraphicsComposition*> compositions;
GuiKeyEventArgs arguments(composition);
(NativeWindowKeyInfo&)arguments = info;
while (composition)
{
if (composition->HasEventReceiver())
{
if (!arguments.eventSource)
{
arguments.eventSource = composition;
}
compositions.Add(composition);
}
composition = composition->GetParent();
}
// TODO: (enumerable) foreach:reversed
for (vint i = compositions.Count() - 1; i >= 0; i--)
{
compositions[i]->GetEventReceiver()->previewKey.Execute(arguments);
if (arguments.handled)
{
return;
}
}
// TODO: (enumerable) foreach
for (vint i = 0; i < compositions.Count(); i++)
{
(compositions[i]->GetEventReceiver()->*eventReceiverEvent).Execute(arguments);
if (arguments.handled)
{
return;
}
}
}
void GuiGraphicsHost::RaiseMouseEvent(GuiMouseEventArgs& arguments, GuiGraphicsComposition* composition, GuiMouseEvent GuiGraphicsEventReceiver::* eventReceiverEvent)
{
arguments.compositionSource=composition;
arguments.eventSource=0;
vint x=arguments.x;
vint y=arguments.y;
while(composition)
{
if(composition->HasEventReceiver())
{
if(!arguments.eventSource)
{
arguments.eventSource=composition;
}
GuiGraphicsEventReceiver* eventReceiver=composition->GetEventReceiver();
(eventReceiver->*eventReceiverEvent).Execute(arguments);
if(arguments.handled)
{
break;
}
}
GuiGraphicsComposition* parent=composition->GetParent();
if(parent)
{
Rect parentBounds=parent->GetCachedBounds();
Rect clientArea=parent->GetCachedClientArea();
Rect childBounds=composition->GetCachedBounds();
x+=childBounds.x1+(clientArea.x1-parentBounds.x1);
y+=childBounds.y1+(clientArea.y1-parentBounds.y1);
arguments.x=x;
arguments.y=y;
}
composition=parent;
}
}
void GuiGraphicsHost::OnMouseInput(const NativeWindowMouseInfo& info, bool capture, bool release, GuiMouseEvent GuiGraphicsEventReceiver::* eventReceiverEvent)
{
if (capture) MouseCapture(info);
GuiGraphicsComposition* composition = 0;
if (mouseCaptureComposition)
{
composition = mouseCaptureComposition;
}
else
{
auto point = hostRecord.nativeWindow->Convert(NativePoint(info.x, info.y));
composition = windowComposition->FindVisibleComposition(point, true);
}
if (release) MouseUncapture(info);
if (composition)
{
Rect bounds = composition->GetGlobalBounds();
Point point = hostRecord.nativeWindow->Convert(NativePoint(info.x, info.y));
GuiMouseEventArgs arguments;
arguments.ctrl = info.ctrl;
arguments.shift = info.shift;
arguments.left = info.left;
arguments.middle = info.middle;
arguments.right = info.right;
arguments.wheel = info.wheel;
arguments.nonClient = info.nonClient;
arguments.x = point.x - bounds.x1;
arguments.y = point.y - bounds.y1;
RaiseMouseEvent(arguments, composition, eventReceiverEvent);
}
}
void GuiGraphicsHost::ResetRenderTarget()
{
windowComposition->UpdateRelatedHostRecord(nullptr);
}
void GuiGraphicsHost::CreateRenderTarget()
{
GetGuiGraphicsResourceManager()->RecreateRenderTarget(hostRecord.nativeWindow);
RefreshRelatedHostRecord(hostRecord.nativeWindow);
}
INativeWindowListener::HitTestResult GuiGraphicsHost::HitTest(NativePoint location)
{
NativeRect bounds = hostRecord.nativeWindow->GetBounds();
NativeRect clientBounds = hostRecord.nativeWindow->GetClientBoundsInScreen();
NativePoint clientLocation(location.x + bounds.x1 - clientBounds.x1, location.y + bounds.y1 - clientBounds.y1);
auto point = hostRecord.nativeWindow->Convert(clientLocation);
if (auto hitComposition = windowComposition->FindVisibleComposition(point, true))
{
return hitComposition->GetRelatedHitTestResult();
}
return INativeWindowListener::NoDecision;
}
void GuiGraphicsHost::Moving(NativeRect& bounds, bool fixSizeOnly, bool draggingBorder)
{
NativeRect oldBounds = hostRecord.nativeWindow->GetBounds();
minSize = windowComposition->GetCachedMinSize();
NativeSize minWindowSize = hostRecord.nativeWindow->Convert(minSize) + (oldBounds.GetSize() - hostRecord.nativeWindow->GetClientSize());
if (bounds.Width() < minWindowSize.x)
{
if (fixSizeOnly)
{
if (bounds.Width() < minWindowSize.x)
{
bounds.x2 = bounds.x1 + minWindowSize.x;
}
}
else if (oldBounds.x1 != bounds.x1)
{
bounds.x1 = oldBounds.x2 - minWindowSize.x;
}
else if (oldBounds.x2 != bounds.x2)
{
bounds.x2 = oldBounds.x1 + minWindowSize.x;
}
}
if (bounds.Height() < minWindowSize.y)
{
if (fixSizeOnly)
{
if (bounds.Height() < minWindowSize.y)
{
bounds.y2 = bounds.y1 + minWindowSize.y;
}
}
else if (oldBounds.y1 != bounds.y1)
{
bounds.y1 = oldBounds.y2 - minWindowSize.y;
}
else if (oldBounds.y2 != bounds.y2)
{
bounds.y2 = oldBounds.y1 + minWindowSize.y;
}
}
}
void GuiGraphicsHost::Moved()
{
RequestUpdateSizeFromNativeWindow();
}
void GuiGraphicsHost::DpiChanged(bool preparing)
{
if (preparing)
{
ResetRenderTarget();
}
else
{
CreateRenderTarget();
needRender = true;
}
}
void GuiGraphicsHost::Paint()
{
if (!supressPaint)
{
needRender = true;
}
}
void GuiGraphicsHost::LeftButtonDown(const NativeWindowMouseInfo& info)
{
altActionManager->CloseAltHost();
OnMouseInput(info, true, false, &GuiGraphicsEventReceiver::leftButtonDown);
}
void GuiGraphicsHost::LeftButtonUp(const NativeWindowMouseInfo& info)
{
OnMouseInput(info, false, true, &GuiGraphicsEventReceiver::leftButtonUp);
}
void GuiGraphicsHost::LeftButtonDoubleClick(const NativeWindowMouseInfo& info)
{
altActionManager->CloseAltHost();
OnMouseInput(info, false, false, &GuiGraphicsEventReceiver::leftButtonDown);
OnMouseInput(info, false, false, &GuiGraphicsEventReceiver::leftButtonDoubleClick);
}
void GuiGraphicsHost::RightButtonDown(const NativeWindowMouseInfo& info)
{
altActionManager->CloseAltHost();
OnMouseInput(info, true, false, &GuiGraphicsEventReceiver::rightButtonDown);
}
void GuiGraphicsHost::RightButtonUp(const NativeWindowMouseInfo& info)
{
OnMouseInput(info, false, true, &GuiGraphicsEventReceiver::rightButtonUp);
}
void GuiGraphicsHost::RightButtonDoubleClick(const NativeWindowMouseInfo& info)
{
altActionManager->CloseAltHost();
OnMouseInput(info, false, false, &GuiGraphicsEventReceiver::rightButtonDown);
OnMouseInput(info, false, false, &GuiGraphicsEventReceiver::rightButtonDoubleClick);
}
void GuiGraphicsHost::MiddleButtonDown(const NativeWindowMouseInfo& info)
{
altActionManager->CloseAltHost();
OnMouseInput(info, true, false, &GuiGraphicsEventReceiver::middleButtonDown);
}
void GuiGraphicsHost::MiddleButtonUp(const NativeWindowMouseInfo& info)
{
OnMouseInput(info, false, true, &GuiGraphicsEventReceiver::middleButtonUp);
}
void GuiGraphicsHost::MiddleButtonDoubleClick(const NativeWindowMouseInfo& info)
{
altActionManager->CloseAltHost();
OnMouseInput(info, false, false, &GuiGraphicsEventReceiver::middleButtonDown);
OnMouseInput(info, false, false, &GuiGraphicsEventReceiver::middleButtonDoubleClick);
}
void GuiGraphicsHost::HorizontalWheel(const NativeWindowMouseInfo& info)
{
OnMouseInput(info, false, false, &GuiGraphicsEventReceiver::horizontalWheel);
}
void GuiGraphicsHost::VerticalWheel(const NativeWindowMouseInfo& info)
{
OnMouseInput(info, false, false, &GuiGraphicsEventReceiver::verticalWheel);
}
void GuiGraphicsHost::MouseMoving(const NativeWindowMouseInfo& info)
{
CompositionList newCompositions;
{
auto point = hostRecord.nativeWindow->Convert(NativePoint(info.x, info.y));
GuiGraphicsComposition* composition = windowComposition->FindVisibleComposition(point, true);
while (composition)
{
newCompositions.Insert(0, composition);
composition = composition->GetParent();
}
}
vint firstDifferentIndex = mouseEnterCompositions.Count();
// TODO: (enumerable) foreach:indexed
for (vint i = 0; i < mouseEnterCompositions.Count(); i++)
{
if (i == newCompositions.Count())
{
firstDifferentIndex = newCompositions.Count();
break;
}
if (mouseEnterCompositions[i] != newCompositions[i])
{
firstDifferentIndex = i;
break;
}
}
// TODO: (enumerable) foreach:reversed Linq:Take
for (vint i = mouseEnterCompositions.Count() - 1; i >= firstDifferentIndex; i--)
{
GuiGraphicsComposition* composition = mouseEnterCompositions[i];
if (composition->HasEventReceiver())
{
composition->GetEventReceiver()->mouseLeave.Execute(GuiEventArgs(composition));
}
}
CopyFrom(mouseEnterCompositions, newCompositions);
// TODO: (enumerable) foreach Linq:Skip
for (vint i = firstDifferentIndex; i < mouseEnterCompositions.Count(); i++)
{
GuiGraphicsComposition* composition = mouseEnterCompositions[i];
if (composition->HasEventReceiver())
{
composition->GetEventReceiver()->mouseEnter.Execute(GuiEventArgs(composition));
}
}
INativeCursor* cursor = 0;
if (newCompositions.Count() > 0)
{
cursor = newCompositions[newCompositions.Count() - 1]->GetRelatedCursor();
}
if (cursor)
{
hostRecord.nativeWindow->SetWindowCursor(cursor);
}
else
{
hostRecord.nativeWindow->SetWindowCursor(GetCurrentController()->ResourceService()->GetDefaultSystemCursor());
}
OnMouseInput(info, false, false, &GuiGraphicsEventReceiver::mouseMove);
}
void GuiGraphicsHost::MouseEntered()
{
}
void GuiGraphicsHost::MouseLeaved()
{
// TODO: (enumerable) foreach:reversed
for (vint i = mouseEnterCompositions.Count() - 1; i >= 0; i--)
{
GuiGraphicsComposition* composition = mouseEnterCompositions[i];
if (composition->HasEventReceiver())
{
composition->GetEventReceiver()->mouseLeave.Execute(GuiEventArgs(composition));
}
}
mouseEnterCompositions.Clear();
}
void GuiGraphicsHost::KeyDown(const NativeWindowKeyInfo& info)
{
if (altActionManager->KeyDown(info)) { return; }
if (tabActionManager->KeyDown(info, focusedComposition)) { return; }
if(shortcutKeyManager && shortcutKeyManager->Execute(info)) { return; }
auto receiver = focusedComposition;
if (!receiver) receiver = controlHost->GetFocusableComposition();
if (!receiver) receiver = controlHost->GetBoundsComposition();
if (receiver && receiver->HasEventReceiver())
{
OnKeyInput(info, receiver, &GuiGraphicsEventReceiver::keyDown);
}
}
void GuiGraphicsHost::KeyUp(const NativeWindowKeyInfo& info)
{
if (altActionManager->KeyUp(info)) { return; }
if (!info.ctrl && !info.shift && info.code == VKEY::KEY_MENU && hostRecord.nativeWindow)
{
hostRecord.nativeWindow->SupressAlt();
}
auto receiver = focusedComposition;
if (!receiver) receiver = controlHost->GetFocusableComposition();
if (!receiver) receiver = controlHost->GetBoundsComposition();
if(receiver && receiver->HasEventReceiver())
{
OnKeyInput(info, receiver, &GuiGraphicsEventReceiver::keyUp);
}
}
void GuiGraphicsHost::Char(const NativeWindowCharInfo& info)
{
if (altActionManager->Char(info)) { return; }
if (tabActionManager->Char(info)) { return; }
auto receiver = focusedComposition;
if (!receiver) receiver = controlHost->GetFocusableComposition();
if (!receiver) receiver = controlHost->GetBoundsComposition();
if(receiver && receiver->HasEventReceiver())
{
OnCharInput(info, receiver, &GuiGraphicsEventReceiver::charInput);
}
}
bool GuiGraphicsHost::NeedRefresh()
{
return needRender;
}
void GuiGraphicsHost::ForceRefresh(bool handleFailure, bool& updated, bool& failureByResized, bool& failureByLostDevice)
{
if (hostRecord.nativeWindow && hostRecord.nativeWindow->IsVisible())
{
auto result = Render(true, handleFailure, updated);
failureByResized |= result == RenderTargetFailure::ResizeWhileRendering;
failureByLostDevice |= result == RenderTargetFailure::LostDevice;
}
else
{
updated = false;
failureByResized = false;
failureByLostDevice = false;
}
}
void GuiGraphicsHost::GlobalTimer()
{
timerManager.Play();
DateTime now = DateTime::UtcTime();
if (now.osMilliseconds - lastCaretTime >= CaretInterval)
{
lastCaretTime = now.osMilliseconds;
if (focusedComposition && focusedComposition->HasEventReceiver())
{
focusedComposition->GetEventReceiver()->caretNotify.Execute(GuiEventArgs(focusedComposition));
}
}
if (hostRecord.nativeWindow && hostRecord.nativeWindow->IsVisible() && hostRecord.nativeWindow->IsActivelyRefreshing())
{
bool updated = false;
Render(false, true, updated);
}
}
elements::RenderTargetFailure GuiGraphicsHost::Render(bool forceUpdate, bool handleFailure, bool& updated)
{
RenderTargetFailure result = RenderTargetFailure::None;
if (!renderingTriggeredInLastFrame && needRender)
{
GuiControlSignalEventArgs arguments(controlHost->boundsComposition);
arguments.controlSignal = ControlSignal::UpdateRequested;
controlHost->ControlSignalTrigerred.Execute(arguments);
}
else if (renderingTriggeredInLastFrame && !needRender)
{
GuiControlSignalEventArgs arguments(controlHost->boundsComposition);
arguments.controlSignal = ControlSignal::UpdateFullfilled;
controlHost->ControlSignalTrigerred.Execute(arguments);
}
updated = needRender;
renderingTriggeredInLastFrame = needRender;
if (!forceUpdate && !needRender)
{
return result;
}
needRender = false;
if(hostRecord.nativeWindow && hostRecord.nativeWindow->IsVisible())
{
supressPaint = true;
{
hostRecord.renderTarget->StartRendering();
auto nativeOffset = hostRecord.nativeWindow->GetRenderingOffset();
auto localOffset = hostRecord.nativeWindow->Convert(nativeOffset);
windowComposition->Render(localOffset);
result = hostRecord.renderTarget->StopRendering();
hostRecord.nativeWindow->RedrawContent();
}
supressPaint = false;
switch (result)
{
case RenderTargetFailure::ResizeWhileRendering:
if (handleFailure)
{
GetGuiGraphicsResourceManager()->ResizeRenderTarget(hostRecord.nativeWindow);
needRender = true;
}
break;
case RenderTargetFailure::LostDevice:
if (handleFailure)
{
ResetRenderTarget();
CreateRenderTarget();
needRender = true;
}
break;
default:
{
supressPaint = true;
auto bounds = windowComposition->GetCachedBounds();
windowComposition->Layout_UpdateMinSize();
auto preferred = windowComposition->GetCachedMinSize();
auto width = bounds.Width() > preferred.x ? bounds.Width() : preferred.x;
auto height = bounds.Height() > preferred.y ? bounds.Height() : preferred.y;
controlHost->UpdateClientSizeAfterRendering(preferred, Size(width, height));
windowComposition->Layout_UpdateBounds({ width,height });
supressPaint = false;
}
}
}
if (!needRender)
{
{
ProcList procs;
CopyFrom(procs, afterRenderProcs);
afterRenderProcs.Clear();
// TODO: (enumerable) foreach
for (vint i = 0; i < procs.Count(); i++)
{
procs[i]();
}
}
{
ProcMap procs;
CopyFrom(procs, afterRenderKeyedProcs);
afterRenderKeyedProcs.Clear();
// TODO: (enumerable) foreach
for (vint i = 0; i < procs.Count(); i++)
{
procs.Values()[i]();
}
}
}
return result;
}
GuiGraphicsHost::GuiGraphicsHost(controls::GuiControlHost* _controlHost, GuiGraphicsComposition* boundsComposition)
:controlHost(_controlHost)
{
altActionManager = new GuiAltActionManager(controlHost);
tabActionManager = new GuiTabActionManager(controlHost);
hostRecord.host = this;
windowComposition=new GuiWindowComposition;
windowComposition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
windowComposition->AddChild(boundsComposition);
RefreshRelatedHostRecord(nullptr);
}
GuiGraphicsHost::~GuiGraphicsHost()
{
windowComposition->RemoveChild(windowComposition->Children()[0]);
NotifyFinalizeInstance(windowComposition);
delete altActionManager;
delete tabActionManager;
if (shortcutKeyManager)
{
delete shortcutKeyManager;
shortcutKeyManager = nullptr;
}
delete windowComposition;
}
INativeWindow* GuiGraphicsHost::GetNativeWindow()
{
return hostRecord.nativeWindow;
}
void GuiGraphicsHost::SetNativeWindow(INativeWindow* _nativeWindow)
{
if (hostRecord.nativeWindow != _nativeWindow)
{
if (hostRecord.nativeWindow)
{
GetCurrentController()->CallbackService()->UninstallListener(this);
hostRecord.nativeWindow->UninstallListener(this);
}
if (_nativeWindow)
{
_nativeWindow->InstallListener(this);
GetCurrentController()->CallbackService()->InstallListener(this);
previousClientSize = _nativeWindow->GetClientSize();
minSize = windowComposition->GetCachedMinSize();
_nativeWindow->SetCaretPoint(_nativeWindow->Convert(caretPoint));
needRender = true;
}
RefreshRelatedHostRecord(_nativeWindow);
}
}
GuiGraphicsComposition* GuiGraphicsHost::GetMainComposition()
{
return windowComposition;
}
void GuiGraphicsHost::RequestRender()
{
needRender = true;
}
void GuiGraphicsHost::RequestUpdateSizeFromNativeWindow()
{
NativeSize size = hostRecord.nativeWindow->GetClientSize();
if (previousClientSize != size)
{
previousClientSize = size;
windowComposition->Layout_UpdateMinSize();
windowComposition->Layout_UpdateBounds(hostRecord.nativeWindow->Convert(size));
minSize = windowComposition->GetCachedMinSize();
needRender = true;
}
}
void GuiGraphicsHost::InvokeAfterRendering(const Func<void()>& proc, ProcKey key)
{
if (key.key == nullptr)
{
afterRenderProcs.Add(proc);
}
else
{
afterRenderKeyedProcs.Set(key, proc);
}
}
void GuiGraphicsHost::InvalidateTabOrderCache()
{
tabActionManager->InvalidateTabOrderCache();
}
IGuiShortcutKeyManager* GuiGraphicsHost::GetShortcutKeyManager()
{
return shortcutKeyManager;
}
void GuiGraphicsHost::SetShortcutKeyManager(IGuiShortcutKeyManager* value)
{
shortcutKeyManager=value;
}
bool GuiGraphicsHost::SetFocus(GuiGraphicsComposition* composition)
{
if(!composition || composition->GetRelatedGraphicsHost()!=this)
{
return false;
}
if(focusedComposition == composition)
{
return true;
}
SetFocusInternal(composition);
return true;
}
bool GuiGraphicsHost::ClearFocus()
{
if (!focusedComposition) return false;
SetFocusInternal(nullptr);
return true;
}
GuiGraphicsComposition* GuiGraphicsHost::GetFocusedComposition()
{
return focusedComposition;
}
Point GuiGraphicsHost::GetCaretPoint()
{
return caretPoint;
}
void GuiGraphicsHost::SetCaretPoint(Point value, GuiGraphicsComposition* referenceComposition)
{
if (referenceComposition)
{
Rect bounds = referenceComposition->GetGlobalBounds();
value.x += bounds.x1;
value.y += bounds.y1;
}
caretPoint = value;
if (hostRecord.nativeWindow)
{
hostRecord.nativeWindow->SetCaretPoint(hostRecord.nativeWindow->Convert(caretPoint));
}
}
GuiGraphicsTimerManager* GuiGraphicsHost::GetTimerManager()
{
return &timerManager;
}
void GuiGraphicsHost::DisconnectComposition(GuiGraphicsComposition* composition)
{
DisconnectCompositionInternal(composition);
}
}
}
}
/***********************************************************************
.\APPLICATION\GRAPHICSHOST\GUIGRAPHICSHOST_ALT.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
using namespace collections;
using namespace controls;
using namespace theme;
const wchar_t* const IGuiAltAction::Identifier = L"vl::presentation::compositions::IGuiAltAction";
const wchar_t* const IGuiAltActionContainer::Identifier = L"vl::presentation::compositions::IGuiAltActionContainer";
const wchar_t* const IGuiAltActionHost::Identifier = L"vl::presentation::compositions::IGuiAltActionHost";
/***********************************************************************
IGuiAltAction
***********************************************************************/
bool IGuiAltAction::IsLegalAlt(const WString& alt)
{
for (vint i = 0; i < alt.Length(); i++)
{
auto c = alt[i];
if (('A' <= c && c <= 'Z') || ('0' <= c && c <= '9'))
{
continue;
}
return false;
}
return true;
}
/***********************************************************************
IGuiAltActionHost
***********************************************************************/
void IGuiAltActionHost::CollectAltActionsFromControl(controls::GuiControl* control, bool includeThisControl, collections::Group<WString, IGuiAltAction*>& actions)
{
List<GuiControl*> controls;
controls.Add(control);
vint index = 0;
while (index < controls.Count())
{
auto current = controls[index++];
if (current != control || includeThisControl)
{
if (auto container = current->QueryTypedService<IGuiAltActionContainer>())
{
vint count = container->GetAltActionCount();
for (vint i = 0; i < count; i++)
{
auto action = container->GetAltAction(i);
actions.Add(action->GetAlt(), action);
}
continue;
}
else if (auto action = current->QueryTypedService<IGuiAltAction>())
{
if (action->IsAltAvailable())
{
if (action->IsAltEnabled())
{
actions.Add(action->GetAlt(), action);
continue;
}
}
}
}
vint count = current->GetChildrenCount();
for (vint i = 0; i < count; i++)
{
controls.Add(current->GetChild(i));
}
}
}
/***********************************************************************
GuiAltActionHostBase
***********************************************************************/
void GuiAltActionHostBase::SetAltComposition(GuiGraphicsComposition* _composition)
{
composition = _composition;
}
void GuiAltActionHostBase::SetAltControl(controls::GuiControl* _control, bool _includeControl)
{
control = _control;
includeControl = _includeControl;
}
GuiGraphicsComposition* GuiAltActionHostBase::GetAltComposition()
{
CHECK_ERROR(composition, L"GuiAltActionHostBase::GetAltComposition()#Need to call SetAltComposition.");
return composition;
}
IGuiAltActionHost* GuiAltActionHostBase::GetPreviousAltHost()
{
return previousHost;
}
void GuiAltActionHostBase::OnActivatedAltHost(IGuiAltActionHost* _previousHost)
{
previousHost = _previousHost;
}
void GuiAltActionHostBase::OnDeactivatedAltHost()
{
previousHost = nullptr;
}
void GuiAltActionHostBase::CollectAltActions(collections::Group<WString, IGuiAltAction*>& actions)
{
CHECK_ERROR(control, L"GuiAltActionHostBase::CollectAltActions(Group<WString, IGuiAltAction*>&)#Need to call SetAltControl.");
CollectAltActionsFromControl(control, includeControl, actions);
}
/***********************************************************************
GuiAltActionManager
***********************************************************************/
void GuiAltActionManager::EnterAltHost(IGuiAltActionHost* host)
{
ClearAltHost();
Group<WString, IGuiAltAction*> actions;
host->CollectAltActions(actions);
if (actions.Count() == 0)
{
CloseAltHost();
return;
}
host->OnActivatedAltHost(currentAltHost);
currentAltHost = host;
CreateAltTitles(actions);
}
void GuiAltActionManager::LeaveAltHost()
{
if (currentAltHost)
{
ClearAltHost();
auto previousHost = currentAltHost->GetPreviousAltHost();
currentAltHost->OnDeactivatedAltHost();
currentAltHost = previousHost;
if (currentAltHost)
{
Group<WString, IGuiAltAction*> actions;
currentAltHost->CollectAltActions(actions);
CreateAltTitles(actions);
}
}
}
bool GuiAltActionManager::EnterAltKey(wchar_t key)
{
currentAltPrefix += WString::FromChar(key);
vint index = currentActiveAltActions.Keys().IndexOf(currentAltPrefix);
if (index == -1)
{
if (FilterTitles() == 0)
{
currentAltPrefix = currentAltPrefix.Left(currentAltPrefix.Length() - 1);
FilterTitles();
}
}
else
{
auto action = currentActiveAltActions.Values()[index];
if (action->GetActivatingAltHost())
{
EnterAltHost(action->GetActivatingAltHost());
}
else
{
CloseAltHost();
}
action->OnActiveAlt();
return true;
}
return false;
}
void GuiAltActionManager::LeaveAltKey()
{
if (currentAltPrefix.Length() >= 1)
{
currentAltPrefix = currentAltPrefix.Left(currentAltPrefix.Length() - 1);
}
FilterTitles();
}
void GuiAltActionManager::CreateAltTitles(const collections::Group<WString, IGuiAltAction*>& actions)
{
if (currentAltHost)
{
// TODO: (enumerable) foreach on group (key, value[])
vint count = actions.Count();
for (vint i = 0; i < count; i++)
{
WString key = actions.Keys()[i];
const auto& values = actions.GetByIndex(i);
vint numberLength = 0;
if (values.Count() == 1 && key.Length() > 0)
{
numberLength = 0;
}
else if (values.Count() <= 10)
{
numberLength = 1;
}
else if (values.Count() <= 100)
{
numberLength = 2;
}
else if (values.Count() <= 1000)
{
numberLength = 3;
}
else
{
continue;
}
for (auto [action, index] : indexed(values))
{
WString key = actions.Keys()[i];
if (numberLength > 0)
{
WString number = itow(index);
while (number.Length() < numberLength)
{
number = L"0" + number;
}
key += number;
}
currentActiveAltActions.Add(key, action);
}
}
// TODO: (enumerable) foreach on dictionary
count = currentActiveAltActions.Count();
auto window = dynamic_cast<GuiWindow*>(currentAltHost->GetAltComposition()->GetRelatedControlHost());
for (vint i = 0; i < count; i++)
{
auto key = currentActiveAltActions.Keys()[i];
auto composition = currentActiveAltActions.Values()[i]->GetAltComposition();
auto label = new GuiLabel(theme::ThemeName::ShortcutKey);
if (auto labelStyle = window->TypedControlTemplateObject(true)->GetShortcutKeyTemplate())
{
label->SetControlTemplate(labelStyle);
}
label->SetText(key);
composition->AddChild(label->GetBoundsComposition());
currentActiveAltTitles.Add(key, label);
}
FilterTitles();
}
}
vint GuiAltActionManager::FilterTitles()
{
// TODO: (enumerable) foreach on dictionary
vint count = currentActiveAltTitles.Count();
vint visibles = 0;
for (vint i = 0; i < count; i++)
{
auto key = currentActiveAltTitles.Keys()[i];
auto value = currentActiveAltTitles.Values()[i];
if (key.Length() >= currentAltPrefix.Length() && key.Left(currentAltPrefix.Length()) == currentAltPrefix)
{
value->SetVisible(true);
if (currentAltPrefix.Length() <= key.Length())
{
value->SetText(
key
.Insert(currentAltPrefix.Length(), L"[")
.Insert(currentAltPrefix.Length() + 2, L"]")
);
}
else
{
value->SetText(key);
}
visibles++;
}
else
{
value->SetVisible(false);
}
}
return visibles;
}
void GuiAltActionManager::ClearAltHost()
{
for (auto title : currentActiveAltTitles.Values())
{
SafeDeleteControl(title);
}
currentActiveAltActions.Clear();
currentActiveAltTitles.Clear();
currentAltPrefix = L"";
}
void GuiAltActionManager::CloseAltHost()
{
ClearAltHost();
while (currentAltHost)
{
currentAltHost->OnDeactivatedAltHost();
currentAltHost = currentAltHost->GetPreviousAltHost();
}
}
GuiAltActionManager::GuiAltActionManager(controls::GuiControlHost* _controlHost)
:controlHost(_controlHost)
{
}
GuiAltActionManager::~GuiAltActionManager()
{
}
bool GuiAltActionManager::KeyDown(const NativeWindowKeyInfo& info)
{
if (!info.ctrl && !info.shift)
{
if (currentAltHost)
{
if (info.code == VKEY::KEY_ESCAPE)
{
LeaveAltHost();
return true;
}
else if (info.code == VKEY::KEY_BACK)
{
LeaveAltKey();
}
else if (VKEY::KEY_NUMPAD0 <= info.code && info.code <= VKEY::KEY_NUMPAD9)
{
if (EnterAltKey((wchar_t)(L'0' + ((vint)info.code - (vint)VKEY::KEY_NUMPAD0))))
{
supressAltKey = info.code;
return true;
}
}
else if ((VKEY::KEY_0 <= info.code && info.code <= VKEY::KEY_9) || (VKEY::KEY_A <= info.code && info.code <= VKEY::KEY_Z))
{
if (EnterAltKey((wchar_t)info.code))
{
supressAltKey = info.code;
return true;
}
}
}
else
{
if (info.code == VKEY::KEY_MENU)
{
if (auto altHost = controlHost->QueryTypedService<IGuiAltActionHost>())
{
if (!altHost->GetPreviousAltHost())
{
EnterAltHost(altHost);
}
}
}
}
}
if (currentAltHost)
{
return true;
}
return false;
}
bool GuiAltActionManager::KeyUp(const NativeWindowKeyInfo& info)
{
if (!info.ctrl && !info.shift && info.code == supressAltKey)
{
supressAltKey = VKEY::KEY_UNKNOWN;
return true;
}
return false;
}
bool GuiAltActionManager::Char(const NativeWindowCharInfo& info)
{
if (currentAltHost || supressAltKey != VKEY::KEY_UNKNOWN)
{
return true;
}
return false;
}
}
}
}
/***********************************************************************
.\APPLICATION\GRAPHICSHOST\GUIGRAPHICSHOST_SHORTCUTKEY.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
/***********************************************************************
GuiShortcutKeyItem
***********************************************************************/
GuiShortcutKeyItem::GuiShortcutKeyItem(GuiShortcutKeyManager* _shortcutKeyManager, bool _global, bool _ctrl, bool _shift, bool _alt, VKEY _key)
:shortcutKeyManager(_shortcutKeyManager)
,global(_global)
,ctrl(_ctrl)
,shift(_shift)
,alt(_alt)
,key(_key)
{
}
GuiShortcutKeyItem::~GuiShortcutKeyItem()
{
}
IGuiShortcutKeyManager* GuiShortcutKeyItem::GetManager()
{
return shortcutKeyManager;
}
WString GuiShortcutKeyItem::GetName()
{
WString name;
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
info.ctrl==ctrl &&
info.shift==shift &&
info.alt==alt &&
info.code==key;
}
bool GuiShortcutKeyItem::CanActivate(bool _ctrl, bool _shift, bool _alt, VKEY _key)
{
return
_ctrl==ctrl &&
_shift==shift &&
_alt==alt &&
_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()
{
return shortcutKeyItems.Count();
}
IGuiShortcutKeyItem* GuiShortcutKeyManager::GetItem(vint index)
{
return shortcutKeyItems[index].Obj();
}
bool GuiShortcutKeyManager::Execute(const NativeWindowKeyInfo& info)
{
bool executed=false;
for (auto item : shortcutKeyItems)
{
if(item->CanActivate(info))
{
item->Execute();
executed=true;
}
}
return executed;
}
IGuiShortcutKeyItem* GuiShortcutKeyManager::TryGetShortcut(bool ctrl, bool shift, bool alt, VKEY key)
{
for (auto item : shortcutKeyItems)
{
if (item->CanActivate(ctrl, shift, alt, key))
{
return item.Obj();
}
}
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);
}
}
}
}
/***********************************************************************
.\APPLICATION\GRAPHICSHOST\GUIGRAPHICSHOST_TAB.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
using namespace collections;
using namespace controls;
const wchar_t* const IGuiTabAction::Identifier = L"vl::presentation::compositions::IGuiTabAction";
/***********************************************************************
GuiTabActionManager
***********************************************************************/
namespace tab_focus
{
void CollectControls(GuiControl* current, bool includeCurrent, Group<vuint64_t, GuiControl*>& prioritized)
{
if (includeCurrent)
{
auto tabAction = current->QueryTypedService<IGuiTabAction>();
if (tabAction && (tabAction->IsTabAvailable() || tabAction->GetTabPriority() != -1))
{
vint priority = tabAction->GetTabPriority();
vuint64_t normalized = priority < 0 ? ~(vuint64_t)0 : (vuint64_t)priority;
prioritized.Add(normalized, current);
return;
}
}
vint count = current->GetChildrenCount();
for (vint i = 0; i < count; i++)
{
CollectControls(current->GetChild(i), true, prioritized);
}
}
void InsertPrioritized(List<GuiControl*>& controls, vint index, Group<vuint64_t, GuiControl*>& prioritized)
{
// TODO: (enumerable) Linq:SelectMany
vint count = prioritized.Count();
for (vint i = 0; i < count; i++)
{
auto& values = prioritized.GetByIndex(i);
for (vint j = 0; j < values.Count(); j++)
{
controls.Insert(index++, values[j]);
}
}
}
}
using namespace tab_focus;
void GuiTabActionManager::BuildControlList()
{
controlsInOrder.Clear();
{
Group<vuint64_t, GuiControl*> prioritized;
CollectControls(controlHost, false, prioritized);
InsertPrioritized(controlsInOrder, 0, prioritized);
}
// TODO: (enumerable) foreach
for (vint i = 0; i < controlsInOrder.Count(); i++)
{
Group<vuint64_t, GuiControl*> prioritized;
CollectControls(controlsInOrder[i], false, prioritized);
InsertPrioritized(controlsInOrder, i + 1, prioritized);
}
}
controls::GuiControl* GuiTabActionManager::GetNextFocusControl(controls::GuiControl* focusedControl, vint offset)
{
if (!available)
{
BuildControlList();
available = true;
}
#define STEP_AND_NORMALIZE(INDEX) (((INDEX) + offset + controlsInOrder.Count()) % controlsInOrder.Count())
if (controlsInOrder.Count() == 0) return nullptr;
vint startIndex = controlsInOrder.IndexOf(focusedControl);
startIndex =
startIndex == -1 ? 0 :
STEP_AND_NORMALIZE(startIndex);
vint index = startIndex;
do
{
auto control = controlsInOrder[index];
if (auto tabAction = control->QueryTypedService<IGuiTabAction>())
{
if (tabAction->IsTabAvailable() && tabAction->IsTabEnabled())
{
return control;
}
}
index = STEP_AND_NORMALIZE(index);
} while (index != startIndex);
#undef STEP_AND_NORMALIZE
return nullptr;
}
GuiTabActionManager::GuiTabActionManager(controls::GuiControlHost* _controlHost)
:controlHost(_controlHost)
{
}
GuiTabActionManager::~GuiTabActionManager()
{
}
void GuiTabActionManager::InvalidateTabOrderCache()
{
available = false;
controlsInOrder.Clear();
}
bool GuiTabActionManager::KeyDown(const NativeWindowKeyInfo& info, GuiGraphicsComposition* focusedComposition)
{
if (!info.ctrl && !info.alt && info.code == VKEY::KEY_TAB)
{
GuiControl* focusedControl = nullptr;
if (focusedComposition)
{
focusedControl = focusedComposition->GetRelatedControl();
if (focusedControl && focusedControl->GetAcceptTabInput())
{
return false;
}
}
if (auto next = GetNextFocusControl(focusedControl, (info.shift ? -1 : 1)))
{
next->SetFocused();
supressTabOnce = true;
return true;
}
}
return false;
}
bool GuiTabActionManager::Char(const NativeWindowCharInfo& info)
{
bool supress = supressTabOnce;
supressTabOnce = false;
return supress && info.code == L'\t';
}
}
}
}
/***********************************************************************
.\CONTROLS\GUIBUTTONCONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace elements;
using namespace compositions;
using namespace collections;
using namespace reflection::description;
/***********************************************************************
GuiButton
***********************************************************************/
void GuiButton::BeforeControlTemplateUninstalled_()
{
}
void GuiButton::AfterControlTemplateInstalled_(bool initialize)
{
TypedControlTemplateObject(true)->SetState(controlState);
}
void GuiButton::OnParentLineChanged()
{
GuiControl::OnParentLineChanged();
if (GetRelatedControlHost() == 0)
{
mousePressingDirect = false;
mousePressingIndirect = false;
mouseHoving = false;
UpdateControlState();
}
}
void GuiButton::OnActiveAlt()
{
if (autoFocus)
{
GuiControl::OnActiveAlt();
}
Clicked.Execute(GetNotifyEventArguments());
}
bool GuiButton::IsTabAvailable()
{
return autoFocus && GuiControl::IsTabAvailable();
}
void GuiButton::UpdateControlState()
{
auto newControlState = ButtonState::Normal;
if (keyPressing)
{
newControlState = ButtonState::Pressed;
}
else if (mousePressingDirect || mousePressingIndirect)
{
if (mouseHoving)
{
newControlState = ButtonState::Pressed;
}
else
{
newControlState = ButtonState::Active;
}
}
else
{
if (mouseHoving)
{
newControlState = ButtonState::Active;
}
else
{
newControlState = ButtonState::Normal;
}
}
if (controlState != newControlState)
{
controlState = newControlState;
TypedControlTemplateObject(true)->SetState(controlState);
}
}
void GuiButton::CheckAndClick(bool skipChecking, compositions::GuiEventArgs& arguments)
{
if (!skipChecking)
{
auto eventSource = arguments.eventSource->GetAssociatedControl();
while (eventSource && eventSource != this)
{
if (eventSource->GetFocusableComposition())
{
return;
}
eventSource = eventSource->GetParent();
}
}
Clicked.Execute(GetNotifyEventArguments());
}
void GuiButton::OnLeftButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if (arguments.eventSource == boundsComposition)
{
mousePressingDirect = true;
}
else if (!ignoreChildControlMouseEvents)
{
mousePressingIndirect = true;
}
if (mousePressingDirect || mousePressingIndirect)
{
if (GetVisuallyEnabled() && autoFocus)
{
SetFocused();
}
UpdateControlState();
if (GetVisuallyEnabled() && !clickOnMouseUp)
{
CheckAndClick(mousePressingIndirect, arguments);
}
}
}
void GuiButton::OnLeftButtonUp(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if (mousePressingDirect || mousePressingIndirect)
{
bool skipChecking = mousePressingIndirect;
mousePressingDirect = false;
mousePressingIndirect = false;
UpdateControlState();
if (GetVisuallyEnabled() && mouseHoving && clickOnMouseUp)
{
CheckAndClick(skipChecking, arguments);
}
}
}
void GuiButton::OnMouseEnter(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (arguments.eventSource == boundsComposition || !ignoreChildControlMouseEvents)
{
mouseHoving = true;
UpdateControlState();
}
}
void GuiButton::OnMouseLeave(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (arguments.eventSource == boundsComposition || !ignoreChildControlMouseEvents)
{
mouseHoving = false;
UpdateControlState();
}
}
void GuiButton::OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments)
{
if (arguments.eventSource == focusableComposition && !arguments.ctrl && !arguments.shift && !arguments.alt)
{
switch (arguments.code)
{
case VKEY::KEY_RETURN:
CheckAndClick(false, arguments);
arguments.handled = true;
break;
case VKEY::KEY_SPACE:
if (!arguments.autoRepeatKeyDown)
{
keyPressing = true;
UpdateControlState();
}
arguments.handled = true;
break;
default:;
}
}
}
void GuiButton::OnKeyUp(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments)
{
if (arguments.eventSource == focusableComposition && !arguments.ctrl && !arguments.shift && !arguments.alt)
{
switch (arguments.code)
{
case VKEY::KEY_SPACE:
if (keyPressing)
{
keyPressing = false;
UpdateControlState();
CheckAndClick(false, arguments);
}
arguments.handled = true;
break;
default:;
}
}
}
void GuiButton::OnLostFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (keyPressing)
{
keyPressing = false;
UpdateControlState();
}
}
GuiButton::GuiButton(theme::ThemeName themeName)
:GuiControl(themeName)
{
Clicked.SetAssociatedComposition(boundsComposition);
SetFocusableComposition(boundsComposition);
boundsComposition->GetEventReceiver()->leftButtonDown.AttachMethod(this, &GuiButton::OnLeftButtonDown);
boundsComposition->GetEventReceiver()->leftButtonUp.AttachMethod(this, &GuiButton::OnLeftButtonUp);
boundsComposition->GetEventReceiver()->mouseEnter.AttachMethod(this, &GuiButton::OnMouseEnter);
boundsComposition->GetEventReceiver()->mouseLeave.AttachMethod(this, &GuiButton::OnMouseLeave);
boundsComposition->GetEventReceiver()->keyDown.AttachMethod(this, &GuiButton::OnKeyDown);
boundsComposition->GetEventReceiver()->keyUp.AttachMethod(this, &GuiButton::OnKeyUp);
boundsComposition->GetEventReceiver()->lostFocus.AttachMethod(this, &GuiButton::OnLostFocus);
}
GuiButton::~GuiButton()
{
}
bool GuiButton::GetClickOnMouseUp()
{
return clickOnMouseUp;
}
void GuiButton::SetClickOnMouseUp(bool value)
{
clickOnMouseUp=value;
}
bool GuiButton::GetAutoFocus()
{
return autoFocus;
}
void GuiButton::SetAutoFocus(bool value)
{
autoFocus = value;
}
bool GuiButton::GetIgnoreChildControlMouseEvents()
{
return ignoreChildControlMouseEvents;
}
void GuiButton::SetIgnoreChildControlMouseEvents(bool value)
{
ignoreChildControlMouseEvents = value;
}
/***********************************************************************
GuiSelectableButton::GroupController
***********************************************************************/
GuiSelectableButton::GroupController::GroupController()
{
}
GuiSelectableButton::GroupController::~GroupController()
{
// TODO: (enumerable) foreach:reversed
for(vint i=buttons.Count()-1;i>=0;i--)
{
buttons[i]->SetGroupController(0);
}
}
void GuiSelectableButton::GroupController::Attach(GuiSelectableButton* button)
{
if(!buttons.Contains(button))
{
buttons.Add(button);
}
}
void GuiSelectableButton::GroupController::Detach(GuiSelectableButton* button)
{
buttons.Remove(button);
}
/***********************************************************************
GuiSelectableButton::MutexGroupController
***********************************************************************/
GuiSelectableButton::MutexGroupController::MutexGroupController()
:suppress(false)
{
}
GuiSelectableButton::MutexGroupController::~MutexGroupController()
{
}
void GuiSelectableButton::MutexGroupController::OnSelectedChanged(GuiSelectableButton* button)
{
if(!suppress)
{
suppress=true;
// TODO: (enumerable) foreach
for(vint i=0;i<buttons.Count();i++)
{
buttons[i]->SetSelected(buttons[i]==button);
}
suppress=false;
}
}
/***********************************************************************
GuiSelectableButton
***********************************************************************/
void GuiSelectableButton::BeforeControlTemplateUninstalled_()
{
}
void GuiSelectableButton::AfterControlTemplateInstalled_(bool initialize)
{
TypedControlTemplateObject(true)->SetSelected(isSelected);
}
void GuiSelectableButton::OnClicked(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if(autoSelection)
{
SetSelected(!GetSelected());
}
}
GuiSelectableButton::GuiSelectableButton(theme::ThemeName themeName)
:GuiButton(themeName)
{
GroupControllerChanged.SetAssociatedComposition(boundsComposition);
AutoSelectionChanged.SetAssociatedComposition(boundsComposition);
SelectedChanged.SetAssociatedComposition(boundsComposition);
Clicked.AttachMethod(this, &GuiSelectableButton::OnClicked);
}
GuiSelectableButton::~GuiSelectableButton()
{
if(groupController)
{
groupController->Detach(this);
}
}
GuiSelectableButton::GroupController* GuiSelectableButton::GetGroupController()
{
return groupController;
}
void GuiSelectableButton::SetGroupController(GroupController* value)
{
if(groupController)
{
groupController->Detach(this);
}
groupController=value;
if(groupController)
{
groupController->Attach(this);
}
GroupControllerChanged.Execute(GetNotifyEventArguments());
}
bool GuiSelectableButton::GetAutoSelection()
{
return autoSelection;
}
void GuiSelectableButton::SetAutoSelection(bool value)
{
if(autoSelection!=value)
{
autoSelection=value;
AutoSelectionChanged.Execute(GetNotifyEventArguments());
}
}
bool GuiSelectableButton::GetSelected()
{
return isSelected;
}
void GuiSelectableButton::SetSelected(bool value)
{
if (isSelected != value)
{
isSelected = value;
TypedControlTemplateObject(true)->SetSelected(isSelected);
if (groupController)
{
groupController->OnSelectedChanged(this);
}
SelectedChanged.Execute(GetNotifyEventArguments());
}
}
}
}
}
/***********************************************************************
.\CONTROLS\GUICONTAINERCONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace compositions;
namespace controls
{
using namespace reflection::description;
/***********************************************************************
GuiTabPage
***********************************************************************/
bool GuiTabPage::IsAltAvailable()
{
return false;
}
GuiTabPage::GuiTabPage(theme::ThemeName themeName)
:GuiCustomControl(themeName)
{
}
GuiTabPage::~GuiTabPage()
{
FinalizeAggregation();
}
GuiTab* GuiTabPage::GetOwnerTab()
{
return tab;
}
/***********************************************************************
GuiTabPageList
***********************************************************************/
bool GuiTabPageList::QueryInsert(vint index, GuiTabPage* const& value)
{
return !items.Contains(value) && value->tab == nullptr;
}
void GuiTabPageList::AfterInsert(vint index, GuiTabPage* const& value)
{
value->tab = tab;
value->SetVisible(false);
value->boundsComposition->SetAlignmentToParent(Margin(0, 0, 0, 0));
tab->containerComposition->AddChild(value->boundsComposition);
if (!tab->selectedPage)
{
tab->SetSelectedPage(value);
}
}
void GuiTabPageList::BeforeRemove(vint index, GuiTabPage* const& value)
{
tab->containerComposition->RemoveChild(value->boundsComposition);
value->tab = nullptr;
if (items.Count() > 1)
{
if (items.Count() > index + 1)
{
tab->SetSelectedPage(items[index + 1]);
}
else if (items.Count() == index + 1)
{
tab->SetSelectedPage(items[index - 1]);
}
}
}
void GuiTabPageList::AfterRemove(vint index, vint count)
{
if (items.Count() == 0)
{
tab->SetSelectedPage(nullptr);
}
}
GuiTabPageList::GuiTabPageList(GuiTab* _tab)
:tab(_tab)
{
}
GuiTabPageList::~GuiTabPageList()
{
}
/***********************************************************************
GuiTab::CommandExecutor
***********************************************************************/
GuiTab::CommandExecutor::CommandExecutor(GuiTab* _tab)
:tab(_tab)
{
}
GuiTab::CommandExecutor::~CommandExecutor()
{
}
void GuiTab::CommandExecutor::ShowTab(vint index, bool setFocus)
{
tab->SetSelectedPage(tab->GetPages().Get(index));
if (setFocus)
{
tab->SetFocused();
}
}
/***********************************************************************
GuiTab
***********************************************************************/
void GuiTab::BeforeControlTemplateUninstalled_()
{
auto ct = TypedControlTemplateObject(false);
if (!ct) return;
ct->SetCommands(nullptr);
ct->SetTabPages(nullptr);
ct->SetSelectedTabPage(nullptr);
}
void GuiTab::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
ct->SetCommands(commandExecutor.Obj());
ct->SetTabPages(UnboxValue<Ptr<IValueObservableList>>(BoxParameter(tabPages)));
ct->SetSelectedTabPage(selectedPage);
}
void GuiTab::OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments)
{
if (arguments.eventSource == focusableComposition)
{
if (auto ct = TypedControlTemplateObject(false))
{
vint index = tabPages.IndexOf(selectedPage);
if (index != -1)
{
auto hint = ct->GetTabOrder();
vint tabOffset = 0;
switch (hint)
{
case TabPageOrder::LeftToRight:
if (arguments.code == VKEY::KEY_LEFT) tabOffset = -1;
else if (arguments.code == VKEY::KEY_RIGHT) tabOffset = 1;
break;
case TabPageOrder::RightToLeft:
if (arguments.code == VKEY::KEY_LEFT) tabOffset = 1;
else if (arguments.code == VKEY::KEY_RIGHT) tabOffset = -1;
break;
case TabPageOrder::TopToBottom:
if (arguments.code == VKEY::KEY_UP) tabOffset = -1;
else if (arguments.code == VKEY::KEY_DOWN) tabOffset = 1;
break;
case TabPageOrder::BottomToTop:
if (arguments.code == VKEY::KEY_UP) tabOffset = 1;
else if (arguments.code == VKEY::KEY_DOWN) tabOffset = -1;
break;
default:;
}
if (tabOffset != 0)
{
arguments.handled = true;
index += tabOffset;
if (index < 0) index = 0;
else if (index >= tabPages.Count()) index = tabPages.Count() - 1;
SetSelectedPage(tabPages[index]);
}
}
}
}
}
GuiTab::GuiTab(theme::ThemeName themeName)
:GuiControl(themeName)
, tabPages(this)
{
commandExecutor = Ptr(new CommandExecutor(this));
SetFocusableComposition(boundsComposition);
boundsComposition->GetEventReceiver()->keyDown.AttachMethod(this, &GuiTab::OnKeyDown);
}
GuiTab::~GuiTab()
{
}
collections::ObservableList<GuiTabPage*>& GuiTab::GetPages()
{
return tabPages;
}
GuiTabPage* GuiTab::GetSelectedPage()
{
return selectedPage;
}
bool GuiTab::SetSelectedPage(GuiTabPage* value)
{
if (!value)
{
if (tabPages.Count() == 0)
{
selectedPage = nullptr;
}
}
else if (value->GetOwnerTab() == this)
{
if (selectedPage == value)
{
return true;
}
selectedPage = value;
for (auto tabPage : tabPages)
{
tabPage->SetVisible(tabPage == selectedPage);
}
}
if (auto ct = TypedControlTemplateObject(false))
{
ct->SetSelectedTabPage(selectedPage);
}
SelectedPageChanged.Execute(GetNotifyEventArguments());
return selectedPage == value;
}
/***********************************************************************
GuiScrollView
***********************************************************************/
void GuiScrollView::BeforeControlTemplateUninstalled_()
{
auto ct = TypedControlTemplateObject(false);
if (!ct) return;
if (auto scroll = ct->GetHorizontalScroll())
{
scroll->PositionChanged.Detach(hScrollHandler);
}
if (auto scroll = ct->GetVerticalScroll())
{
scroll->PositionChanged.Detach(vScrollHandler);
}
ct->GetEventReceiver()->horizontalWheel.Detach(hWheelHandler);
ct->GetEventReceiver()->verticalWheel.Detach(vWheelHandler);
ct->CachedBoundsChanged.Detach(containerCachedBoundsChangedHandler);
hScrollHandler = nullptr;
vScrollHandler = nullptr;
hWheelHandler = nullptr;
vWheelHandler = nullptr;
containerCachedBoundsChangedHandler = nullptr;
supressScrolling = false;
}
void GuiScrollView::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
if (auto scroll = ct->GetHorizontalScroll())
{
hScrollHandler = scroll->PositionChanged.AttachMethod(this, &GuiScrollView::OnHorizontalScroll);
}
if (auto scroll = ct->GetVerticalScroll())
{
vScrollHandler = scroll->PositionChanged.AttachMethod(this, &GuiScrollView::OnVerticalScroll);
}
hWheelHandler = ct->GetEventReceiver()->horizontalWheel.AttachMethod(this, &GuiScrollView::OnHorizontalWheel);
vWheelHandler = ct->GetEventReceiver()->verticalWheel.AttachMethod(this, &GuiScrollView::OnVerticalWheel);
containerCachedBoundsChangedHandler = ct->CachedBoundsChanged.AttachMethod(this, &GuiScrollView::OnContainerCachedBoundsChanged);
CalculateView();
}
void GuiScrollView::UpdateDisplayFont()
{
GuiControl::UpdateDisplayFont();
CalculateView();
}
void GuiScrollView::OnContainerCachedBoundsChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
CalculateView();
}
void GuiScrollView::OnHorizontalScroll(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if(!supressScrolling)
{
CallUpdateView();
}
}
void GuiScrollView::OnVerticalScroll(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if(!supressScrolling)
{
CallUpdateView();
}
}
void GuiScrollView::OnHorizontalWheel(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if(!supressScrolling)
{
if (auto scroll = TypedControlTemplateObject(true)->GetHorizontalScroll())
{
if (scroll->GetEnabled())
{
vint position = scroll->GetPosition();
vint move = scroll->GetSmallMove();
position -= move * arguments.wheel / 60;
scroll->SetPosition(position);
}
}
}
}
void GuiScrollView::OnVerticalWheel(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if(!supressScrolling && GetVisuallyEnabled())
{
if (auto scroll = TypedControlTemplateObject(true)->GetVerticalScroll())
{
if (scroll->GetEnabled())
{
vint position = scroll->GetPosition();
vint move = scroll->GetSmallMove();
position -= move * arguments.wheel / 60;
scroll->SetPosition(position);
}
}
}
}
void GuiScrollView::CallUpdateView()
{
Rect viewBounds=GetViewBounds();
UpdateView(viewBounds);
}
bool GuiScrollView::AdjustView(Size fullSize)
{
auto ct = TypedControlTemplateObject(true);
auto hScroll = ct->GetHorizontalScroll();
auto vScroll = ct->GetVerticalScroll();
Size viewSize = ct->GetContainerComposition()->GetCachedBounds().GetSize();
auto hVisible = hScroll ? hScroll->GetVisible() : false;
auto vVisible = vScroll ? vScroll->GetVisible() : false;
if (hScroll)
{
if (fullSize.x <= viewSize.x)
{
hScroll->SetVisible(horizontalAlwaysVisible);
hScroll->SetEnabled(false);
hScroll->SetPosition(0);
}
else
{
hScroll->SetVisible(true);
hScroll->SetEnabled(true);
hScroll->SetTotalSize(fullSize.x);
hScroll->SetPageSize(viewSize.x);
}
}
if (vScroll)
{
if (fullSize.y <= viewSize.y)
{
vScroll->SetVisible(verticalAlwaysVisible);
vScroll->SetEnabled(false);
vScroll->SetPosition(0);
}
else
{
vScroll->SetVisible(true);
vScroll->SetEnabled(true);
vScroll->SetTotalSize(fullSize.y);
vScroll->SetPageSize(viewSize.y);
}
}
auto hVisible2 = hScroll ? hScroll->GetVisible() : false;
auto vVisible2 = vScroll ? vScroll->GetVisible() : false;
return hVisible != hVisible2 || vVisible != vVisible2;
}
GuiScrollView::GuiScrollView(theme::ThemeName themeName)
:GuiControl(themeName)
{
containerComposition->CachedBoundsChanged.AttachMethod(this, &GuiScrollView::OnContainerCachedBoundsChanged);
}
vint GuiScrollView::GetSmallMove()
{
return GetDisplayFont().size * 2;
}
Size GuiScrollView::GetBigMove()
{
return GetViewSize();
}
GuiScrollView::~GuiScrollView()
{
}
void GuiScrollView::CalculateView()
{
TryDelayExecuteIfNotDeleted([=]()
{
auto ct = TypedControlTemplateObject(true);
auto hScroll = ct->GetHorizontalScroll();
auto vScroll = ct->GetVerticalScroll();
if (!supressScrolling)
{
Size fullSize = QueryFullSize();
while (true)
{
bool flagA = false;
bool flagB = false;
flagA = AdjustView(fullSize);
bool bothInvisible = (hScroll ? !hScroll->GetVisible() : true) && (vScroll ? !vScroll->GetVisible() : true);
if (!bothInvisible)
{
flagB = AdjustView(fullSize);
bothInvisible = (hScroll ? !hScroll->GetVisible() : true) && (vScroll ? !vScroll->GetVisible() : true);
}
supressScrolling = true;
CallUpdateView();
supressScrolling = false;
Size newSize = QueryFullSize();
if (fullSize == newSize)
{
vint smallMove = GetSmallMove();
Size bigMove = GetBigMove();
if (hScroll)
{
hScroll->SetSmallMove(smallMove);
hScroll->SetBigMove(bigMove.x);
}
if (vScroll)
{
vScroll->SetSmallMove(smallMove);
vScroll->SetBigMove(bigMove.y);
}
if (bothInvisible || !flagA && !flagB)
{
break;
}
}
else
{
fullSize = newSize;
}
}
}
});
}
Size GuiScrollView::GetViewSize()
{
Size viewSize = TypedControlTemplateObject(true)->GetContainerComposition()->GetCachedBounds().GetSize();
return viewSize;
}
Rect GuiScrollView::GetViewBounds()
{
return Rect(GetViewPosition(), GetViewSize());
}
Point GuiScrollView::GetViewPosition()
{
auto ct = TypedControlTemplateObject(true);
auto hScroll = ct->GetHorizontalScroll();
auto vScroll = ct->GetVerticalScroll();
return Point(
(hScroll && hScroll->GetEnabled()) ? hScroll->GetPosition() : 0,
(vScroll && vScroll->GetEnabled()) ? vScroll->GetPosition() : 0
);
}
void GuiScrollView::SetViewPosition(Point value)
{
if (GetViewPosition() == value) return;
auto ct = TypedControlTemplateObject(true);
if (auto hScroll = ct->GetHorizontalScroll())
{
hScroll->SetPosition(value.x);
}
if (auto vScroll = ct->GetVerticalScroll())
{
vScroll->SetPosition(value.y);
}
}
GuiScroll* GuiScrollView::GetHorizontalScroll()
{
return TypedControlTemplateObject(true)->GetHorizontalScroll();
}
GuiScroll* GuiScrollView::GetVerticalScroll()
{
return TypedControlTemplateObject(true)->GetVerticalScroll();
}
bool GuiScrollView::GetHorizontalAlwaysVisible()
{
return horizontalAlwaysVisible;
}
void GuiScrollView::SetHorizontalAlwaysVisible(bool value)
{
if (horizontalAlwaysVisible != value)
{
horizontalAlwaysVisible = value;
CalculateView();
}
}
bool GuiScrollView::GetVerticalAlwaysVisible()
{
return verticalAlwaysVisible;
}
void GuiScrollView::SetVerticalAlwaysVisible(bool value)
{
if (verticalAlwaysVisible != value)
{
verticalAlwaysVisible = value;
CalculateView();
}
}
/***********************************************************************
GuiScrollContainer
***********************************************************************/
Size GuiScrollContainer::QueryFullSize()
{
return containerComposition->GetCachedBounds().GetSize();
}
void GuiScrollContainer::UpdateView(Rect viewBounds)
{
auto leftTop = Point(-viewBounds.x1, -viewBounds.y1);
containerComposition->SetExpectedBounds(Rect(leftTop, Size(0, 0)));
}
GuiScrollContainer::GuiScrollContainer(theme::ThemeName themeName)
:GuiScrollView(themeName)
{
containerComposition->SetAlignmentToParent(Margin(-1, -1, -1, -1));
UpdateView(Rect(0, 0, 0, 0));
}
GuiScrollContainer::~GuiScrollContainer()
{
}
bool GuiScrollContainer::GetExtendToFullWidth()
{
return extendToFullWidth;
}
void GuiScrollContainer::SetExtendToFullWidth(bool value)
{
if (extendToFullWidth != value)
{
extendToFullWidth = value;
auto margin = containerComposition->GetAlignmentToParent();
if (value)
{
containerComposition->SetAlignmentToParent(Margin(0, margin.top, 0, margin.bottom));
}
else
{
containerComposition->SetAlignmentToParent(Margin(-1, margin.top, -1, margin.bottom));
}
}
}
bool GuiScrollContainer::GetExtendToFullHeight()
{
return extendToFullHeight;
}
void GuiScrollContainer::SetExtendToFullHeight(bool value)
{
if (extendToFullHeight != value)
{
extendToFullHeight = value;
auto margin = containerComposition->GetAlignmentToParent();
if (value)
{
containerComposition->SetAlignmentToParent(Margin(margin.left, 0, margin.right, 0));
}
else
{
containerComposition->SetAlignmentToParent(Margin(margin.left, -1, margin.right, -1));
}
}
}
}
}
}
/***********************************************************************
.\CONTROLS\GUIDATETIMECONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace collections;
using namespace compositions;
using namespace elements;
/***********************************************************************
GuiDatePicker::CommandExecutor
***********************************************************************/
GuiDatePicker::CommandExecutor::CommandExecutor(GuiDatePicker* _datePicker)
:datePicker(_datePicker)
{
}
GuiDatePicker::CommandExecutor::~CommandExecutor()
{
}
void GuiDatePicker::CommandExecutor::NotifyDateChanged()
{
datePicker->date = datePicker->TypedControlTemplateObject(true)->GetDate();
datePicker->UpdateText();
datePicker->DateChanged.Execute(datePicker->GetNotifyEventArguments());
}
void GuiDatePicker::CommandExecutor::NotifyDateNavigated()
{
datePicker->DateNavigated.Execute(datePicker->GetNotifyEventArguments());
}
void GuiDatePicker::CommandExecutor::NotifyDateSelected()
{
datePicker->DateSelected.Execute(datePicker->GetNotifyEventArguments());
}
/***********************************************************************
GuiDatePicker
***********************************************************************/
void GuiDatePicker::BeforeControlTemplateUninstalled_()
{
auto ct = TypedControlTemplateObject(false);
if (!ct) return;
ct->SetCommands(nullptr);
}
void GuiDatePicker::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
ct->SetCommands(commandExecutor.Obj());
ct->SetDate(date);
ct->SetDateLocale(dateLocale);
UpdateText();
}
void GuiDatePicker::UpdateText()
{
GuiControl::SetText(dateLocale.FormatDate(dateFormat, date));
}
bool GuiDatePicker::IsAltAvailable()
{
if (nestedAlt)
{
return alt != L"";
}
else
{
return GuiControl::IsAltAvailable();
}
}
compositions::IGuiAltActionHost* GuiDatePicker::GetActivatingAltHost()
{
if (nestedAlt)
{
return this;
}
else
{
return GuiControl::GetActivatingAltHost();
}
}
GuiDatePicker::GuiDatePicker(theme::ThemeName themeName, bool _nestedAlt)
:GuiControl(themeName)
, nestedAlt(_nestedAlt)
{
commandExecutor = Ptr(new CommandExecutor(this));
SetDate(DateTime::LocalTime());
SetDateLocale(Locale::UserDefault());
SetAltComposition(boundsComposition);
SetAltControl(this, false);
DateChanged.SetAssociatedComposition(boundsComposition);
DateNavigated.SetAssociatedComposition(boundsComposition);
DateSelected.SetAssociatedComposition(boundsComposition);
DateFormatChanged.SetAssociatedComposition(boundsComposition);
DateLocaleChanged.SetAssociatedComposition(boundsComposition);
commandExecutor->NotifyDateChanged();
}
GuiDatePicker::~GuiDatePicker()
{
}
const DateTime& GuiDatePicker::GetDate()
{
return date;
}
void GuiDatePicker::SetDate(const DateTime& value)
{
if (date != value)
{
date = value;
TypedControlTemplateObject(true)->SetDate(value);
}
}
const WString& GuiDatePicker::GetDateFormat()
{
return dateFormat;
}
void GuiDatePicker::SetDateFormat(const WString& value)
{
dateFormat=value;
UpdateText();
DateFormatChanged.Execute(GetNotifyEventArguments());
}
const Locale& GuiDatePicker::GetDateLocale()
{
return dateLocale;
}
void GuiDatePicker::SetDateLocale(const Locale& value)
{
dateLocale=value;
List<WString> formats;
dateLocale.GetLongDateFormats(formats);
if(formats.Count()>0)
{
dateFormat=formats[0];
}
TypedControlTemplateObject(true)->SetDateLocale(dateLocale);
UpdateText();
DateFormatChanged.Execute(GetNotifyEventArguments());
DateLocaleChanged.Execute(GetNotifyEventArguments());
}
void GuiDatePicker::SetText(const WString& value)
{
}
/***********************************************************************
GuiDateComboBox
***********************************************************************/
void GuiDateComboBox::BeforeControlTemplateUninstalled_()
{
}
void GuiDateComboBox::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
datePicker->SetControlTemplate(ct->GetDatePickerTemplate());
}
void GuiDateComboBox::UpdateText()
{
SetText(datePicker->GetDateLocale().FormatDate(datePicker->GetDateFormat(), selectedDate));
}
void GuiDateComboBox::NotifyUpdateSelectedDate()
{
UpdateText();
SelectedDateChanged.Execute(GetNotifyEventArguments());
}
void GuiDateComboBox::OnSubMenuOpeningChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
datePicker->SetDate(selectedDate);
}
void GuiDateComboBox::datePicker_DateLocaleChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
UpdateText();
}
void GuiDateComboBox::datePicker_DateFormatChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
UpdateText();
}
void GuiDateComboBox::datePicker_DateSelected(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
selectedDate=datePicker->GetDate();
GetSubMenu()->Hide();
NotifyUpdateSelectedDate();
}
GuiDateComboBox::GuiDateComboBox(theme::ThemeName themeName)
:GuiComboBoxBase(themeName)
{
SelectedDateChanged.SetAssociatedComposition(GetBoundsComposition());
datePicker = new GuiDatePicker(theme::ThemeName::DatePicker, false);
datePicker->DateSelected.AttachMethod(this, &GuiDateComboBox::datePicker_DateSelected);
datePicker->DateLocaleChanged.AttachMethod(this, &GuiDateComboBox::datePicker_DateLocaleChanged);
datePicker->DateFormatChanged.AttachMethod(this, &GuiDateComboBox::datePicker_DateFormatChanged);
datePicker->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
GetSubMenu()->GetContainerComposition()->AddChild(datePicker->GetBoundsComposition());
GetSubMenu()->SetHideOnDeactivateAltHost(false);
selectedDate=datePicker->GetDate();
SubMenuOpeningChanged.AttachMethod(this, &GuiDateComboBox::OnSubMenuOpeningChanged);
SetFont(GetFont());
SetText(datePicker->GetText());
}
GuiDateComboBox::~GuiDateComboBox()
{
}
void GuiDateComboBox::SetFont(const Nullable<FontProperties>& value)
{
GuiComboBoxBase::SetFont(value);
datePicker->SetFont(value);
}
const DateTime& GuiDateComboBox::GetSelectedDate()
{
return selectedDate;
}
void GuiDateComboBox::SetSelectedDate(const DateTime& value)
{
selectedDate=value;
datePicker->SetDate(selectedDate);
NotifyUpdateSelectedDate();
}
GuiDatePicker* GuiDateComboBox::GetDatePicker()
{
return datePicker;
}
}
}
}
/***********************************************************************
.\CONTROLS\GUIDIALOGS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace elements;
using namespace compositions;
using namespace collections;
using namespace reflection::description;
/***********************************************************************
GuiDialogBase
***********************************************************************/
GuiWindow* GuiDialogBase::GetHostWindow()
{
if (rootObject)
{
if (auto control = dynamic_cast<GuiControl*>(rootObject))
{
if (auto host = control->GetRelatedControlHost())
{
return dynamic_cast<GuiWindow*>(host);
}
}
else if (auto composition = dynamic_cast<GuiGraphicsComposition*>(rootObject))
{
if (auto host = composition->GetRelatedControlHost())
{
return dynamic_cast<GuiWindow*>(host);
}
}
}
return nullptr;
}
GuiDialogBase::GuiDialogBase()
{
}
GuiDialogBase::~GuiDialogBase()
{
}
void GuiDialogBase::Attach(GuiInstanceRootObject* _rootObject)
{
rootObject = _rootObject;
}
void GuiDialogBase::Detach(GuiInstanceRootObject* _rootObject)
{
rootObject = nullptr;
}
/***********************************************************************
GuiMessageDialog
***********************************************************************/
GuiMessageDialog::GuiMessageDialog()
{
}
GuiMessageDialog::~GuiMessageDialog()
{
}
INativeDialogService::MessageBoxButtonsInput GuiMessageDialog::GetInput()
{
return input;
}
void GuiMessageDialog::SetInput(INativeDialogService::MessageBoxButtonsInput value)
{
input = value;
}
INativeDialogService::MessageBoxDefaultButton GuiMessageDialog::GetDefaultButton()
{
return defaultButton;
}
void GuiMessageDialog::SetDefaultButton(INativeDialogService::MessageBoxDefaultButton value)
{
defaultButton = value;
}
INativeDialogService::MessageBoxIcons GuiMessageDialog::GetIcon()
{
return icon;
}
void GuiMessageDialog::SetIcon(INativeDialogService::MessageBoxIcons value)
{
icon = value;
}
INativeDialogService::MessageBoxModalOptions GuiMessageDialog::GetModalOption()
{
return modalOption;
}
void GuiMessageDialog::SetModalOption(INativeDialogService::MessageBoxModalOptions value)
{
modalOption = value;
}
const WString& GuiMessageDialog::GetText()
{
return text;
}
void GuiMessageDialog::SetText(const WString& value)
{
text = value;
}
const WString& GuiMessageDialog::GetTitle()
{
return title;
}
void GuiMessageDialog::SetTitle(const WString& value)
{
title = value;
}
INativeDialogService::MessageBoxButtonsOutput GuiMessageDialog::ShowDialog()
{
auto service = GetCurrentController()->DialogService();
return service->ShowMessageBox(GetHostWindow()->GetNativeWindow(), text, title, input, defaultButton, icon, modalOption);
}
/***********************************************************************
GuiColorDialog
***********************************************************************/
GuiColorDialog::GuiColorDialog()
{
for (vint i = 0; i < 16; i++)
{
customColors.Add(Color());
}
}
GuiColorDialog::~GuiColorDialog()
{
}
bool GuiColorDialog::GetEnabledCustomColor()
{
return enabledCustomColor;
}
void GuiColorDialog::SetEnabledCustomColor(bool value)
{
enabledCustomColor = value;
}
bool GuiColorDialog::GetOpenedCustomColor()
{
return openedCustomColor;
}
void GuiColorDialog::SetOpenedCustomColor(bool value)
{
openedCustomColor = value;
}
Color GuiColorDialog::GetSelectedColor()
{
return selectedColor;
}
void GuiColorDialog::SetSelectedColor(Color value)
{
if (selectedColor != value)
{
selectedColor = value;
SelectedColorChanged.Execute(GuiEventArgs());
}
}
collections::List<Color>& GuiColorDialog::GetCustomColors()
{
return customColors;
}
bool GuiColorDialog::ShowDialog()
{
Array<Color> colors;
CopyFrom(colors, customColors);
colors.Resize(16);
INativeDialogService::ColorDialogCustomColorOptions options =
!enabledCustomColor ? INativeDialogService::CustomColorDisabled :
!openedCustomColor ? INativeDialogService::CustomColorEnabled :
INativeDialogService::CustomColorOpened;
auto service = GetCurrentController()->DialogService();
if (!service->ShowColorDialog(GetHostWindow()->GetNativeWindow(), selectedColor, showSelection, options, &colors[0]))
{
return false;
}
CopyFrom(customColors, colors);
SelectedColorChanged.Execute(GuiEventArgs());
return true;
}
/***********************************************************************
GuiFontDialog
***********************************************************************/
GuiFontDialog::GuiFontDialog()
{
}
GuiFontDialog::~GuiFontDialog()
{
}
const FontProperties& GuiFontDialog::GetSelectedFont()
{
return selectedFont;
}
void GuiFontDialog::SetSelectedFont(const FontProperties& value)
{
if (selectedFont != value)
{
selectedFont = value;
SelectedFontChanged.Execute(GuiEventArgs());
}
}
Color GuiFontDialog::GetSelectedColor()
{
return selectedColor;
}
void GuiFontDialog::SetSelectedColor(Color value)
{
if (selectedColor != value)
{
selectedColor = value;
SelectedColorChanged.Execute(GuiEventArgs());
}
}
bool GuiFontDialog::GetShowSelection()
{
return showSelection;
}
void GuiFontDialog::SetShowSelection(bool value)
{
showSelection = value;
}
bool GuiFontDialog::GetShowEffect()
{
return showEffect;
}
void GuiFontDialog::SetShowEffect(bool value)
{
showEffect = value;
}
bool GuiFontDialog::GetForceFontExist()
{
return forceFontExist;
}
void GuiFontDialog::SetForceFontExist(bool value)
{
forceFontExist = value;
}
bool GuiFontDialog::ShowDialog()
{
auto service = GetCurrentController()->DialogService();
if (!service->ShowFontDialog(GetHostWindow()->GetNativeWindow(), selectedFont, selectedColor, showSelection, showEffect, forceFontExist))
{
return false;
}
SelectedColorChanged.Execute(GuiEventArgs());
SelectedFontChanged.Execute(GuiEventArgs());
return true;
}
/***********************************************************************
GuiFileDialogBase
***********************************************************************/
GuiFileDialogBase::GuiFileDialogBase()
{
}
GuiFileDialogBase::~GuiFileDialogBase()
{
}
const WString& GuiFileDialogBase::GetFilter()
{
return filter;
}
void GuiFileDialogBase::SetFilter(const WString& value)
{
filter = value;
}
vint GuiFileDialogBase::GetFilterIndex()
{
return filterIndex;
}
void GuiFileDialogBase::SetFilterIndex(vint value)
{
if (filterIndex != value)
{
filterIndex = value;
FilterIndexChanged.Execute(GuiEventArgs());
}
}
bool GuiFileDialogBase::GetEnabledPreview()
{
return enabledPreview;
}
void GuiFileDialogBase::SetEnabledPreview(bool value)
{
enabledPreview = value;
}
WString GuiFileDialogBase::GetTitle()
{
return title;
}
void GuiFileDialogBase::SetTitle(const WString& value)
{
title = value;
}
WString GuiFileDialogBase::GetFileName()
{
return fileName;
}
void GuiFileDialogBase::SetFileName(const WString& value)
{
if (fileName != value)
{
FileNameChanged.Execute(GuiEventArgs());
}
}
WString GuiFileDialogBase::GetDirectory()
{
return directory;
}
void GuiFileDialogBase::SetDirectory(const WString& value)
{
directory = value;
}
WString GuiFileDialogBase::GetDefaultExtension()
{
return defaultExtension;
}
void GuiFileDialogBase::SetDefaultExtension(const WString& value)
{
defaultExtension = value;
}
INativeDialogService::FileDialogOptions GuiFileDialogBase::GetOptions()
{
return options;
}
void GuiFileDialogBase::SetOptions(INativeDialogService::FileDialogOptions value)
{
options = value;
}
/***********************************************************************
GuiOpenFileDialog
***********************************************************************/
GuiOpenFileDialog::GuiOpenFileDialog()
{
}
GuiOpenFileDialog::~GuiOpenFileDialog()
{
}
collections::List<WString>& GuiOpenFileDialog::GetFileNames()
{
return fileNames;
}
bool GuiOpenFileDialog::ShowDialog()
{
fileNames.Clear();
auto service = GetCurrentController()->DialogService();
if (!service->ShowFileDialog(
GetHostWindow()->GetNativeWindow(),
fileNames,
filterIndex,
(enabledPreview ? INativeDialogService::FileDialogOpenPreview : INativeDialogService::FileDialogOpen),
title,
fileName,
directory,
defaultExtension,
filter,
options))
{
return false;
}
if (fileNames.Count() > 0)
{
fileName = fileNames[0];
FileNameChanged.Execute(GuiEventArgs());
FilterIndexChanged.Execute(GuiEventArgs());
}
return true;
}
/***********************************************************************
GuiSaveFileDialog
***********************************************************************/
GuiSaveFileDialog::GuiSaveFileDialog()
{
}
GuiSaveFileDialog::~GuiSaveFileDialog()
{
}
bool GuiSaveFileDialog::ShowDialog()
{
List<WString> fileNames;
auto service = GetCurrentController()->DialogService();
if (!service->ShowFileDialog(
GetHostWindow()->GetNativeWindow(),
fileNames,
filterIndex,
(enabledPreview ? INativeDialogService::FileDialogSavePreview : INativeDialogService::FileDialogSave),
title,
fileName,
directory,
defaultExtension,
filter,
options))
{
return false;
}
if (fileNames.Count() > 0)
{
fileName = fileNames[0];
FileNameChanged.Execute(GuiEventArgs());
FilterIndexChanged.Execute(GuiEventArgs());
}
return true;
}
}
}
}
/***********************************************************************
.\CONTROLS\GUISCROLLCONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace elements;
using namespace compositions;
using namespace collections;
using namespace reflection::description;
/***********************************************************************
GuiScroll::CommandExecutor
***********************************************************************/
GuiScroll::CommandExecutor::CommandExecutor(GuiScroll* _scroll)
:scroll(_scroll)
{
}
GuiScroll::CommandExecutor::~CommandExecutor()
{
}
void GuiScroll::CommandExecutor::SmallDecrease()
{
scroll->SetPosition(scroll->GetPosition()-scroll->GetSmallMove());
}
void GuiScroll::CommandExecutor::SmallIncrease()
{
scroll->SetPosition(scroll->GetPosition()+scroll->GetSmallMove());
}
void GuiScroll::CommandExecutor::BigDecrease()
{
scroll->SetPosition(scroll->GetPosition()-scroll->GetBigMove());
}
void GuiScroll::CommandExecutor::BigIncrease()
{
scroll->SetPosition(scroll->GetPosition()+scroll->GetBigMove());
}
void GuiScroll::CommandExecutor::SetTotalSize(vint value)
{
scroll->SetTotalSize(value);
}
void GuiScroll::CommandExecutor::SetPageSize(vint value)
{
scroll->SetPageSize(value);
}
void GuiScroll::CommandExecutor::SetPosition(vint value)
{
scroll->SetPosition(value);
}
/***********************************************************************
GuiScroll
***********************************************************************/
void GuiScroll::OnActiveAlt()
{
if (autoFocus)
{
GuiControl::OnActiveAlt();
}
}
bool GuiScroll::IsTabAvailable()
{
return autoFocus && GuiControl::IsTabAvailable();
}
void GuiScroll::OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments)
{
if (arguments.eventSource == focusableComposition)
{
switch (arguments.code)
{
case VKEY::KEY_HOME:
SetPosition(GetMinPosition());
arguments.handled = true;
break;
case VKEY::KEY_END:
SetPosition(GetMaxPosition());
arguments.handled = true;
break;
case VKEY::KEY_PRIOR:
commandExecutor->BigDecrease();
arguments.handled = true;
break;
case VKEY::KEY_NEXT:
commandExecutor->BigIncrease();
arguments.handled = true;
break;
case VKEY::KEY_LEFT:
case VKEY::KEY_UP:
commandExecutor->SmallDecrease();
arguments.handled = true;
break;
case VKEY::KEY_RIGHT:
case VKEY::KEY_DOWN:
commandExecutor->SmallIncrease();
arguments.handled = true;
break;
default:;
}
}
}
void GuiScroll::OnMouseDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if (autoFocus)
{
SetFocused();
}
}
void GuiScroll::BeforeControlTemplateUninstalled_()
{
auto ct = TypedControlTemplateObject(false);
if (!ct) return;
ct->SetCommands(nullptr);
}
void GuiScroll::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
ct->SetCommands(commandExecutor.Obj());
ct->SetPageSize(pageSize);
ct->SetTotalSize(totalSize);
ct->SetPosition(position);
}
GuiScroll::GuiScroll(theme::ThemeName themeName)
:GuiControl(themeName)
{
if (themeName == theme::ThemeName::ProgressBar)
{
autoFocus = false;
}
else
{
SetFocusableComposition(boundsComposition);
}
TotalSizeChanged.SetAssociatedComposition(boundsComposition);
PageSizeChanged.SetAssociatedComposition(boundsComposition);
PositionChanged.SetAssociatedComposition(boundsComposition);
SmallMoveChanged.SetAssociatedComposition(boundsComposition);
BigMoveChanged.SetAssociatedComposition(boundsComposition);
commandExecutor = Ptr(new CommandExecutor(this));
boundsComposition->GetEventReceiver()->keyDown.AttachMethod(this, &GuiScroll::OnKeyDown);
boundsComposition->GetEventReceiver()->leftButtonDown.AttachMethod(this, &GuiScroll::OnMouseDown);
boundsComposition->GetEventReceiver()->rightButtonDown.AttachMethod(this, &GuiScroll::OnMouseDown);
}
GuiScroll::~GuiScroll()
{
}
vint GuiScroll::GetTotalSize()
{
return totalSize;
}
void GuiScroll::SetTotalSize(vint value)
{
if(totalSize!=value && 0<value)
{
totalSize=value;
if(pageSize>totalSize)
{
SetPageSize(totalSize);
}
if(position>GetMaxPosition())
{
SetPosition(GetMaxPosition());
}
TypedControlTemplateObject(true)->SetTotalSize(totalSize);
TotalSizeChanged.Execute(GetNotifyEventArguments());
}
}
vint GuiScroll::GetPageSize()
{
return pageSize;
}
void GuiScroll::SetPageSize(vint value)
{
if(pageSize!=value && 0<=value && value<=totalSize)
{
pageSize=value;
if(position>GetMaxPosition())
{
SetPosition(GetMaxPosition());
}
TypedControlTemplateObject(true)->SetPageSize(pageSize);
PageSizeChanged.Execute(GetNotifyEventArguments());
}
}
vint GuiScroll::GetPosition()
{
return position;
}
void GuiScroll::SetPosition(vint value)
{
vint min=GetMinPosition();
vint max=GetMaxPosition();
vint newPosition=
value<min?min:
value>max?max:
value;
if(position!=newPosition)
{
position=newPosition;
TypedControlTemplateObject(true)->SetPosition(position);
PositionChanged.Execute(GetNotifyEventArguments());
}
}
vint GuiScroll::GetSmallMove()
{
return smallMove;
}
void GuiScroll::SetSmallMove(vint value)
{
if(value>0 && smallMove!=value)
{
smallMove=value;
SmallMoveChanged.Execute(GetNotifyEventArguments());
}
}
vint GuiScroll::GetBigMove()
{
return bigMove;
}
void GuiScroll::SetBigMove(vint value)
{
if(value>0 && bigMove!=value)
{
bigMove=value;
BigMoveChanged.Execute(GetNotifyEventArguments());
}
}
vint GuiScroll::GetMinPosition()
{
return 0;
}
vint GuiScroll::GetMaxPosition()
{
return totalSize-pageSize;
}
bool GuiScroll::GetAutoFocus()
{
return autoFocus;
}
void GuiScroll::SetAutoFocus(bool value)
{
autoFocus = value;
}
}
}
}
/***********************************************************************
.\CONTROLS\LISTCONTROLPACKAGE\DATASOURCEIMPL_IITEMPROVIDER_ITEMPROVIDERBASE.CPP
***********************************************************************/
namespace vl::presentation::controls::list
{
/***********************************************************************
ItemProviderBase
***********************************************************************/
void ItemProviderBase::InvokeOnItemModified(vint start, vint count, vint newCount, bool itemReferenceUpdated)
{
CHECK_ERROR(!callingOnItemModified, L"ItemProviderBase::InvokeOnItemModified(vint, vint, vint)#Canning modify the observable data source during its item modified event, which will cause this event to be executed recursively.");
callingOnItemModified = true;
// TODO: (enumerable) foreach
for (vint i = 0; i < callbacks.Count(); i++)
{
callbacks[i]->OnItemModified(start, count, newCount, itemReferenceUpdated);
}
callingOnItemModified = false;
}
ItemProviderBase::ItemProviderBase()
{
}
ItemProviderBase::~ItemProviderBase()
{
// TODO: (enumerable) foreach
for(vint i=0;i<callbacks.Count();i++)
{
callbacks[i]->OnAttached(0);
}
}
bool ItemProviderBase::AttachCallback(IItemProviderCallback* value)
{
if(callbacks.Contains(value))
{
return false;
}
else
{
callbacks.Add(value);
value->OnAttached(this);
return true;
}
}
bool ItemProviderBase::DetachCallback(IItemProviderCallback* value)
{
vint index=callbacks.IndexOf(value);
if(index==-1)
{
return false;
}
else
{
value->OnAttached(0);
callbacks.Remove(value);
return true;
}
}
void ItemProviderBase::PushEditing()
{
editingCounter++;
}
bool ItemProviderBase::PopEditing()
{
if (editingCounter == 0)return false;
editingCounter--;
return true;
}
bool ItemProviderBase::IsEditing()
{
return editingCounter > 0;
}
}
/***********************************************************************
.\CONTROLS\LISTCONTROLPACKAGE\DATASOURCEIMPL_IITEMPROVIDER_NODEITEMPROVIDER.CPP
***********************************************************************/
namespace vl::presentation::controls::tree
{
using namespace reflection::description;
const wchar_t* const INodeItemView::Identifier = L"vl::presentation::controls::tree::INodeItemView";
/***********************************************************************
NodeItemProvider
***********************************************************************/
Ptr<INodeProvider> NodeItemProvider::GetNodeByOffset(Ptr<INodeProvider> provider, vint offset)
{
if (offset == 0) return provider;
Ptr<INodeProvider> result;
if (provider->GetExpanding() && offset > 0)
{
offset -= 1;
vint count = provider->GetChildCount();
for (vint i = 0; (!result && i < count); i++)
{
auto child = provider->GetChild(i);
vint visibleCount = child->CalculateTotalVisibleNodes();
if (offset < visibleCount)
{
result = GetNodeByOffset(child, offset);
}
else
{
offset -= visibleCount;
}
}
}
return result;
}
void NodeItemProvider::OnAttached(INodeRootProvider* provider)
{
}
void NodeItemProvider::OnBeforeItemModified(INodeProvider* parentNode, vint start, vint count, vint newCount, bool itemReferenceUpdated)
{
vint offset = 0;
vint base = CalculateNodeVisibilityIndexInternal(parentNode);
if (base != -2 && parentNode->GetExpanding())
{
for (vint i = 0; i < count; i++)
{
auto child = parentNode->GetChild(start + i);
offset += child->CalculateTotalVisibleNodes();
}
}
offsetBeforeChildModifieds.Set(parentNode, offset);
}
void NodeItemProvider::OnAfterItemModified(INodeProvider* parentNode, vint start, vint count, vint newCount, bool itemReferenceUpdated)
{
vint offsetBeforeChildModified = 0;
{
vint index = offsetBeforeChildModifieds.Keys().IndexOf(parentNode);
if (index != -1)
{
offsetBeforeChildModified = offsetBeforeChildModifieds.Values().Get(index);
offsetBeforeChildModifieds.Remove(parentNode);
}
}
vint base = CalculateNodeVisibilityIndexInternal(parentNode);
if (base != -2 && parentNode->GetExpanding())
{
vint offset = 0;
vint firstChildStart = -1;
for (vint i = 0; i < newCount; i++)
{
auto child = parentNode->GetChild(start + i);
if (i == 0)
{
firstChildStart = CalculateNodeVisibilityIndexInternal(child.Obj());
}
offset += child->CalculateTotalVisibleNodes();
}
if (firstChildStart == -1)
{
vint childCount = parentNode->GetChildCount();
if (childCount == 0)
{
firstChildStart = base + 1;
}
else if (start < childCount)
{
auto child = parentNode->GetChild(start);
firstChildStart = CalculateNodeVisibilityIndexInternal(child.Obj());
}
else
{
auto child = parentNode->GetChild(start - 1);
firstChildStart = CalculateNodeVisibilityIndexInternal(child.Obj());
firstChildStart += child->CalculateTotalVisibleNodes();
}
}
InvokeOnItemModified(firstChildStart, offsetBeforeChildModified, offset, itemReferenceUpdated);
}
}
void NodeItemProvider::OnItemExpanded(INodeProvider* node)
{
vint base = CalculateNodeVisibilityIndexInternal(node);
if (base != -2)
{
vint visibility = node->CalculateTotalVisibleNodes();
InvokeOnItemModified(base + 1, 0, visibility - 1, true);
}
}
void NodeItemProvider::OnItemCollapsed(INodeProvider* node)
{
vint base = CalculateNodeVisibilityIndexInternal(node);
if (base != -2)
{
vint visibility = 0;
vint count = node->GetChildCount();
for (vint i = 0; i < count; i++)
{
auto child = node->GetChild(i);
visibility += child->CalculateTotalVisibleNodes();
}
InvokeOnItemModified(base + 1, visibility, 0, true);
}
}
vint NodeItemProvider::CalculateNodeVisibilityIndexInternal(INodeProvider* node)
{
auto parent = node->GetParent();
if (!parent)
{
return -1;
}
if (!parent->GetExpanding())
{
return -2;
}
vint index = CalculateNodeVisibilityIndexInternal(parent.Obj());
if (index == -2)
{
return -2;
}
vint count = parent->GetChildCount();
for (vint i = 0; i < count; i++)
{
auto child = parent->GetChild(i);
bool findResult = child == node;
if (findResult)
{
index++;
}
else
{
index += child->CalculateTotalVisibleNodes();
}
if (findResult)
{
return index;
}
}
return -1;
}
vint NodeItemProvider::CalculateNodeVisibilityIndex(INodeProvider* node)
{
vint result = CalculateNodeVisibilityIndexInternal(node);
return result < 0 ? -1 : result;
}
Ptr<INodeProvider> NodeItemProvider::RequestNode(vint index)
{
if(root->CanGetNodeByVisibleIndex())
{
return root->GetNodeByVisibleIndex(index+1);
}
else
{
return GetNodeByOffset(root->GetRootNode(), index+1);
}
}
NodeItemProvider::NodeItemProvider(Ptr<INodeRootProvider> _root)
:root(_root)
{
root->AttachCallback(this);
}
NodeItemProvider::~NodeItemProvider()
{
root->DetachCallback(this);
}
Ptr<INodeRootProvider> NodeItemProvider::GetRoot()
{
return root;
}
vint NodeItemProvider::Count()
{
return root->GetRootNode()->CalculateTotalVisibleNodes()-1;
}
WString NodeItemProvider::GetTextValue(vint itemIndex)
{
if (auto node = RequestNode(itemIndex))
{
return root->GetTextValue(node.Obj());
}
return L"";
}
description::Value NodeItemProvider::GetBindingValue(vint itemIndex)
{
if (auto node = RequestNode(itemIndex))
{
return root->GetBindingValue(node.Obj());
}
return Value();
}
IDescriptable* NodeItemProvider::RequestView(const WString& identifier)
{
if(identifier==INodeItemView::Identifier)
{
return (INodeItemView*)this;
}
else
{
return root->RequestView(identifier);
}
}
}
/***********************************************************************
.\CONTROLS\LISTCONTROLPACKAGE\DATASOURCEIMPL_INODEPROVIDER_MEMORYNODEPROVIDER.CPP
***********************************************************************/
namespace vl::presentation::controls::tree
{
/***********************************************************************
MemoryNodeProvider::NodeCollection
***********************************************************************/
void MemoryNodeProvider::NodeCollection::OnBeforeChildModified(vint start, vint count, vint newCount)
{
if (ownerProvider->expanding)
{
for (vint i = 0; i < count; i++)
{
offsetBeforeChildModified += items[start + i]->totalVisibleNodeCount;
}
}
INodeProviderCallback* proxy = ownerProvider->GetCallbackProxyInternal();
if (proxy)
{
proxy->OnBeforeItemModified(ownerProvider, start, count, newCount, true);
}
}
void MemoryNodeProvider::NodeCollection::OnAfterChildModified(vint start, vint count, vint newCount)
{
ownerProvider->childCount += (newCount - count);
if (ownerProvider->expanding)
{
vint offset = 0;
for (vint i = 0; i < newCount; i++)
{
offset += items[start + i]->totalVisibleNodeCount;
}
ownerProvider->OnChildTotalVisibleNodesChanged(offset - offsetBeforeChildModified);
}
offsetBeforeChildModified = 0;
INodeProviderCallback* proxy = ownerProvider->GetCallbackProxyInternal();
if (proxy)
{
proxy->OnAfterItemModified(ownerProvider, start, count, newCount, true);
}
}
bool MemoryNodeProvider::NodeCollection::QueryInsert(vint index, Ptr<MemoryNodeProvider> const& child)
{
return child->parent == 0;
}
bool MemoryNodeProvider::NodeCollection::QueryRemove(vint index, Ptr<MemoryNodeProvider> const& child)
{
return child->parent == ownerProvider;
}
void MemoryNodeProvider::NodeCollection::BeforeInsert(vint index, Ptr<MemoryNodeProvider> const& child)
{
OnBeforeChildModified(index, 0, 1);
child->parent = ownerProvider;
}
void MemoryNodeProvider::NodeCollection::BeforeRemove(vint index, Ptr<MemoryNodeProvider> const& child)
{
OnBeforeChildModified(index, 1, 0);
child->parent = 0;
}
void MemoryNodeProvider::NodeCollection::AfterInsert(vint index, Ptr<MemoryNodeProvider> const& child)
{
OnAfterChildModified(index, 0, 1);
}
void MemoryNodeProvider::NodeCollection::AfterRemove(vint index, vint count)
{
OnAfterChildModified(index, count, 0);
}
MemoryNodeProvider::NodeCollection::NodeCollection()
:ownerProvider(0)
{
}
/***********************************************************************
MemoryNodeProvider
***********************************************************************/
INodeProviderCallback* MemoryNodeProvider::GetCallbackProxyInternal()
{
if(parent)
{
return parent->GetCallbackProxyInternal();
}
else
{
return 0;
}
}
void MemoryNodeProvider::OnChildTotalVisibleNodesChanged(vint offset)
{
totalVisibleNodeCount+=offset;
if(parent)
{
parent->OnChildTotalVisibleNodesChanged(offset);
}
}
MemoryNodeProvider::MemoryNodeProvider(Ptr<DescriptableObject> _data)
:data(_data)
{
children.ownerProvider=this;
}
MemoryNodeProvider::~MemoryNodeProvider()
{
}
Ptr<DescriptableObject> MemoryNodeProvider::GetData()
{
return data;
}
void MemoryNodeProvider::SetData(const Ptr<DescriptableObject>& value)
{
data=value;
NotifyDataModified();
}
MemoryNodeProvider::NodeCollection& MemoryNodeProvider::Children()
{
return children;
}
bool MemoryNodeProvider::GetExpanding()
{
return expanding;
}
void MemoryNodeProvider::SetExpanding(bool value)
{
if(expanding!=value)
{
expanding=value;
vint offset=0;
for(vint i=0;i<childCount;i++)
{
offset+=children[i]->totalVisibleNodeCount;
}
OnChildTotalVisibleNodesChanged(expanding?offset:-offset);
INodeProviderCallback* proxy=GetCallbackProxyInternal();
if(proxy)
{
if(expanding)
{
proxy->OnItemExpanded(this);
}
else
{
proxy->OnItemCollapsed(this);
}
}
}
}
vint MemoryNodeProvider::CalculateTotalVisibleNodes()
{
return totalVisibleNodeCount;
}
void MemoryNodeProvider::NotifyDataModified()
{
if (parent)
{
vint index = parent->children.IndexOf(this);
INodeProviderCallback* proxy = GetCallbackProxyInternal();
if (proxy)
{
proxy->OnBeforeItemModified(parent, index, 1, 1, false);
proxy->OnAfterItemModified(parent, index, 1, 1, false);
}
}
}
vint MemoryNodeProvider::GetChildCount()
{
return childCount;
}
Ptr<INodeProvider> MemoryNodeProvider::GetParent()
{
return Ptr(parent);
}
Ptr<INodeProvider> MemoryNodeProvider::GetChild(vint index)
{
if (0 <= index && index < childCount)
{
return children[index];
}
else
{
return nullptr;
}
}
/***********************************************************************
NodeRootProviderBase
***********************************************************************/
void NodeRootProviderBase::OnAttached(INodeRootProvider* provider)
{
}
void NodeRootProviderBase::OnBeforeItemModified(INodeProvider* parentNode, vint start, vint count, vint newCount, bool itemReferenceUpdated)
{
// TODO: (enumerable) foreach
for(vint i=0;i<callbacks.Count();i++)
{
callbacks[i]->OnBeforeItemModified(parentNode, start, count, newCount, itemReferenceUpdated);
}
}
void NodeRootProviderBase::OnAfterItemModified(INodeProvider* parentNode, vint start, vint count, vint newCount, bool itemReferenceUpdated)
{
// TODO: (enumerable) foreach
for(vint i=0;i<callbacks.Count();i++)
{
callbacks[i]->OnAfterItemModified(parentNode, start, count, newCount, itemReferenceUpdated);
}
}
void NodeRootProviderBase::OnItemExpanded(INodeProvider* node)
{
// TODO: (enumerable) foreach
for(vint i=0;i<callbacks.Count();i++)
{
callbacks[i]->OnItemExpanded(node);
}
}
void NodeRootProviderBase::OnItemCollapsed(INodeProvider* node)
{
// TODO: (enumerable) foreach
for(vint i=0;i<callbacks.Count();i++)
{
callbacks[i]->OnItemCollapsed(node);
}
}
NodeRootProviderBase::NodeRootProviderBase()
{
}
NodeRootProviderBase::~NodeRootProviderBase()
{
}
bool NodeRootProviderBase::CanGetNodeByVisibleIndex()
{
return false;
}
Ptr<INodeProvider> NodeRootProviderBase::GetNodeByVisibleIndex(vint index)
{
return nullptr;
}
bool NodeRootProviderBase::AttachCallback(INodeProviderCallback* value)
{
if(callbacks.Contains(value))
{
return false;
}
else
{
callbacks.Add(value);
value->OnAttached(this);
return true;
}
}
bool NodeRootProviderBase::DetachCallback(INodeProviderCallback* value)
{
vint index=callbacks.IndexOf(value);
if(index==-1)
{
return false;
}
else
{
value->OnAttached(0);
callbacks.Remove(value);
return true;
}
}
IDescriptable* NodeRootProviderBase::RequestView(const WString& identifier)
{
return 0;
}
/***********************************************************************
MemoryNodeRootProvider
***********************************************************************/
INodeProviderCallback* MemoryNodeRootProvider::GetCallbackProxyInternal()
{
return this;
}
MemoryNodeRootProvider::MemoryNodeRootProvider()
{
SetExpanding(true);
}
MemoryNodeRootProvider::~MemoryNodeRootProvider()
{
}
Ptr<INodeProvider> MemoryNodeRootProvider::GetRootNode()
{
return Ptr(this);
}
MemoryNodeProvider* MemoryNodeRootProvider::GetMemoryNode(INodeProvider* node)
{
return dynamic_cast<MemoryNodeProvider*>(node);
}
}
/***********************************************************************
.\CONTROLS\LISTCONTROLPACKAGE\GUIBINDABLEDATAGRID.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace collections;
using namespace description;
using namespace templates;
namespace list
{
/***********************************************************************
DataFilterBase
***********************************************************************/
void DataFilterBase::InvokeOnProcessorChanged()
{
if (callback)
{
callback->OnProcessorChanged();
}
}
DataFilterBase::DataFilterBase()
{
}
void DataFilterBase::SetCallback(IDataProcessorCallback* value)
{
callback = value;
}
/***********************************************************************
DataMultipleFilter
***********************************************************************/
DataMultipleFilter::DataMultipleFilter()
{
}
bool DataMultipleFilter::AddSubFilter(Ptr<IDataFilter> value)
{
if (!value) return false;
if (filters.Contains(value.Obj())) return false;
filters.Add(value);
value->SetCallback(callback);
InvokeOnProcessorChanged();
return true;
}
bool DataMultipleFilter::RemoveSubFilter(Ptr<IDataFilter> value)
{
if (!value) return false;
if (!filters.Contains(value.Obj())) return false;
value->SetCallback(nullptr);
filters.Remove(value.Obj());
InvokeOnProcessorChanged();
return true;
}
void DataMultipleFilter::SetCallback(IDataProcessorCallback* value)
{
DataFilterBase::SetCallback(value);
// TODO: (enumerable) foreach
for (vint i = 0; i < filters.Count(); i++)
{
filters[i]->SetCallback(value);
}
}
/***********************************************************************
DataAndFilter
***********************************************************************/
DataAndFilter::DataAndFilter()
{
}
bool DataAndFilter::Filter(const description::Value& row)
{
return From(filters)
.All([row](Ptr<IDataFilter> filter)
{
return filter->Filter(row);
});
}
/***********************************************************************
DataOrFilter
***********************************************************************/
DataOrFilter::DataOrFilter()
{
}
bool DataOrFilter::Filter(const description::Value& row)
{
return From(filters)
.Any([row](Ptr<IDataFilter> filter)
{
return filter->Filter(row);
});
}
/***********************************************************************
DataNotFilter
***********************************************************************/
DataNotFilter::DataNotFilter()
{
}
bool DataNotFilter::SetSubFilter(Ptr<IDataFilter> value)
{
if (filter == value) return false;
if (filter) filter->SetCallback(nullptr);
filter = value;
if (filter) filter->SetCallback(callback);
InvokeOnProcessorChanged();
return true;
}
void DataNotFilter::SetCallback(IDataProcessorCallback* value)
{
DataFilterBase::SetCallback(value);
if (filter) filter->SetCallback(value);
}
bool DataNotFilter::Filter(const description::Value& row)
{
return filter ? true : !filter->Filter(row);
}
/***********************************************************************
DataSorterBase
***********************************************************************/
void DataSorterBase::InvokeOnProcessorChanged()
{
if (callback)
{
callback->OnProcessorChanged();
}
}
DataSorterBase::DataSorterBase()
{
}
void DataSorterBase::SetCallback(IDataProcessorCallback* value)
{
callback = value;
}
/***********************************************************************
DataMultipleSorter
***********************************************************************/
DataMultipleSorter::DataMultipleSorter()
{
}
bool DataMultipleSorter::SetLeftSorter(Ptr<IDataSorter> value)
{
if (leftSorter == value) return false;
if (leftSorter) leftSorter->SetCallback(nullptr);
leftSorter = value;
if (leftSorter) leftSorter->SetCallback(callback);
return true;
}
bool DataMultipleSorter::SetRightSorter(Ptr<IDataSorter> value)
{
if (rightSorter == value) return false;
if (rightSorter) rightSorter->SetCallback(nullptr);
rightSorter = value;
if (rightSorter) rightSorter->SetCallback(callback);
return true;
}
void DataMultipleSorter::SetCallback(IDataProcessorCallback* value)
{
DataSorterBase::SetCallback(value);
if (leftSorter) leftSorter->SetCallback(value);
if (rightSorter) rightSorter->SetCallback(value);
}
vint DataMultipleSorter::Compare(const description::Value& row1, const description::Value& row2)
{
if (leftSorter)
{
vint result = leftSorter->Compare(row1, row2);
if (result != 0) return result;
}
if (rightSorter)
{
vint result = rightSorter->Compare(row1, row2);
if (result != 0) return result;
}
return 0;
}
/***********************************************************************
DataReverseSorter
***********************************************************************/
DataReverseSorter::DataReverseSorter()
{
}
bool DataReverseSorter::SetSubSorter(Ptr<IDataSorter> value)
{
if (sorter == value) return false;
if (sorter) sorter->SetCallback(nullptr);
sorter = value;
if (sorter) sorter->SetCallback(callback);
return true;
}
void DataReverseSorter::SetCallback(IDataProcessorCallback* value)
{
DataSorterBase::SetCallback(value);
if (sorter) sorter->SetCallback(value);
}
vint DataReverseSorter::Compare(const description::Value& row1, const description::Value& row2)
{
return sorter ? -sorter->Compare(row1, row2) : 0;
}
/***********************************************************************
DataColumn
***********************************************************************/
void DataColumn::NotifyRebuilt()
{
if (dataProvider)
{
vint index = dataProvider->columns.IndexOf(this);
if (index != -1)
{
dataProvider->columns.NotifyColumnRebuilt(index);
}
}
}
void DataColumn::NotifyChanged(bool needToRefreshItems)
{
if (dataProvider)
{
vint index = dataProvider->columns.IndexOf(this);
if (index != -1)
{
dataProvider->columns.NotifyColumnChanged(index, needToRefreshItems);
}
}
}
DataColumn::DataColumn()
{
}
DataColumn::~DataColumn()
{
if (popup && ownPopup)
{
SafeDeleteControl(popup);
}
}
WString DataColumn::GetText()
{
return text;
}
void DataColumn::SetText(const WString& value)
{
if (text != value)
{
text = value;
NotifyChanged(false);
}
}
vint DataColumn::GetSize()
{
return size;
}
void DataColumn::SetSize(vint value)
{
if (size != value)
{
size = value;
NotifyChanged(true);
}
}
bool DataColumn::GetOwnPopup()
{
return ownPopup;
}
void DataColumn::SetOwnPopup(bool value)
{
ownPopup = value;
}
GuiMenu* DataColumn::GetPopup()
{
return popup;
}
void DataColumn::SetPopup(GuiMenu* value)
{
if (popup != value)
{
popup = value;
NotifyChanged(false);
}
}
Ptr<IDataFilter> DataColumn::GetFilter()
{
return associatedFilter;
}
void DataColumn::SetFilter(Ptr<IDataFilter> value)
{
if (associatedFilter != value)
{
if (associatedFilter) associatedFilter->SetCallback(nullptr);
associatedFilter = value;
if (associatedFilter) associatedFilter->SetCallback(dataProvider);
if (dataProvider)
{
vint index = dataProvider->columns.IndexOf(this);
if (index != -1)
{
dataProvider->OnProcessorChanged();
return;
}
}
NotifyChanged(false);
}
}
Ptr<IDataSorter> DataColumn::GetSorter()
{
return associatedSorter;
}
void DataColumn::SetSorter(Ptr<IDataSorter> value)
{
if (associatedSorter != value)
{
if (associatedSorter) associatedSorter->SetCallback(nullptr);
associatedSorter = value;
if (associatedSorter) associatedSorter->SetCallback(dataProvider);
if (dataProvider)
{
vint index = dataProvider->columns.IndexOf(this);
if (index == dataProvider->GetSortedColumn())
{
dataProvider->SortByColumn(index, sortingState == ColumnSortingState::Ascending);
return;
}
}
NotifyChanged(false);
}
}
Ptr<IDataVisualizerFactory> DataColumn::GetVisualizerFactory()
{
return visualizerFactory;
}
void DataColumn::SetVisualizerFactory(Ptr<IDataVisualizerFactory> value)
{
visualizerFactory = value;
NotifyRebuilt();
}
Ptr<IDataEditorFactory> DataColumn::GetEditorFactory()
{
return editorFactory;
}
void DataColumn::SetEditorFactory(Ptr<IDataEditorFactory> value)
{
editorFactory = value;
NotifyRebuilt();
}
WString DataColumn::GetCellText(vint row)
{
if (0 <= row && row < dataProvider->Count())
{
return ReadProperty(dataProvider->GetBindingValue(row), textProperty);
}
return L"";
}
description::Value DataColumn::GetCellValue(vint row)
{
if (0 <= row && row < dataProvider->Count())
{
return ReadProperty(dataProvider->GetBindingValue(row), valueProperty);
}
return Value();
}
void DataColumn::SetCellValue(vint row, description::Value value)
{
if (0 <= row && row < dataProvider->Count())
{
auto rowValue = dataProvider->GetBindingValue(row);
WriteProperty(rowValue, valueProperty, value);
dataProvider->InvokeOnItemModified(row, 1, 1, false);
}
}
ItemProperty<WString> DataColumn::GetTextProperty()
{
return textProperty;
}
void DataColumn::SetTextProperty(const ItemProperty<WString>& value)
{
if (textProperty != value)
{
textProperty = value;
NotifyRebuilt();
compositions::GuiEventArgs arguments;
TextPropertyChanged.Execute(arguments);
}
}
WritableItemProperty<description::Value> DataColumn::GetValueProperty()
{
return valueProperty;
}
void DataColumn::SetValueProperty(const WritableItemProperty<description::Value>& value)
{
if (valueProperty != value)
{
valueProperty = value;
NotifyRebuilt();
compositions::GuiEventArgs arguments;
ValuePropertyChanged.Execute(arguments);
}
}
/***********************************************************************
DataColumns
***********************************************************************/
void DataColumns::NotifyColumnRebuilt(vint column)
{
NotifyUpdate(column, 1);
}
void DataColumns::NotifyColumnChanged(vint column, bool needToRefreshItems)
{
dataProvider->NotifyColumnChanged();
}
void DataColumns::NotifyUpdateInternal(vint start, vint count, vint newCount)
{
dataProvider->NotifyColumnRebuilt();
}
bool DataColumns::QueryInsert(vint index, const Ptr<DataColumn>& value)
{
return !items.Contains(value.Obj());
}
void DataColumns::AfterInsert(vint index, const Ptr<DataColumn>& value)
{
value->dataProvider = dataProvider;
}
void DataColumns::BeforeRemove(vint index, const Ptr<DataColumn>& value)
{
value->dataProvider = nullptr;
}
DataColumns::DataColumns(DataProvider* _dataProvider)
:dataProvider(_dataProvider)
{
}
DataColumns::~DataColumns()
{
}
/***********************************************************************
DataProvider
***********************************************************************/
bool DataProvider::NotifyUpdate(vint start, vint count, bool itemReferenceUpdated)
{
if (!itemSource) return false;
if (start<0 || start >= itemSource->GetCount() || count <= 0 || start + count > itemSource->GetCount())
{
return false;
}
else
{
InvokeOnItemModified(start, count, count, itemReferenceUpdated);
return true;
}
}
void DataProvider::RebuildAllItems()
{
NotifyUpdate(0, Count(), true);
}
void DataProvider::RefreshAllItems()
{
NotifyUpdate(0, Count(), false);
}
void DataProvider::NotifyColumnRebuilt()
{
for (auto callback : columnItemViewCallbacks)
{
callback->OnColumnRebuilt();
}
RefreshAllItems();
}
void DataProvider::NotifyColumnChanged()
{
for (auto callback : columnItemViewCallbacks)
{
callback->OnColumnChanged(true);
}
RefreshAllItems();
}
list::IItemProvider* DataProvider::GetItemProvider()
{
return this;
}
void DataProvider::OnProcessorChanged()
{
RebuildFilter();
ReorderRows(true);
}
void DataProvider::OnItemSourceModified(vint start, vint count, vint newCount)
{
if (!currentSorter && !currentFilter && count == newCount)
{
InvokeOnItemModified(start, count, newCount, true);
}
else
{
ReorderRows(true);
}
}
ListViewDataColumns& DataProvider::GetDataColumns()
{
return dataColumns;
}
DataColumns& DataProvider::GetColumns()
{
return columns;
}
Ptr<description::IValueEnumerable> DataProvider::GetItemSource()
{
return itemSource;
}
void DataProvider::SetItemSource(Ptr<description::IValueEnumerable> _itemSource)
{
vint oldCount = 0;
if (itemSource)
{
oldCount = itemSource->GetCount();
}
if (itemChangedEventHandler)
{
auto ol = itemSource.Cast<IValueObservableList>();
ol->ItemChanged.Remove(itemChangedEventHandler);
}
itemSource = nullptr;
itemChangedEventHandler = nullptr;
if (_itemSource)
{
if (auto ol = _itemSource.Cast<IValueObservableList>())
{
itemSource = ol;
itemChangedEventHandler = ol->ItemChanged.Add([this](vint start, vint oldCount, vint newCount)
{
OnItemSourceModified(start, oldCount, newCount);
});
}
else if (auto rl = _itemSource.Cast<IValueReadonlyList>())
{
itemSource = rl;
}
else
{
itemSource = IValueList::Create(GetLazyList<Value>(_itemSource));
}
}
OnItemSourceModified(0, oldCount, itemSource ? itemSource->GetCount() : 0);
}
void DataProvider::RebuildFilter()
{
if (currentFilter)
{
currentFilter->SetCallback(nullptr);
currentFilter = nullptr;
}
List<Ptr<IDataFilter>> selectedFilters;
CopyFrom(
selectedFilters,
From(columns)
.Select([](Ptr<DataColumn> column) {return column->GetFilter(); })
.Where([](Ptr<IDataFilter> filter) {return filter != nullptr; })
);
if (additionalFilter)
{
selectedFilters.Add(additionalFilter);
}
if (selectedFilters.Count() > 0)
{
auto andFilter = Ptr(new DataAndFilter);
for (auto filter : selectedFilters)
{
andFilter->AddSubFilter(filter);
}
currentFilter = andFilter;
}
if (currentFilter)
{
currentFilter->SetCallback(this);
}
}
void DataProvider::ReorderRows(bool invokeCallback)
{
vint oldRowCount = Count();
vint rowCount = itemSource ? itemSource->GetCount() : 0;
virtualRowToSourceRow = nullptr;
if (currentFilter)
{
virtualRowToSourceRow = Ptr(new List<vint>);
for (vint i = 0; i < rowCount; i++)
{
if (currentFilter->Filter(itemSource->Get(i)))
{
virtualRowToSourceRow->Add(i);
}
}
}
else if (currentSorter)
{
virtualRowToSourceRow = Ptr(new List<vint>);
for (vint i = 0; i < rowCount; i++)
{
virtualRowToSourceRow->Add(i);
}
}
if (currentSorter && virtualRowToSourceRow->Count() > 0)
{
IDataSorter* sorter = currentSorter.Obj();
SortLambda(
&virtualRowToSourceRow->operator[](0),
virtualRowToSourceRow->Count(),
[=](vint a, vint b)
{
auto ordering = sorter->Compare(itemSource->Get(a), itemSource->Get(b)) <=> 0;
return ordering == 0 ? a <=> b : ordering;
});
}
if (invokeCallback)
{
vint newRowCount = Count();
InvokeOnItemModified(0, oldRowCount, newRowCount, true);
}
}
DataProvider::DataProvider()
:dataColumns(this)
, columns(this)
{
RebuildFilter();
ReorderRows(false);
}
DataProvider::~DataProvider()
{
if (itemChangedEventHandler)
{
auto ol = itemSource.Cast<IValueObservableList>();
ol->ItemChanged.Remove(itemChangedEventHandler);
}
}
Ptr<IDataFilter> DataProvider::GetAdditionalFilter()
{
return additionalFilter;
}
void DataProvider::SetAdditionalFilter(Ptr<IDataFilter> value)
{
additionalFilter = value;
OnProcessorChanged();
}
// ===================== GuiListControl::IItemProvider =====================
vint DataProvider::Count()
{
if (itemSource)
{
if (virtualRowToSourceRow)
{
return virtualRowToSourceRow->Count();
}
else
{
return itemSource->GetCount();
}
}
else
{
return 0;
}
}
WString DataProvider::GetTextValue(vint itemIndex)
{
return GetText(itemIndex);
}
description::Value DataProvider::GetBindingValue(vint itemIndex)
{
if (itemSource)
{
if (virtualRowToSourceRow)
{
return itemSource->Get(virtualRowToSourceRow->Get(itemIndex));
}
else
{
return itemSource->Get(itemIndex);
}
}
else
{
return Value();
}
}
IDescriptable* DataProvider::RequestView(const WString& identifier)
{
if (identifier == IListViewItemView::Identifier)
{
return (IListViewItemView*)this;
}
else if (identifier == ListViewColumnItemArranger::IColumnItemView::Identifier)
{
return (ListViewColumnItemArranger::IColumnItemView*)this;
}
else if (identifier == IDataGridView::Identifier)
{
return (IDataGridView*)this;
}
else
{
return nullptr;
}
}
// ===================== list::IListViewItemProvider =====================
Ptr<GuiImageData> DataProvider::GetSmallImage(vint itemIndex)
{
if (0 <= itemIndex && itemIndex < Count())
{
return ReadProperty(GetBindingValue(itemIndex), smallImageProperty);
}
return nullptr;
}
Ptr<GuiImageData> DataProvider::GetLargeImage(vint itemIndex)
{
if (0 <= itemIndex && itemIndex < Count())
{
return ReadProperty(GetBindingValue(itemIndex), largeImageProperty);
}
return nullptr;
}
WString DataProvider::GetText(vint itemIndex)
{
if (columns.Count() == 0)return L"";
return columns[0]->GetCellText(itemIndex);
}
WString DataProvider::GetSubItem(vint itemIndex, vint index)
{
return columns[index + 1]->GetCellText(itemIndex);
}
vint DataProvider::GetDataColumnCount()
{
return dataColumns.Count();
}
vint DataProvider::GetDataColumn(vint index)
{
return dataColumns[index];
}
vint DataProvider::GetColumnCount()
{
return columns.Count();
}
WString DataProvider::GetColumnText(vint index)
{
return columns[index]->GetText();
}
// ===================== list::ListViewColumnItemArranger::IColumnItemView =====================
bool DataProvider::AttachCallback(ListViewColumnItemArranger::IColumnItemViewCallback* value)
{
if (columnItemViewCallbacks.Contains(value))
{
return false;
}
else
{
columnItemViewCallbacks.Add(value);
return true;
}
}
bool DataProvider::DetachCallback(ListViewColumnItemArranger::IColumnItemViewCallback* value)
{
vint index = columnItemViewCallbacks.IndexOf(value);
if (index == -1)
{
return false;
}
else
{
columnItemViewCallbacks.Remove(value);
return true;
}
}
vint DataProvider::GetColumnSize(vint index)
{
return columns[index]->GetSize();
}
void DataProvider::SetColumnSize(vint index, vint value)
{
columns[index]->SetSize(value);
}
GuiMenu* DataProvider::GetDropdownPopup(vint index)
{
return columns[index]->GetPopup();
}
ColumnSortingState DataProvider::GetSortingState(vint index)
{
return columns[index]->sortingState;
}
// ===================== list::IDataGridView =====================
bool DataProvider::IsColumnSortable(vint column)
{
return columns[column]->GetSorter();
}
void DataProvider::SortByColumn(vint column, bool ascending)
{
if (0 <= column && column < columns.Count())
{
auto sorter = columns[column]->GetSorter();
if (!sorter)
{
currentSorter = nullptr;
}
else if (ascending)
{
currentSorter = sorter;
}
else
{
auto reverseSorter = Ptr(new DataReverseSorter);
reverseSorter->SetSubSorter(sorter);
currentSorter = reverseSorter;
}
}
else
{
currentSorter = nullptr;
}
// TODO: (enumerable) foreach:indexed
for (vint i = 0; i < columns.Count(); i++)
{
columns[i]->sortingState =
i != column ? ColumnSortingState::NotSorted :
ascending ? ColumnSortingState::Ascending :
ColumnSortingState::Descending
;
}
NotifyColumnChanged();
ReorderRows(true);
}
vint DataProvider::GetSortedColumn()
{
// TODO: (enumerable) foreach:indexed
for (vint i = 0; i < columns.Count(); i++)
{
auto state = columns[i]->sortingState;
if (state != ColumnSortingState::NotSorted)
{
return i;
}
}
return -1;
}
bool DataProvider::IsSortOrderAscending()
{
// TODO: (enumerable) foreach
for (vint i = 0; i < columns.Count(); i++)
{
auto state = columns[i]->sortingState;
if (state != ColumnSortingState::NotSorted)
{
return state == ColumnSortingState::Ascending;
}
}
return true;
}
vint DataProvider::GetCellSpan(vint row, vint column)
{
return 1;
}
IDataVisualizerFactory* DataProvider::GetCellDataVisualizerFactory(vint row, vint column)
{
return columns[column]->GetVisualizerFactory().Obj();
}
IDataEditorFactory* DataProvider::GetCellDataEditorFactory(vint row, vint column)
{
return columns[column]->GetEditorFactory().Obj();
}
description::Value DataProvider::GetBindingCellValue(vint row, vint column)
{
return columns[column]->GetCellValue(row);
}
void DataProvider::SetBindingCellValue(vint row, vint column, const description::Value& value)
{
columns[column]->SetCellValue(row, value);
}
}
/***********************************************************************
GuiBindableDataGrid
***********************************************************************/
GuiBindableDataGrid::GuiBindableDataGrid(theme::ThemeName themeName)
:GuiVirtualDataGrid(themeName, new list::DataProvider)
{
dataProvider = dynamic_cast<list::DataProvider*>(GetItemProvider());
}
GuiBindableDataGrid::~GuiBindableDataGrid()
{
}
list::ListViewDataColumns& GuiBindableDataGrid::GetDataColumns()
{
return dataProvider->GetDataColumns();
}
list::DataColumns& GuiBindableDataGrid::GetColumns()
{
return dataProvider->GetColumns();
}
Ptr<description::IValueEnumerable> GuiBindableDataGrid::GetItemSource()
{
return dataProvider->GetItemSource();
}
void GuiBindableDataGrid::SetItemSource(Ptr<description::IValueEnumerable> _itemSource)
{
dataProvider->SetItemSource(_itemSource);
}
Ptr<list::IDataFilter> GuiBindableDataGrid::GetAdditionalFilter()
{
return dataProvider->GetAdditionalFilter();
}
void GuiBindableDataGrid::SetAdditionalFilter(Ptr<list::IDataFilter> value)
{
dataProvider->SetAdditionalFilter(value);
}
ItemProperty<Ptr<GuiImageData>> GuiBindableDataGrid::GetLargeImageProperty()
{
return dataProvider->largeImageProperty;
}
void GuiBindableDataGrid::SetLargeImageProperty(const ItemProperty<Ptr<GuiImageData>>& value)
{
if (dataProvider->largeImageProperty != value)
{
dataProvider->largeImageProperty = value;
dataProvider->RefreshAllItems();
LargeImagePropertyChanged.Execute(GetNotifyEventArguments());
}
}
ItemProperty<Ptr<GuiImageData>> GuiBindableDataGrid::GetSmallImageProperty()
{
return dataProvider->smallImageProperty;
}
void GuiBindableDataGrid::SetSmallImageProperty(const ItemProperty<Ptr<GuiImageData>>& value)
{
if (dataProvider->smallImageProperty != value)
{
dataProvider->smallImageProperty = value;
dataProvider->RefreshAllItems();
SmallImagePropertyChanged.Execute(GetNotifyEventArguments());
}
}
description::Value GuiBindableDataGrid::GetSelectedRowValue()
{
auto pos = GetSelectedCell();
if (pos.row == -1 || pos.column == -1)
{
return Value();
}
return dataProvider->GetBindingValue(GetSelectedCell().row);
}
description::Value GuiBindableDataGrid::GetSelectedCellValue()
{
auto pos = GetSelectedCell();
if (pos.row == -1 || pos.column == -1)
{
return Value();
}
return dataProvider->GetColumns()[pos.column]->GetCellValue(pos.row);
}
bool GuiBindableDataGrid::NotifyItemDataModified(vint start, vint count)
{
StopEdit();
return dataProvider->NotifyUpdate(start, count, false);
}
}
}
}
/***********************************************************************
.\CONTROLS\LISTCONTROLPACKAGE\GUIBINDABLELISTCONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace collections;
using namespace list;
using namespace tree;
using namespace reflection::description;
using namespace templates;
/***********************************************************************
GuiBindableTextList::ItemSource
***********************************************************************/
GuiBindableTextList::ItemSource::ItemSource()
{
}
GuiBindableTextList::ItemSource::~ItemSource()
{
if (itemChangedEventHandler)
{
auto ol = itemSource.Cast<IValueObservableList>();
ol->ItemChanged.Remove(itemChangedEventHandler);
}
}
Ptr<description::IValueEnumerable> GuiBindableTextList::ItemSource::GetItemSource()
{
return itemSource;
}
void GuiBindableTextList::ItemSource::SetItemSource(Ptr<description::IValueEnumerable> _itemSource)
{
vint oldCount = 0;
if (itemSource)
{
oldCount = itemSource->GetCount();
}
if (itemChangedEventHandler)
{
auto ol = itemSource.Cast<IValueObservableList>();
ol->ItemChanged.Remove(itemChangedEventHandler);
}
itemSource = nullptr;
itemChangedEventHandler = nullptr;
if (_itemSource)
{
if (auto ol = _itemSource.Cast<IValueObservableList>())
{
itemSource = ol;
itemChangedEventHandler = ol->ItemChanged.Add([this](vint start, vint oldCount, vint newCount)
{
InvokeOnItemModified(start, oldCount, newCount, true);
});
}
else if (auto rl = _itemSource.Cast<IValueReadonlyList>())
{
itemSource = rl;
}
else
{
itemSource = IValueList::Create(GetLazyList<Value>(_itemSource));
}
}
InvokeOnItemModified(0, oldCount, itemSource ? itemSource->GetCount() : 0, true);
}
description::Value GuiBindableTextList::ItemSource::Get(vint index)
{
if (!itemSource) return Value();
return itemSource->Get(index);
}
void GuiBindableTextList::ItemSource::UpdateBindingProperties()
{
InvokeOnItemModified(0, Count(), Count(), false);
}
bool GuiBindableTextList::ItemSource::NotifyUpdate(vint start, vint count, bool itemReferenceUpdated)
{
if (!itemSource) return false;
if (start<0 || start >= itemSource->GetCount() || count <= 0 || start + count > itemSource->GetCount())
{
return false;
}
else
{
InvokeOnItemModified(start, count, count, itemReferenceUpdated);
return true;
}
}
// ===================== GuiListControl::IItemProvider =====================
vint GuiBindableTextList::ItemSource::Count()
{
if (!itemSource) return 0;
return itemSource->GetCount();
}
WString GuiBindableTextList::ItemSource::GetTextValue(vint itemIndex)
{
if (itemSource)
{
if (0 <= itemIndex && itemIndex < itemSource->GetCount())
{
return ReadProperty(itemSource->Get(itemIndex), textProperty);
}
}
return L"";
}
IDescriptable* GuiBindableTextList::ItemSource::RequestView(const WString& identifier)
{
if (identifier == ITextItemView::Identifier)
{
return (ITextItemView*)this;
}
else
{
return 0;
}
}
// ===================== GuiListControl::IItemBindingView =====================
description::Value GuiBindableTextList::ItemSource::GetBindingValue(vint itemIndex)
{
if (itemSource)
{
if (0 <= itemIndex && itemIndex < itemSource->GetCount())
{
return itemSource->Get(itemIndex);
}
}
return Value();
}
// ===================== list::TextItemStyleProvider::ITextItemView =====================
bool GuiBindableTextList::ItemSource::GetChecked(vint itemIndex)
{
if (itemSource)
{
if (0 <= itemIndex && itemIndex < itemSource->GetCount())
{
return ReadProperty(itemSource->Get(itemIndex), checkedProperty);
}
}
return false;
}
void GuiBindableTextList::ItemSource::SetChecked(vint itemIndex, bool value)
{
if (itemSource)
{
if (0 <= itemIndex && itemIndex < itemSource->GetCount())
{
auto thisValue = itemSource->Get(itemIndex);
WriteProperty(thisValue, checkedProperty, value);
InvokeOnItemModified(itemIndex, 1, 1, false);
}
}
}
/***********************************************************************
GuiBindableTextList
***********************************************************************/
GuiBindableTextList::GuiBindableTextList(theme::ThemeName themeName)
:GuiVirtualTextList(themeName, new ItemSource)
{
itemSource = dynamic_cast<ItemSource*>(GetItemProvider());
TextPropertyChanged.SetAssociatedComposition(boundsComposition);
TextPropertyChanged.SetAssociatedComposition(boundsComposition);
}
GuiBindableTextList::~GuiBindableTextList()
{
}
Ptr<description::IValueEnumerable> GuiBindableTextList::GetItemSource()
{
return itemSource->GetItemSource();
}
void GuiBindableTextList::SetItemSource(Ptr<description::IValueEnumerable> _itemSource)
{
itemSource->SetItemSource(_itemSource);
}
ItemProperty<WString> GuiBindableTextList::GetTextProperty()
{
return itemSource->textProperty;
}
void GuiBindableTextList::SetTextProperty(const ItemProperty<WString>& value)
{
if (itemSource->textProperty != value)
{
itemSource->textProperty = value;
itemSource->UpdateBindingProperties();
TextPropertyChanged.Execute(GetNotifyEventArguments());
}
}
WritableItemProperty<bool> GuiBindableTextList::GetCheckedProperty()
{
return itemSource->checkedProperty;
}
void GuiBindableTextList::SetCheckedProperty(const WritableItemProperty<bool>& value)
{
if (itemSource->checkedProperty != value)
{
itemSource->checkedProperty = value;
itemSource->UpdateBindingProperties();
CheckedPropertyChanged.Execute(GetNotifyEventArguments());
}
}
description::Value GuiBindableTextList::GetSelectedItem()
{
vint index = GetSelectedItemIndex();
if (index == -1) return Value();
return itemSource->Get(index);
}
bool GuiBindableTextList::NotifyItemDataModified(vint start, vint count)
{
return itemSource->NotifyUpdate(start, count, false);
}
/***********************************************************************
GuiBindableListView::ItemSource
***********************************************************************/
GuiBindableListView::ItemSource::ItemSource()
:columns(this)
, dataColumns(this)
{
}
GuiBindableListView::ItemSource::~ItemSource()
{
if (itemChangedEventHandler)
{
auto ol = itemSource.Cast<IValueObservableList>();
ol->ItemChanged.Remove(itemChangedEventHandler);
}
}
Ptr<description::IValueEnumerable> GuiBindableListView::ItemSource::GetItemSource()
{
return itemSource;
}
void GuiBindableListView::ItemSource::SetItemSource(Ptr<description::IValueEnumerable> _itemSource)
{
vint oldCount = 0;
if (itemSource)
{
oldCount = itemSource->GetCount();
}
if (itemChangedEventHandler)
{
auto ol = itemSource.Cast<IValueObservableList>();
ol->ItemChanged.Remove(itemChangedEventHandler);
}
itemSource = nullptr;
itemChangedEventHandler = nullptr;
if (_itemSource)
{
if (auto ol = _itemSource.Cast<IValueObservableList>())
{
itemSource = ol;
itemChangedEventHandler = ol->ItemChanged.Add([this](vint start, vint oldCount, vint newCount)
{
InvokeOnItemModified(start, oldCount, newCount, true);
});
}
else if (auto rl = _itemSource.Cast<IValueReadonlyList>())
{
itemSource = rl;
}
else
{
itemSource = IValueList::Create(GetLazyList<Value>(_itemSource));
}
}
InvokeOnItemModified(0, oldCount, itemSource ? itemSource->GetCount() : 0, true);
}
description::Value GuiBindableListView::ItemSource::Get(vint index)
{
if (!itemSource) return Value();
return itemSource->Get(index);
}
void GuiBindableListView::ItemSource::UpdateBindingProperties()
{
InvokeOnItemModified(0, Count(), Count(), false);
}
bool GuiBindableListView::ItemSource::NotifyUpdate(vint start, vint count, bool itemReferenceUpdated)
{
if (!itemSource) return false;
if (start<0 || start >= itemSource->GetCount() || count <= 0 || start + count > itemSource->GetCount())
{
return false;
}
else
{
InvokeOnItemModified(start, count, count, itemReferenceUpdated);
return true;
}
}
list::ListViewDataColumns& GuiBindableListView::ItemSource::GetDataColumns()
{
return dataColumns;
}
list::ListViewColumns& GuiBindableListView::ItemSource::GetColumns()
{
return columns;
}
// ===================== list::IListViewItemProvider =====================
void GuiBindableListView::ItemSource::RebuildAllItems()
{
InvokeOnItemModified(0, Count(), Count(), true);
}
void GuiBindableListView::ItemSource::RefreshAllItems()
{
InvokeOnItemModified(0, Count(), Count(), false);
}
void GuiBindableListView::ItemSource::NotifyColumnRebuilt()
{
for (auto callback : columnItemViewCallbacks)
{
callback->OnColumnRebuilt();
}
RebuildAllItems();
}
void GuiBindableListView::ItemSource::NotifyColumnChanged()
{
for (auto callback : columnItemViewCallbacks)
{
callback->OnColumnChanged(true);
}
RefreshAllItems();
}
// ===================== GuiListControl::IItemProvider =====================
vint GuiBindableListView::ItemSource::Count()
{
if (!itemSource) return 0;
return itemSource->GetCount();
}
WString GuiBindableListView::ItemSource::GetTextValue(vint itemIndex)
{
return GetText(itemIndex);
}
description::Value GuiBindableListView::ItemSource::GetBindingValue(vint itemIndex)
{
if (itemSource)
{
if (0 <= itemIndex && itemIndex < itemSource->GetCount())
{
return itemSource->Get(itemIndex);
}
}
return Value();
}
IDescriptable* GuiBindableListView::ItemSource::RequestView(const WString& identifier)
{
if (identifier == IListViewItemView::Identifier)
{
return (IListViewItemView*)this;
}
else if (identifier == ListViewColumnItemArranger::IColumnItemView::Identifier)
{
return (ListViewColumnItemArranger::IColumnItemView*)this;
}
else
{
return 0;
}
}
// ===================== list::ListViewItemStyleProvider::IListViewItemView =====================
Ptr<GuiImageData> GuiBindableListView::ItemSource::GetSmallImage(vint itemIndex)
{
if (itemSource)
{
if (0 <= itemIndex && itemIndex < itemSource->GetCount())
{
return ReadProperty(itemSource->Get(itemIndex), smallImageProperty);
}
}
return nullptr;
}
Ptr<GuiImageData> GuiBindableListView::ItemSource::GetLargeImage(vint itemIndex)
{
if (itemSource)
{
if (0 <= itemIndex && itemIndex < itemSource->GetCount())
{
return ReadProperty(itemSource->Get(itemIndex), largeImageProperty);
}
}
return nullptr;
}
WString GuiBindableListView::ItemSource::GetText(vint itemIndex)
{
if (itemSource)
{
if (0 <= itemIndex && itemIndex < itemSource->GetCount() && columns.Count()>0)
{
return ReadProperty(itemSource->Get(itemIndex), columns[0]->GetTextProperty());
}
}
return L"";
}
WString GuiBindableListView::ItemSource::GetSubItem(vint itemIndex, vint index)
{
if (itemSource)
{
if (0 <= itemIndex && itemIndex < itemSource->GetCount() && 0 <= index && index < columns.Count() - 1)
{
return ReadProperty(itemSource->Get(itemIndex), columns[index + 1]->GetTextProperty());
}
}
return L"";
}
vint GuiBindableListView::ItemSource::GetDataColumnCount()
{
return dataColumns.Count();
}
vint GuiBindableListView::ItemSource::GetDataColumn(vint index)
{
return dataColumns[index];
}
vint GuiBindableListView::ItemSource::GetColumnCount()
{
return columns.Count();
}
WString GuiBindableListView::ItemSource::GetColumnText(vint index)
{
if (index < 0 || index >= columns.Count())
{
return L"";
}
else
{
return columns[index]->GetText();
}
}
// ===================== list::ListViewColumnItemArranger::IColumnItemView =====================
bool GuiBindableListView::ItemSource::AttachCallback(ListViewColumnItemArranger::IColumnItemViewCallback* value)
{
if(columnItemViewCallbacks.Contains(value))
{
return false;
}
else
{
columnItemViewCallbacks.Add(value);
return true;
}
}
bool GuiBindableListView::ItemSource::DetachCallback(ListViewColumnItemArranger::IColumnItemViewCallback* value)
{
vint index = columnItemViewCallbacks.IndexOf(value);
if (index == -1)
{
return false;
}
else
{
columnItemViewCallbacks.Remove(value);
return true;
}
}
vint GuiBindableListView::ItemSource::GetColumnSize(vint index)
{
if (index < 0 || index >= columns.Count())
{
return 0;
}
else
{
return columns[index]->GetSize();
}
}
void GuiBindableListView::ItemSource::SetColumnSize(vint index, vint value)
{
if (index >= 0 && index < columns.Count())
{
columns[index]->SetSize(value);
}
}
GuiMenu* GuiBindableListView::ItemSource::GetDropdownPopup(vint index)
{
if (index < 0 || index >= columns.Count())
{
return 0;
}
else
{
return columns[index]->GetDropdownPopup();
}
}
ColumnSortingState GuiBindableListView::ItemSource::GetSortingState(vint index)
{
if (index < 0 || index >= columns.Count())
{
return ColumnSortingState::NotSorted;
}
else
{
return columns[index]->GetSortingState();
}
}
/***********************************************************************
GuiBindableListView
***********************************************************************/
GuiBindableListView::GuiBindableListView(theme::ThemeName themeName)
:GuiVirtualListView(themeName, new ItemSource)
{
itemSource = dynamic_cast<ItemSource*>(GetItemProvider());
LargeImagePropertyChanged.SetAssociatedComposition(boundsComposition);
SmallImagePropertyChanged.SetAssociatedComposition(boundsComposition);
}
GuiBindableListView::~GuiBindableListView()
{
}
list::ListViewDataColumns& GuiBindableListView::GetDataColumns()
{
return itemSource->GetDataColumns();
}
list::ListViewColumns& GuiBindableListView::GetColumns()
{
return itemSource->GetColumns();
}
Ptr<description::IValueEnumerable> GuiBindableListView::GetItemSource()
{
return itemSource->GetItemSource();
}
void GuiBindableListView::SetItemSource(Ptr<description::IValueEnumerable> _itemSource)
{
itemSource->SetItemSource(_itemSource);
}
ItemProperty<Ptr<GuiImageData>> GuiBindableListView::GetLargeImageProperty()
{
return itemSource->largeImageProperty;
}
void GuiBindableListView::SetLargeImageProperty(const ItemProperty<Ptr<GuiImageData>>& value)
{
if (itemSource->largeImageProperty != value)
{
itemSource->largeImageProperty = value;
itemSource->UpdateBindingProperties();
LargeImagePropertyChanged.Execute(GetNotifyEventArguments());
}
}
ItemProperty<Ptr<GuiImageData>> GuiBindableListView::GetSmallImageProperty()
{
return itemSource->smallImageProperty;
}
void GuiBindableListView::SetSmallImageProperty(const ItemProperty<Ptr<GuiImageData>>& value)
{
if (itemSource->smallImageProperty != value)
{
itemSource->smallImageProperty = value;
itemSource->UpdateBindingProperties();
SmallImagePropertyChanged.Execute(GetNotifyEventArguments());
}
}
description::Value GuiBindableListView::GetSelectedItem()
{
vint index = GetSelectedItemIndex();
if (index == -1) return Value();
return itemSource->Get(index);
}
bool GuiBindableListView::NotifyItemDataModified(vint start, vint count)
{
return itemSource->NotifyUpdate(start, count, false);
}
/***********************************************************************
GuiBindableTreeView::ItemSourceNode
***********************************************************************/
Ptr<description::IValueReadonlyList> GuiBindableTreeView::ItemSourceNode::PrepareValueList(const description::Value& inputItemSource)
{
if (auto value = ReadProperty(inputItemSource, rootProvider->childrenProperty))
{
if (auto ol = value.Cast<IValueObservableList>())
{
return ol;
}
else if (auto rl = value.Cast<IValueReadonlyList>())
{
return rl;
}
else
{
return IValueList::Create(GetLazyList<Value>(value));
}
}
else
{
return IValueList::Create();
}
}
void GuiBindableTreeView::ItemSourceNode::PrepareChildren(Ptr<description::IValueReadonlyList> newValueList)
{
if (!childrenVirtualList)
{
childrenVirtualList = newValueList;
if (auto ol = childrenVirtualList.Cast<IValueObservableList>())
{
itemChangedEventHandler = ol->ItemChanged.Add([this](vint start, vint oldCount, vint newCount)
{
callback->OnBeforeItemModified(this, start, oldCount, newCount, true);
children.RemoveRange(start, oldCount);
for (vint i = 0; i < newCount; i++)
{
Value value = childrenVirtualList->Get(start + i);
auto node = Ptr(new ItemSourceNode(value, this));
children.Insert(start + i, node);
}
callback->OnAfterItemModified(this, start, oldCount, newCount, true);
});
}
vint count = childrenVirtualList->GetCount();
for (vint i = 0; i < count; i++)
{
Value value = childrenVirtualList->Get(i);
auto node = Ptr(new ItemSourceNode(value, this));
children.Add(node);
}
}
}
void GuiBindableTreeView::ItemSourceNode::UnprepareChildren()
{
if (itemChangedEventHandler)
{
auto ol = childrenVirtualList.Cast<IValueObservableList>();
ol->ItemChanged.Remove(itemChangedEventHandler);
itemChangedEventHandler = nullptr;
}
childrenVirtualList = nullptr;
for (auto node : children)
{
node->UnprepareChildren();
}
children.Clear();
}
void GuiBindableTreeView::ItemSourceNode::PrepareReverseMapping()
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::controls::GuiBindableTreeView::ItemSourceNode::PrepareReverseMapping()#"
if (rootProvider->reverseMappingProperty && !itemSource.IsNull())
{
auto oldValue = ReadProperty(itemSource, rootProvider->reverseMappingProperty);
CHECK_ERROR(oldValue.IsNull(), ERROR_MESSAGE_PREFIX L"The reverse mapping property of an item has been unexpectedly changed.");
WriteProperty(itemSource, rootProvider->reverseMappingProperty, Value::From(this));
}
#undef ERROR_MESSAGE_PREFIX
}
void GuiBindableTreeView::ItemSourceNode::UnprepareReverseMapping()
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::controls::GuiBindableTreeView::ItemSourceNode::PrepareReverseMapping()#"
if (rootProvider->reverseMappingProperty && !itemSource.IsNull())
{
auto oldValue = ReadProperty(itemSource, rootProvider->reverseMappingProperty);
CHECK_ERROR(oldValue.GetRawPtr() == this, ERROR_MESSAGE_PREFIX L"The reverse mapping property of an item has been unexpectedly changed.");
WriteProperty(itemSource, rootProvider->reverseMappingProperty, {});
}
#undef ERROR_MESSAGE_PREFIX
}
GuiBindableTreeView::ItemSourceNode::ItemSourceNode(const description::Value& _itemSource, ItemSourceNode* _parent)
:itemSource(_itemSource)
, rootProvider(_parent->rootProvider)
, parent(_parent)
, callback(_parent->callback)
{
PrepareReverseMapping();
}
GuiBindableTreeView::ItemSourceNode::ItemSourceNode(ItemSource* _rootProvider)
:rootProvider(_rootProvider)
, parent(nullptr)
, callback(_rootProvider)
{
}
GuiBindableTreeView::ItemSourceNode::~ItemSourceNode()
{
UnprepareReverseMapping();
if (itemChangedEventHandler)
{
auto ol = childrenVirtualList.Cast<IValueObservableList>();
ol->ItemChanged.Remove(itemChangedEventHandler);
}
}
description::Value GuiBindableTreeView::ItemSourceNode::GetItemSource()
{
return itemSource;
}
void GuiBindableTreeView::ItemSourceNode::SetItemSource(const description::Value& _itemSource)
{
auto newVirtualList = PrepareValueList(_itemSource);
vint oldCount = childrenVirtualList ? childrenVirtualList->GetCount() : 0;
vint newCount = newVirtualList->GetCount();
callback->OnBeforeItemModified(this, 0, oldCount, newCount, true);
UnprepareChildren();
UnprepareReverseMapping();
itemSource = _itemSource;
PrepareReverseMapping();
PrepareChildren(newVirtualList);
callback->OnAfterItemModified(this, 0, oldCount, newCount, true);
}
bool GuiBindableTreeView::ItemSourceNode::GetExpanding()
{
return this == rootProvider->rootNode.Obj() ? true : expanding;
}
void GuiBindableTreeView::ItemSourceNode::SetExpanding(bool value)
{
if (this != rootProvider->rootNode.Obj() && expanding != value)
{
expanding = value;
if (expanding)
{
callback->OnItemExpanded(this);
}
else
{
callback->OnItemCollapsed(this);
}
}
}
vint GuiBindableTreeView::ItemSourceNode::CalculateTotalVisibleNodes()
{
if (!GetExpanding())
{
return 1;
}
if (!childrenVirtualList)
{
PrepareChildren(PrepareValueList(itemSource));
}
vint count = 1;
for (auto child : children)
{
count += child->CalculateTotalVisibleNodes();
}
return count;
}
void GuiBindableTreeView::ItemSourceNode::NotifyDataModified()
{
if (parent)
{
vint index = parent->children.IndexOf(this);
callback->OnBeforeItemModified(parent, index, 1, 1, false);
callback->OnAfterItemModified(parent, index, 1, 1, false);
}
}
vint GuiBindableTreeView::ItemSourceNode::GetChildCount()
{
if (!childrenVirtualList)
{
PrepareChildren(PrepareValueList(itemSource));
}
return children.Count();
}
Ptr<tree::INodeProvider> GuiBindableTreeView::ItemSourceNode::GetParent()
{
return Ptr(parent);
}
Ptr<tree::INodeProvider> GuiBindableTreeView::ItemSourceNode::GetChild(vint index)
{
if (!childrenVirtualList)
{
PrepareChildren(PrepareValueList(itemSource));
}
if (0 <= index && index < children.Count())
{
return children[index];
}
return nullptr;
}
/***********************************************************************
GuiBindableTreeView::ItemSource
***********************************************************************/
GuiBindableTreeView::ItemSource::ItemSource()
{
rootNode = Ptr(new ItemSourceNode(this));
}
GuiBindableTreeView::ItemSource::~ItemSource()
{
}
description::Value GuiBindableTreeView::ItemSource::GetItemSource()
{
return rootNode->GetItemSource();
}
void GuiBindableTreeView::ItemSource::SetItemSource(const description::Value& _itemSource)
{
rootNode->SetItemSource(_itemSource);
}
void GuiBindableTreeView::ItemSource::UpdateBindingProperties(bool updateChildrenProperty)
{
vint oldCount = rootNode->GetChildCount();
if (updateChildrenProperty)
{
rootNode->UnprepareChildren();
}
vint newCount = rootNode->GetChildCount();
OnBeforeItemModified(rootNode.Obj(), 0, oldCount, newCount, updateChildrenProperty);
OnAfterItemModified(rootNode.Obj(), 0, oldCount, newCount, updateChildrenProperty);
}
// ===================== tree::INodeRootProvider =====================
Ptr<tree::INodeProvider> GuiBindableTreeView::ItemSource::GetRootNode()
{
return rootNode;
}
WString GuiBindableTreeView::ItemSource::GetTextValue(tree::INodeProvider* node)
{
return ReadProperty(GetBindingValue(node), textProperty);
}
description::Value GuiBindableTreeView::ItemSource::GetBindingValue(tree::INodeProvider* node)
{
if (auto itemSourceNode = dynamic_cast<ItemSourceNode*>(node))
{
return itemSourceNode->GetItemSource();
}
return Value();
}
IDescriptable* GuiBindableTreeView::ItemSource::RequestView(const WString& identifier)
{
if(identifier==ITreeViewItemView::Identifier)
{
return (ITreeViewItemView*)this;
}
else
{
return 0;
}
}
// ===================== tree::ITreeViewItemView =====================
Ptr<GuiImageData> GuiBindableTreeView::ItemSource::GetNodeImage(tree::INodeProvider* node)
{
if (auto itemSourceNode = dynamic_cast<ItemSourceNode*>(node))
{
return ReadProperty(itemSourceNode->GetItemSource(), imageProperty);
}
return nullptr;
}
/***********************************************************************
GuiBindableTreeView
***********************************************************************/
GuiBindableTreeView::GuiBindableTreeView(theme::ThemeName themeName, WritableItemProperty<description::Value> reverseMappingProperty)
:GuiVirtualTreeView(themeName, Ptr(new ItemSource))
{
itemSource = dynamic_cast<ItemSource*>(GetNodeRootProvider());
itemSource->reverseMappingProperty = reverseMappingProperty;
TextPropertyChanged.SetAssociatedComposition(boundsComposition);
ImagePropertyChanged.SetAssociatedComposition(boundsComposition);
ChildrenPropertyChanged.SetAssociatedComposition(boundsComposition);
}
GuiBindableTreeView::~GuiBindableTreeView()
{
}
description::Value GuiBindableTreeView::GetItemSource()
{
return itemSource->GetItemSource();
}
void GuiBindableTreeView::SetItemSource(description::Value _itemSource)
{
itemSource->SetItemSource(_itemSource);
}
WritableItemProperty<description::Value> GuiBindableTreeView::GetReverseMappingProperty()
{
return itemSource->reverseMappingProperty;
}
ItemProperty<WString> GuiBindableTreeView::GetTextProperty()
{
return itemSource->textProperty;
}
void GuiBindableTreeView::SetTextProperty(const ItemProperty<WString>& value)
{
if (itemSource->textProperty != value)
{
itemSource->textProperty = value;
itemSource->UpdateBindingProperties(false);
TextPropertyChanged.Execute(GetNotifyEventArguments());
}
}
ItemProperty<Ptr<GuiImageData>> GuiBindableTreeView::GetImageProperty()
{
return itemSource->imageProperty;
}
void GuiBindableTreeView::SetImageProperty(const ItemProperty<Ptr<GuiImageData>>& value)
{
if (itemSource->imageProperty != value)
{
itemSource->imageProperty = value;
itemSource->UpdateBindingProperties(false);
ImagePropertyChanged.Execute(GetNotifyEventArguments());
}
}
ItemProperty<Ptr<IValueEnumerable>> GuiBindableTreeView::GetChildrenProperty()
{
return itemSource->childrenProperty;
}
void GuiBindableTreeView::SetChildrenProperty(const ItemProperty<Ptr<IValueEnumerable>>& value)
{
if (itemSource->childrenProperty != value)
{
itemSource->childrenProperty = value;
itemSource->UpdateBindingProperties(true);
ChildrenPropertyChanged.Execute(GetNotifyEventArguments());
}
}
description::Value GuiBindableTreeView::GetSelectedItem()
{
vint index = GetSelectedItemIndex();
if (index == -1) return Value();
Value result;
if (auto node = nodeItemView->RequestNode(index))
{
if (auto itemSourceNode = node.Cast<ItemSourceNode>())
{
result = itemSourceNode->GetItemSource();
}
}
return result;
}
void GuiBindableTreeView::NotifyNodeDataModified(description::Value value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::controls::GuiBindableTreeView::NotifyNodeDataModified(Value)#"
CHECK_ERROR(itemSource->reverseMappingProperty, ERROR_MESSAGE_PREFIX L"This function can only be called when the ReverseMappingProperty is in use.");
CHECK_ERROR(!value.IsNull(), ERROR_MESSAGE_PREFIX L"The item cannot be null.");
auto mapping = ReadProperty(value, itemSource->reverseMappingProperty);
auto node = dynamic_cast<tree::INodeProvider*>(mapping.GetRawPtr());
CHECK_ERROR(node, ERROR_MESSAGE_PREFIX L"The item is not binded to a GuiBindableTreeView control or its reverse mapping property has been unexpectedly changed.");
auto rootNode = node;
while (rootNode->GetParent())
{
rootNode = rootNode->GetParent().Obj();
}
CHECK_ERROR(rootNode == itemSource->rootNode.Obj(), ERROR_MESSAGE_PREFIX L"The item is not binded to this control.");
CHECK_ERROR(node != itemSource->rootNode.Obj(), ERROR_MESSAGE_PREFIX L"The item should not be the root item, which is the item source assigned to this control.");
node->NotifyDataModified();
#undef ERROR_MESSAGE_PREFIX
}
}
}
}
/***********************************************************************
.\CONTROLS\LISTCONTROLPACKAGE\GUICOMBOCONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
/***********************************************************************
GuiComboBoxBase
***********************************************************************/
void GuiComboBoxBase::BeforeControlTemplateUninstalled_()
{
}
void GuiComboBoxBase::AfterControlTemplateInstalled_(bool initialize)
{
}
IGuiMenuService::Direction GuiComboBoxBase::GetSubMenuDirection()
{
return IGuiMenuService::Horizontal;
}
void GuiComboBoxBase::OnCachedBoundsChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
Size size=GetPreferredMenuClientSize();
size.x=boundsComposition->GetCachedBounds().Width();
SetPreferredMenuClientSize(size);
}
GuiComboBoxBase::GuiComboBoxBase(theme::ThemeName themeName)
:GuiMenuButton(themeName)
{
CreateSubMenu();
SetCascadeAction(false);
boundsComposition->CachedBoundsChanged.AttachMethod(this, &GuiComboBoxBase::OnCachedBoundsChanged);
}
GuiComboBoxBase::~GuiComboBoxBase()
{
}
/***********************************************************************
GuiComboButton
***********************************************************************/
GuiComboButton::GuiComboButton(theme::ThemeName themeName, GuiControl* _dropdownControl)
:GuiComboBoxBase(themeName)
, dropdownControl(_dropdownControl)
{
dropdownControl->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
GetSubMenu()->GetContainerComposition()->AddChild(dropdownControl->GetBoundsComposition());
}
GuiComboButton::~GuiComboButton()
{
}
/***********************************************************************
GuiComboBoxListControl
***********************************************************************/
void GuiComboBoxListControl::UpdateDisplayFont()
{
GuiControl::UpdateDisplayFont();
if (itemStyleController)
{
itemStyleController->SetFont(GetDisplayFont());
}
}
void GuiComboBoxListControl::BeforeControlTemplateUninstalled()
{
GuiComboBoxBase::BeforeControlTemplateUninstalled();
}
void GuiComboBoxListControl::AfterControlTemplateInstalled(bool initialize)
{
GuiComboBoxBase::AfterControlTemplateInstalled(initialize);
TypedControlTemplateObject(true)->SetTextVisible(!itemStyleProperty);
}
void GuiComboBoxListControl::RemoveStyleController()
{
if (itemStyleController)
{
SafeDeleteComposition(itemStyleController);
itemStyleController = nullptr;
}
}
void GuiComboBoxListControl::InstallStyleController(vint itemIndex)
{
if (itemStyleProperty)
{
if (itemIndex != -1)
{
auto item = containedListControl->GetItemProvider()->GetBindingValue(itemIndex);
if (!item.IsNull())
{
if (auto style = itemStyleProperty(item))
{
itemStyleController = style;
itemStyleController->SetText(GetText());
itemStyleController->SetFont(GetDisplayFont());
itemStyleController->SetContext(GetContext());
itemStyleController->SetVisuallyEnabled(GetVisuallyEnabled());
itemStyleController->SetAlignmentToParent(Margin(0, 0, 0, 0));
containerComposition->AddChild(itemStyleController);
}
}
}
}
}
void GuiComboBoxListControl::DisplaySelectedContent(vint itemIndex)
{
if (itemIndex == -1)
{
SetText(L"");
}
else
{
WString text = containedListControl->GetItemProvider()->GetTextValue(itemIndex);
SetText(text);
}
RemoveStyleController();
InstallStyleController(itemIndex);
if (selectedIndex != itemIndex)
{
selectedIndex = itemIndex;
SelectedIndexChanged.Execute(GetNotifyEventArguments());
}
}
void GuiComboBoxListControl::AdoptSubMenuSize()
{
if (auto subMenu = GetSubMenu())
{
Size expectedSize(0, GetDisplayFont().size * 20);
Size adoptedSize = containedListControl->GetAdoptedSize(expectedSize);
Size clientSize = GetPreferredMenuClientSize();
vint height = adoptedSize.y + subMenu->GetClientSize().y - containedListControl->GetBoundsComposition()->GetCachedBounds().Height();
if (clientSize.y != height)
{
clientSize.y = height;
SetPreferredMenuClientSize(clientSize);
}
}
}
void GuiComboBoxListControl::OnTextChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (itemStyleController)
{
itemStyleController->SetText(GetText());
}
}
void GuiComboBoxListControl::OnContextChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (itemStyleController)
{
itemStyleController->SetContext(GetContext());
}
}
void GuiComboBoxListControl::OnVisuallyEnabledChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (itemStyleController)
{
itemStyleController->SetVisuallyEnabled(GetVisuallyEnabled());
}
}
void GuiComboBoxListControl::OnAfterSubMenuOpening(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
containedListControl->SelectItemsByClick(selectedIndex, false, false, true);
containedListControl->EnsureItemVisible(selectedIndex);
}
void GuiComboBoxListControl::OnListControlAdoptedSizeInvalidated(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
TryDelayExecuteIfNotDeleted([=]() { AdoptSubMenuSize(); });
}
void GuiComboBoxListControl::OnListControlItemMouseDown(compositions::GuiGraphicsComposition* sender, compositions::GuiItemMouseEventArgs& arguments)
{
DisplaySelectedContent(containedListControl->GetSelectedItemIndex());
GetSubMenu()->Hide();
}
void GuiComboBoxListControl::OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments)
{
if (!arguments.autoRepeatKeyDown)
{
switch (arguments.code)
{
case VKEY::KEY_RETURN:
DisplaySelectedContent(containedListControl->GetSelectedItemIndex());
arguments.handled = true;
case VKEY::KEY_ESCAPE:
GetSubMenu()->Hide();
arguments.handled = true;
break;
default:
containedListControl->SelectItemsByKey(arguments.code, arguments.ctrl, arguments.shift);
}
}
}
void GuiComboBoxListControl::OnAttached(list::IItemProvider* provider)
{
}
void GuiComboBoxListControl::OnItemModified(vint start, vint count, vint newCount, bool itemReferenceUpdated)
{
if (count == newCount && start <= selectedIndex && selectedIndex < start + count)
{
DisplaySelectedContent(selectedIndex);
}
else
{
DisplaySelectedContent(-1);
}
}
GuiComboBoxListControl::GuiComboBoxListControl(theme::ThemeName themeName, GuiSelectableListControl* _containedListControl)
:GuiComboBoxBase(themeName)
, containedListControl(_containedListControl)
{
TextChanged.AttachMethod(this, &GuiComboBoxListControl::OnTextChanged);
ContextChanged.AttachMethod(this, &GuiComboBoxListControl::OnContextChanged);
VisuallyEnabledChanged.AttachMethod(this, &GuiComboBoxListControl::OnVisuallyEnabledChanged);
AfterSubMenuOpening.AttachMethod(this, &GuiComboBoxListControl::OnAfterSubMenuOpening);
containedListControl->GetItemProvider()->AttachCallback(this);
containedListControl->SetMultiSelect(false);
containedListControl->AdoptedSizeInvalidated.AttachMethod(this, &GuiComboBoxListControl::OnListControlAdoptedSizeInvalidated);
containedListControl->ItemLeftButtonDown.AttachMethod(this, &GuiComboBoxListControl::OnListControlItemMouseDown);
containedListControl->ItemRightButtonDown.AttachMethod(this, &GuiComboBoxListControl::OnListControlItemMouseDown);
boundsComposition->GetEventReceiver()->keyDown.AttachMethod(this, &GuiComboBoxListControl::OnKeyDown);
auto itemProvider = containedListControl->GetItemProvider();
SelectedIndexChanged.SetAssociatedComposition(boundsComposition);
containedListControl->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
GetSubMenu()->GetContainerComposition()->AddChild(containedListControl->GetBoundsComposition());
SetFont(GetFont());
}
GuiComboBoxListControl::~GuiComboBoxListControl()
{
containedListControl->GetItemProvider()->DetachCallback(this);
containedListControl->GetBoundsComposition()->CachedBoundsChanged.Detach(boundsChangedHandler);
boundsChangedHandler = nullptr;
}
GuiSelectableListControl* GuiComboBoxListControl::GetContainedListControl()
{
return containedListControl;
}
GuiComboBoxListControl::ItemStyleProperty GuiComboBoxListControl::GetItemTemplate()
{
return itemStyleProperty;
}
void GuiComboBoxListControl::SetItemTemplate(ItemStyleProperty value)
{
RemoveStyleController();
itemStyleProperty = value;
TypedControlTemplateObject(true)->SetTextVisible(!itemStyleProperty);
InstallStyleController(selectedIndex);
ItemTemplateChanged.Execute(GetNotifyEventArguments());
}
vint GuiComboBoxListControl::GetSelectedIndex()
{
return selectedIndex;
}
void GuiComboBoxListControl::SetSelectedIndex(vint value)
{
if (selectedIndex != value)
{
if (0 <= value && value < containedListControl->GetItemProvider()->Count())
{
DisplaySelectedContent(value);
}
}
GetSubMenu()->Hide();
}
description::Value GuiComboBoxListControl::GetSelectedItem()
{
if (selectedIndex != -1)
{
return containedListControl->GetItemProvider()->GetBindingValue(selectedIndex);
}
return description::Value();
}
list::IItemProvider* GuiComboBoxListControl::GetItemProvider()
{
return containedListControl->GetItemProvider();
}
}
}
}
/***********************************************************************
.\CONTROLS\LISTCONTROLPACKAGE\GUIDATAGRIDCONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
namespace list
{
using namespace compositions;
using namespace collections;
using namespace description;
using namespace templates;
const wchar_t* const IDataGridView::Identifier = L"vl::presentation::controls::list::IDataGridView";
/***********************************************************************
DefaultDataGridItemTemplate
***********************************************************************/
IDataVisualizerFactory* DefaultDataGridItemTemplate::GetDataVisualizerFactory(vint row, vint column)
{
if (auto dataGrid = dynamic_cast<GuiVirtualDataGrid*>(listControl))
{
if (auto factory = dataGrid->dataGridView->GetCellDataVisualizerFactory(row, column))
{
return factory;
}
if (column == 0)
{
return dataGrid->defaultMainColumnVisualizerFactory.Obj();
}
else
{
return dataGrid->defaultSubColumnVisualizerFactory.Obj();
}
}
return nullptr;
}
IDataEditorFactory* DefaultDataGridItemTemplate::GetDataEditorFactory(vint row, vint column)
{
if (auto dataGrid = dynamic_cast<GuiVirtualDataGrid*>(listControl))
{
return dataGrid->dataGridView->GetCellDataEditorFactory(row, column);
}
return nullptr;
}
vint DefaultDataGridItemTemplate::GetCellColumnIndex(compositions::GuiGraphicsComposition* composition)
{
for (vint i = 0; i < textTable->GetColumns(); i++)
{
auto cell = textTable->GetSitedCell(0, i);
if (composition == cell)
{
return i;
}
}
return -1;
}
bool DefaultDataGridItemTemplate::IsInEditor(GuiVirtualDataGrid* dataGrid, compositions::GuiMouseEventArgs& arguments)
{
if (!dataGrid->currentEditor) return false;
auto editorComposition = dataGrid->currentEditor->GetTemplate();
auto currentComposition = arguments.eventSource;
while (currentComposition)
{
if (currentComposition == editorComposition)
{
return true;
}
else if (currentComposition == this)
{
break;
}
else
{
currentComposition = currentComposition->GetParent();
}
}
return false;
}
void DefaultDataGridItemTemplate::OnCellButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if (auto dataGrid = dynamic_cast<GuiVirtualDataGrid*>(listControl))
{
if (IsInEditor(dataGrid, arguments))
{
arguments.handled = true;
}
}
}
void DefaultDataGridItemTemplate::OnCellLeftButtonUp(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if (auto dataGrid = dynamic_cast<GuiVirtualDataGrid*>(listControl))
{
if (IsInEditor(dataGrid, arguments))
{
arguments.handled = true;
}
else if (dataGrid->GetVisuallyEnabled())
{
vint index = GetCellColumnIndex(sender);
if (index != -1)
{
vint currentRow = GetIndex();
dataGrid->SelectCell({ currentRow,index }, true);
}
}
}
}
void DefaultDataGridItemTemplate::OnCellRightButtonUp(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if (auto dataGrid = dynamic_cast<GuiVirtualDataGrid*>(listControl))
{
if (IsInEditor(dataGrid, arguments))
{
arguments.handled = true;
}
else if (dataGrid->GetVisuallyEnabled())
{
vint index = GetCellColumnIndex(sender);
if (index != -1)
{
vint currentRow = GetIndex();
dataGrid->SelectCell({ currentRow,index }, false);
}
}
}
}
void DefaultDataGridItemTemplate::DeleteAllVisualizers()
{
for (vint i = 0; i < dataVisualizers.Count(); i++)
{
DeleteVisualizer(i);
}
}
void DefaultDataGridItemTemplate::DeleteVisualizer(vint column)
{
auto visualizer = dataVisualizers[column];
auto composition = visualizer->GetTemplate();
visualizer->NotifyDeletedTemplate();
if (composition->GetParent())
{
composition->GetParent()->RemoveChild(composition);
}
SafeDeleteComposition(composition);
dataVisualizers[column] = nullptr;
}
void DefaultDataGridItemTemplate::ResetDataTable(vint columnCount)
{
vint itemIndex = GetIndex();
if (dataVisualizers.Count() == columnCount)
{
for (vint i = 0; i < columnCount; i++)
{
auto factory = GetDataVisualizerFactory(itemIndex, i);
if (dataVisualizerFactories[i] != factory)
{
DeleteVisualizer(i);
dataVisualizerFactories[i] = factory;
}
}
}
else
{
DeleteAllVisualizers();
dataVisualizerFactories.Resize(columnCount);
dataVisualizers.Resize(columnCount);
for (auto cell : dataCells)
{
SafeDeleteComposition(cell);
}
dataCells.Resize(columnCount);
for (vint i = 0; i < columnCount; i++)
{
dataVisualizerFactories[i] = GetDataVisualizerFactory(itemIndex, i);
}
textTable->SetRowsAndColumns(1, columnCount);
for (vint i = 0; i < columnCount; i++)
{
auto cell = new GuiCellComposition;
textTable->AddChild(cell);
cell->SetSite(0, i, 1, 1);
cell->GetEventReceiver()->leftButtonDown.AttachMethod(this, &DefaultDataGridItemTemplate::OnCellButtonDown);
cell->GetEventReceiver()->rightButtonDown.AttachMethod(this, &DefaultDataGridItemTemplate::OnCellButtonDown);
cell->GetEventReceiver()->leftButtonUp.AttachMethod(this, &DefaultDataGridItemTemplate::OnCellLeftButtonUp);
cell->GetEventReceiver()->rightButtonUp.AttachMethod(this, &DefaultDataGridItemTemplate::OnCellRightButtonUp);
dataCells[i] = cell;
}
}
}
void DefaultDataGridItemTemplate::OnInitialize()
{
{
textTable = new GuiTableComposition;
textTable->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
textTable->SetAlignmentToParent(Margin(0, 0, 0, 0));
textTable->SetRowsAndColumns(1, 1);
textTable->SetRowOption(0, GuiCellOption::MinSizeOption());
textTable->SetColumnOption(0, GuiCellOption::AbsoluteOption(0));
AddChild(textTable);
}
SelectedChanged.AttachMethod(this, &DefaultDataGridItemTemplate::OnSelectedChanged);
FontChanged.AttachMethod(this, &DefaultDataGridItemTemplate::OnFontChanged);
ContextChanged.AttachMethod(this, &DefaultDataGridItemTemplate::OnContextChanged);
VisuallyEnabledChanged.AttachMethod(this, &DefaultDataGridItemTemplate::OnVisuallyEnabledChanged);
SelectedChanged.Execute(compositions::GuiEventArgs(this));
FontChanged.Execute(compositions::GuiEventArgs(this));
ContextChanged.Execute(compositions::GuiEventArgs(this));
VisuallyEnabledChanged.Execute(compositions::GuiEventArgs(this));
}
void DefaultDataGridItemTemplate::OnRefresh()
{
if (auto dataGrid = dynamic_cast<GuiVirtualDataGrid*>(listControl))
{
vint columnCount = dataGrid->listViewItemView->GetColumnCount();
vint itemIndex = GetIndex();
ResetDataTable(columnCount);
for (vint i = 0; i < columnCount; i++)
{
auto& dataVisualizer = dataVisualizers[i];
if (!dataVisualizer)
{
dataVisualizer = dataVisualizerFactories[i]->CreateVisualizer(dataGrid);
dataVisualizer->GetTemplate()->SetFont(GetFont());
dataVisualizers[i] = dataVisualizer;
auto cell = dataCells[i];
auto composition = dataVisualizer->GetTemplate();
composition->SetAlignmentToParent(Margin(0, 0, 0, 0));
cell->AddChild(composition);
}
dataVisualizer->BeforeVisualizeCell(dataGrid->GetItemProvider(), itemIndex, i);
}
GridPos selectedCell = dataGrid->GetSelectedCell();
if (selectedCell.row == itemIndex)
{
NotifySelectCell(selectedCell.column);
}
else
{
NotifySelectCell(-1);
}
}
UpdateSubItemSize();
}
void DefaultDataGridItemTemplate::OnSelectedChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (!GetSelected())
{
NotifySelectCell(-1);
}
}
void DefaultDataGridItemTemplate::OnFontChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
for (auto visualizer : dataVisualizers)
{
visualizer->GetTemplate()->SetFont(GetFont());
}
if (currentEditor)
{
currentEditor->GetTemplate()->SetFont(GetFont());
}
}
void DefaultDataGridItemTemplate::OnContextChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
for (auto visualizer : dataVisualizers)
{
visualizer->GetTemplate()->SetContext(GetContext());
}
if (currentEditor)
{
currentEditor->GetTemplate()->SetContext(GetContext());
}
}
void DefaultDataGridItemTemplate::OnVisuallyEnabledChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
for (auto visualizer : dataVisualizers)
{
visualizer->GetTemplate()->SetVisuallyEnabled(GetVisuallyEnabled());
}
if (currentEditor)
{
currentEditor->GetTemplate()->SetVisuallyEnabled(GetVisuallyEnabled());
}
}
DefaultDataGridItemTemplate::DefaultDataGridItemTemplate()
{
}
DefaultDataGridItemTemplate::~DefaultDataGridItemTemplate()
{
for (auto visualizer : dataVisualizers)
{
visualizer->NotifyDeletedTemplate();
}
if (currentEditor)
{
currentEditor->NotifyDeletedTemplate();
}
}
void DefaultDataGridItemTemplate::UpdateSubItemSize()
{
if (auto dataGrid = dynamic_cast<GuiVirtualDataGrid*>(listControl))
{
vint columnCount = dataGrid->listViewItemView->GetColumnCount();
if (columnCount > textTable->GetColumns())
{
columnCount = textTable->GetColumns();
}
for (vint i = 0; i < columnCount; i++)
{
textTable->SetColumnOption(i, GuiCellOption::AbsoluteOption(dataGrid->columnItemView->GetColumnSize(i)));
}
}
}
bool DefaultDataGridItemTemplate::IsEditorOpened()
{
return currentEditor != nullptr;
}
void DefaultDataGridItemTemplate::NotifyOpenEditor(vint column, IDataEditor* editor)
{
currentEditor = editor;
if (currentEditor)
{
auto cell = textTable->GetSitedCell(0, column);
auto* editorBounds = currentEditor->GetTemplate();
editorBounds->SetFont(GetFont());
editorBounds->SetContext(GetContext());
if (editorBounds->GetParent() && editorBounds->GetParent() != cell)
{
editorBounds->GetParent()->RemoveChild(editorBounds);
}
editorBounds->SetAlignmentToParent(Margin(0, 0, 0, 0));
cell->AddChild(editorBounds);
if (auto focusControl = currentEditor->GetTemplate()->GetFocusControl())
{
focusControl->SetFocused();
}
dataVisualizers[column]->GetTemplate()->SetVisible(false);
}
}
void DefaultDataGridItemTemplate::NotifyCloseEditor()
{
if (currentEditor)
{
for (vint i = 0; i < dataVisualizers.Count(); i++)
{
dataVisualizers[i]->GetTemplate()->SetVisible(true);
}
auto composition = currentEditor->GetTemplate();
if (composition->GetParent())
{
composition->GetParent()->RemoveChild(composition);
}
currentEditor = nullptr;
}
}
void DefaultDataGridItemTemplate::NotifySelectCell(vint column)
{
for (vint i = 0; i < dataVisualizers.Count(); i++)
{
dataVisualizers[i]->SetSelected(i == column);
}
}
void DefaultDataGridItemTemplate::NotifyCellEdited()
{
for (vint i = 0; i < dataVisualizers.Count(); i++)
{
dataVisualizers[i]->BeforeVisualizeCell(listControl->GetItemProvider(), GetIndex(), i);
}
}
}
/***********************************************************************
GuiVirtualDataGrid (Editor)
***********************************************************************/
using namespace list;
compositions::IGuiAltActionHost* GuiVirtualDataGrid::GetActivatingAltHost()
{
if (currentEditor)
{
if (auto focusControl = currentEditor->GetTemplate()->GetFocusControl())
{
if (auto action = focusControl->QueryTypedService<IGuiAltAction>())
{
if (action->IsAltAvailable() && action->IsAltEnabled())
{
SetAltComposition(currentEditor->GetTemplate());
SetAltControl(focusControl, true);
return this;
}
}
}
}
SetAltComposition(nullptr);
SetAltControl(nullptr, false);
return GuiVirtualListView::GetActivatingAltHost();
}
void GuiVirtualDataGrid::NotifySelectionChanged(bool triggeredByItemContentModified)
{
GuiVirtualListView::NotifySelectionChanged(triggeredByItemContentModified);
if (!skipOnSelectionChanged && !triggeredByItemContentModified)
{
vint row = GetSelectedItemIndex();
if (row == selectedCell.row)
{
// do nothing
}
else if (row != -1)
{
if (selectedCell.row != row && selectedCell.column != -1)
{
SelectCell({ row,selectedCell.column }, false);
}
else
{
SelectCell({ row,0 }, false);
}
}
else
{
StopEdit();
NotifySelectCell(-1, -1);
}
}
}
void GuiVirtualDataGrid::OnItemModified(vint start, vint count, vint newCount, bool itemReferenceUpdated)
{
GuiVirtualListView::OnItemModified(start, count, newCount, itemReferenceUpdated);
if (!GetItemProvider()->IsEditing())
{
StopEdit();
}
}
void GuiVirtualDataGrid::OnStyleInstalled(vint index, ItemStyle* style, bool refreshPropertiesOnly)
{
GuiVirtualListView::OnStyleInstalled(index, style, refreshPropertiesOnly);
if (auto itemStyle = dynamic_cast<DefaultDataGridItemTemplate*>(style))
{
if (selectedCell.row == index && selectedCell.column != -1)
{
itemStyle->NotifySelectCell(selectedCell.column);
}
}
}
void GuiVirtualDataGrid::OnStyleUninstalled(ItemStyle* style)
{
GuiVirtualListView::OnStyleUninstalled(style);
if (auto itemStyle = dynamic_cast<DefaultDataGridItemTemplate*>(style))
{
if (itemStyle->IsEditorOpened())
{
itemStyle->NotifyCloseEditor();
currentEditor = nullptr;
currentEditorPos = { -1,-1 };
}
}
}
void GuiVirtualDataGrid::NotifyCloseEditor()
{
if (currentEditorPos.row != -1 && GetArranger())
{
auto style = GetArranger()->GetVisibleStyle(currentEditorPos.row);
if (auto itemStyle = dynamic_cast<DefaultDataGridItemTemplate*>(style))
{
itemStyle->NotifyCloseEditor();
}
}
}
void GuiVirtualDataGrid::NotifySelectCell(vint row, vint column)
{
if (selectedCell.row != row || selectedCell.column != column)
{
selectedCell = { row, column };
SelectedCellChanged.Execute(GetNotifyEventArguments());
auto style = GetArranger()->GetVisibleStyle(row);
if (auto itemStyle = dynamic_cast<DefaultDataGridItemTemplate*>(style))
{
itemStyle->NotifySelectCell(column);
}
}
}
bool GuiVirtualDataGrid::StartEdit(vint row, vint column)
{
StopEdit();
NotifySelectCell(row, column);
auto style = GetArranger()->GetVisibleStyle(row);
if (auto itemStyle = dynamic_cast<DefaultDataGridItemTemplate*>(style))
{
if (auto factory = dataGridView->GetCellDataEditorFactory(row, column))
{
currentEditorOpeningEditor = true;
currentEditorPos = { row,column };
currentEditor = factory->CreateEditor(this);
if (auto focusControl = currentEditor->GetTemplate()->GetFocusControl())
{
focusControl->SetAlt(L"E");
}
currentEditor->BeforeEditCell(GetItemProvider(), row, column);
itemStyle->NotifyOpenEditor(column, currentEditor.Obj());
currentEditorOpeningEditor = false;
return true;
}
}
return false;
}
void GuiVirtualDataGrid::StopEdit()
{
if (GetItemProvider()->IsEditing())
{
NotifyCloseEditor();
}
else
{
if (currentEditorPos != GridPos{-1, -1})
{
if (currentEditor)
{
NotifyCloseEditor();
}
}
}
SetAltComposition(nullptr);
SetAltControl(nullptr, false);
currentEditor = nullptr;
currentEditorPos = { -1,-1 };
}
/***********************************************************************
GuiVirtualDataGrid (IDataGridContext)
***********************************************************************/
templates::GuiListViewTemplate* GuiVirtualDataGrid::GetListViewControlTemplate()
{
return TypedControlTemplateObject(true);
}
void GuiVirtualDataGrid::RequestSaveData()
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::controls::list::DefaultTextListItemTemplate::OnBulletSelectedChanged(GuiGraphicsComposition*, GuiEventArgs&)#"
if (currentEditor && !currentEditorOpeningEditor)
{
GuiControl* focusedControl = nullptr;
if (auto controlHost = GetRelatedControlHost())
{
if (auto graphicsHost = controlHost->GetGraphicsHost())
{
if (auto focusComposition = graphicsHost->GetFocusedComposition())
{
focusedControl = focusComposition->GetRelatedControl();
}
}
}
GetItemProvider()->PushEditing();
dataGridView->SetBindingCellValue(currentEditorPos.row, currentEditorPos.column, currentEditor->GetTemplate()->GetCellValue());
CHECK_ERROR(GetItemProvider()->PopEditing(), ERROR_MESSAGE_PREFIX L"BeginEditListItem and EndEditListItem calls are not paired.");
auto style = GetArranger()->GetVisibleStyle(currentEditorPos.row);
if (auto itemStyle = dynamic_cast<DefaultDataGridItemTemplate*>(style))
{
itemStyle->NotifyCellEdited();
}
if (currentEditor && focusedControl)
{
focusedControl->SetFocused();
}
}
#undef ERROR_MESSAGE_PREFIX
}
/***********************************************************************
GuiVirtualDataGrid
***********************************************************************/
void GuiVirtualDataGrid::OnColumnClicked(compositions::GuiGraphicsComposition* sender, compositions::GuiItemEventArgs& arguments)
{
if(dataGridView->IsColumnSortable(arguments.itemIndex))
{
switch(columnItemView->GetSortingState(arguments.itemIndex))
{
case ColumnSortingState::NotSorted:
dataGridView->SortByColumn(arguments.itemIndex, true);
break;
case ColumnSortingState::Ascending:
dataGridView->SortByColumn(arguments.itemIndex, false);
break;
case ColumnSortingState::Descending:
dataGridView->SortByColumn(-1, false);
break;
}
}
}
void GuiVirtualDataGrid::OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments)
{
if (selectedCell.row != -1)
{
if (arguments.code == VKEY::KEY_RETURN)
{
RequestSaveData();
SelectCell(selectedCell, !currentEditor);
arguments.handled = true;
if (!currentEditor)
{
SetFocused();
}
arguments.handled = true;
}
else if (arguments.code == VKEY::KEY_ESCAPE)
{
if (currentEditor)
{
SelectCell(currentEditorPos, false);
SetFocused();
arguments.handled = true;
}
}
else
{
vint columnOffset = 0;
switch (arguments.code)
{
case VKEY::KEY_LEFT:
columnOffset = -1;
arguments.handled = true;
break;
case VKEY::KEY_RIGHT:
columnOffset = 1;
arguments.handled = true;
break;
default:
return;
}
vint column = selectedCell.column + columnOffset;
if (column < 0)
{
column = 0;
}
else if (column >= listViewItemView->GetColumnCount())
{
column = listViewItemView->GetColumnCount();
}
SelectCell({ selectedCell.row, column }, false);
}
}
}
void GuiVirtualDataGrid::OnKeyUp(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments)
{
}
GuiVirtualDataGrid::GuiVirtualDataGrid(theme::ThemeName themeName, list::IItemProvider* _itemProvider)
:GuiVirtualListView(themeName, _itemProvider)
{
listViewItemView = dynamic_cast<IListViewItemView*>(_itemProvider->RequestView(WString::Unmanaged(IListViewItemView::Identifier)));
columnItemView = dynamic_cast<ListViewColumnItemArranger::IColumnItemView*>(_itemProvider->RequestView(WString::Unmanaged(ListViewColumnItemArranger::IColumnItemView::Identifier)));
dataGridView = dynamic_cast<IDataGridView*>(_itemProvider->RequestView(WString::Unmanaged(IDataGridView::Identifier)));
{
auto mainProperty = [](const Value&) { return new MainColumnVisualizerTemplate; };
auto subProperty = [](const Value&) { return new SubColumnVisualizerTemplate; };
auto focusRectangleProperty = [](const Value&) { return new FocusRectangleVisualizerTemplate; };
auto cellBorderProperty = [](const Value&) { return new CellBorderVisualizerTemplate; };
defaultMainColumnVisualizerFactory =
Ptr(new DataVisualizerFactory(cellBorderProperty,
Ptr(new DataVisualizerFactory(focusRectangleProperty,
Ptr(new DataVisualizerFactory(mainProperty)
)))));
defaultSubColumnVisualizerFactory =
Ptr(new DataVisualizerFactory(cellBorderProperty,
Ptr(new DataVisualizerFactory(focusRectangleProperty,
Ptr(new DataVisualizerFactory(subProperty)
)))));
}
CHECK_ERROR(listViewItemView != nullptr, L"GuiVirtualDataGrid::GuiVirtualDataGrid(IStyleController*, GuiListControl::IItemProvider*)#Missing IListViewItemView from item provider.");
CHECK_ERROR(columnItemView != nullptr, L"GuiVirtualDataGrid::GuiVirtualDataGrid(IStyleController*, GuiListControl::IItemProvider*)#Missing ListViewColumnItemArranger::IColumnItemView from item provider.");
CHECK_ERROR(dataGridView != nullptr, L"GuiVirtualDataGrid::GuiVirtualDataGrid(IStyleController*, GuiListControl::IItemProvider*)#Missing IDataGridView from item provider.");
SetViewToDefault();
ColumnClicked.AttachMethod(this, &GuiVirtualDataGrid::OnColumnClicked);
focusableComposition->GetEventReceiver()->keyDown.AttachMethod(this, &GuiVirtualDataGrid::OnKeyDown);
focusableComposition->GetEventReceiver()->keyUp.AttachMethod(this, &GuiVirtualDataGrid::OnKeyUp);
SelectedCellChanged.SetAssociatedComposition(boundsComposition);
}
GuiVirtualDataGrid::~GuiVirtualDataGrid()
{
}
list::IItemProvider* GuiVirtualDataGrid::GetItemProvider()
{
return GuiVirtualListView::GetItemProvider();
}
void GuiVirtualDataGrid::SetViewToDefault()
{
SetStyleAndArranger(
[](const Value&) { return new list::DefaultDataGridItemTemplate; },
Ptr(new list::ListViewColumnItemArranger)
);
}
GridPos GuiVirtualDataGrid::GetSelectedCell()
{
return selectedCell;
}
Ptr<list::IDataEditor> GuiVirtualDataGrid::GetOpenedEditor()
{
return currentEditor;
}
bool GuiVirtualDataGrid::SelectCell(const GridPos& value, bool openEditor)
{
bool validPos = 0 <= value.row && value.row < GetItemProvider()->Count() && 0 <= value.column && value.column < listViewItemView->GetColumnCount();
if (validPos && selectedCell == value)
{
if (currentEditor && !openEditor)
{
StopEdit();
}
else if (!currentEditor && openEditor)
{
StartEdit(value.row, value.column);
}
return currentEditor != nullptr;
}
StopEdit();
if (validPos)
{
NotifySelectCell(value.row, value.column);
if (openEditor)
{
EnsureItemVisible(value.row);
if (GetMultiSelect())
{
ClearSelection();
}
}
skipOnSelectionChanged = true;
SetSelected(value.row, true);
skipOnSelectionChanged = false;
if (openEditor)
{
return StartEdit(value.row, value.column);
}
}
else
{
NotifySelectCell(-1, -1);
ClearSelection();
}
return false;
}
}
}
}
/***********************************************************************
.\CONTROLS\LISTCONTROLPACKAGE\GUIDATAGRIDEXTENSIONS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
namespace list
{
using namespace compositions;
using namespace elements;
using namespace theme;
using namespace templates;
/***********************************************************************
DataVisualizerBase
***********************************************************************/
DataVisualizerBase::DataVisualizerBase()
{
}
DataVisualizerBase::~DataVisualizerBase()
{
if (visualizerTemplate)
{
SafeDeleteComposition(visualizerTemplate);
}
}
IDataVisualizerFactory* DataVisualizerBase::GetFactory()
{
return factory;
}
templates::GuiGridVisualizerTemplate* DataVisualizerBase::GetTemplate()
{
return visualizerTemplate;
}
void DataVisualizerBase::NotifyDeletedTemplate()
{
visualizerTemplate = nullptr;
}
void DataVisualizerBase::BeforeVisualizeCell(list::IItemProvider* itemProvider, vint row, vint column)
{
if (auto listViewItemView = dynamic_cast<IListViewItemView*>(dataGridContext->GetItemProvider()->RequestView(WString::Unmanaged(IListViewItemView::Identifier))))
{
auto style = dataGridContext->GetListViewControlTemplate();
visualizerTemplate->SetPrimaryTextColor(style->GetPrimaryTextColor());
visualizerTemplate->SetSecondaryTextColor(style->GetSecondaryTextColor());
visualizerTemplate->SetItemSeparatorColor(style->GetItemSeparatorColor());
visualizerTemplate->SetLargeImage(listViewItemView->GetLargeImage(row));
visualizerTemplate->SetSmallImage(listViewItemView->GetSmallImage(row));
visualizerTemplate->SetText(column == 0 ? listViewItemView->GetText(row) : listViewItemView->GetSubItem(row, column - 1));
}
if (auto dataGridView = dynamic_cast<IDataGridView*>(dataGridContext->GetItemProvider()->RequestView(WString::Unmanaged(IDataGridView::Identifier))))
{
visualizerTemplate->SetRowValue(itemProvider->GetBindingValue(row));
visualizerTemplate->SetCellValue(dataGridView->GetBindingCellValue(row, column));
}
}
void DataVisualizerBase::SetSelected(bool value)
{
if (visualizerTemplate)
{
visualizerTemplate->SetSelected(value);
}
}
/***********************************************************************
DataVisualizerFactory
***********************************************************************/
DataVisualizerFactory::ItemTemplate* DataVisualizerFactory::CreateItemTemplate(controls::list::IDataGridContext* dataGridContext)
{
ItemTemplate* itemTemplate = templateFactory({});
CHECK_ERROR(itemTemplate, L"DataVisualizerFactory::CreateItemTemplate(IDataGridContext*)#An instance of GuiGridEditorTemplate is expected.");
if (decoratedFactory)
{
auto childTemplate = decoratedFactory->CreateItemTemplate(dataGridContext);
childTemplate->SetAlignmentToParent(Margin(0, 0, 0, 0));
itemTemplate->GetContainerComposition()->AddChild(childTemplate);
#define FORWARD_EVENT(NAME)\
itemTemplate->NAME##Changed.AttachLambda([=](GuiGraphicsComposition* sender, GuiEventArgs& arguments)\
{\
childTemplate->Set##NAME(itemTemplate->Get##NAME());\
});\
#define FORWARD_EVENT_IMPL(CLASS, TYPE, NAME, VALUE) FORWARD_EVENT(NAME)
GuiTemplate_PROPERTIES(FORWARD_EVENT_IMPL)
GuiControlTemplate_PROPERTIES(FORWARD_EVENT_IMPL)
GuiGridCellTemplate_PROPERTIES(FORWARD_EVENT_IMPL)
GuiGridVisualizerTemplate_PROPERTIES(FORWARD_EVENT_IMPL)
#undef FORWARD_EVENT_IMPL
#undef FORWARD_EVENT
}
return itemTemplate;
}
DataVisualizerFactory::DataVisualizerFactory(TemplateProperty<ItemTemplate> _templateFactory, Ptr<DataVisualizerFactory> _decoratedFactory)
:templateFactory(_templateFactory)
, decoratedFactory(_decoratedFactory)
{
}
DataVisualizerFactory::~DataVisualizerFactory()
{
}
Ptr<controls::list::IDataVisualizer> DataVisualizerFactory::CreateVisualizer(controls::list::IDataGridContext* dataGridContext)
{
auto dataVisualizer = Ptr(new DataVisualizerBase);
dataVisualizer->factory = this;
dataVisualizer->dataGridContext = dataGridContext;
dataVisualizer->visualizerTemplate = CreateItemTemplate(dataGridContext);
return dataVisualizer;
}
/***********************************************************************
DataEditorBase
***********************************************************************/
void DataEditorBase::OnCellValueChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
dataGridContext->RequestSaveData();
}
DataEditorBase::DataEditorBase()
{
}
DataEditorBase::~DataEditorBase()
{
if (editorTemplate)
{
SafeDeleteComposition(editorTemplate);
}
}
IDataEditorFactory* DataEditorBase::GetFactory()
{
return factory;
}
templates::GuiGridEditorTemplate* DataEditorBase::GetTemplate()
{
return editorTemplate;
}
void DataEditorBase::NotifyDeletedTemplate()
{
editorTemplate = nullptr;
}
void DataEditorBase::BeforeEditCell(list::IItemProvider* itemProvider, vint row, vint column)
{
if (auto listViewItemView = dynamic_cast<IListViewItemView*>(dataGridContext->GetItemProvider()->RequestView(WString::Unmanaged(IListViewItemView::Identifier))))
{
auto style = dataGridContext->GetListViewControlTemplate();
editorTemplate->SetPrimaryTextColor(style->GetPrimaryTextColor());
editorTemplate->SetSecondaryTextColor(style->GetSecondaryTextColor());
editorTemplate->SetItemSeparatorColor(style->GetItemSeparatorColor());
editorTemplate->SetLargeImage(listViewItemView->GetLargeImage(row));
editorTemplate->SetSmallImage(listViewItemView->GetSmallImage(row));
editorTemplate->SetText(column == 0 ? listViewItemView->GetText(row) : listViewItemView->GetSubItem(row, column - 1));
}
if (auto dataGridView = dynamic_cast<IDataGridView*>(dataGridContext->GetItemProvider()->RequestView(WString::Unmanaged(IDataGridView::Identifier))))
{
editorTemplate->SetRowValue(itemProvider->GetBindingValue(row));
editorTemplate->SetCellValue(dataGridView->GetBindingCellValue(row, column));
}
editorTemplate->CellValueChanged.AttachMethod(this, &DataEditorBase::OnCellValueChanged);
}
bool DataEditorBase::GetCellValueSaved()
{
if (editorTemplate)
{
return editorTemplate->GetCellValueSaved();
}
return true;
}
/***********************************************************************
DataEditorFactory
***********************************************************************/
DataEditorFactory::DataEditorFactory(TemplateProperty<GuiGridEditorTemplate> _templateFactory)
:templateFactory(_templateFactory)
{
}
DataEditorFactory::~DataEditorFactory()
{
}
Ptr<IDataEditor> DataEditorFactory::CreateEditor(controls::list::IDataGridContext* dataGridContext)
{
auto editor = Ptr(new DataEditorBase);
editor->factory = this;
editor->dataGridContext = dataGridContext;
ItemTemplate* itemTemplate = templateFactory({});
CHECK_ERROR(itemTemplate, L"DataEditorFactory::CreateEditor(IDataGridContext*)#An instance of GuiGridEditorTemplate is expected.");
editor->editorTemplate = itemTemplate;
return editor;
}
/***********************************************************************
MainColumnVisualizerTemplate
***********************************************************************/
void MainColumnVisualizerTemplate::OnTextChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
text->SetText(GetText());
}
void MainColumnVisualizerTemplate::OnFontChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
text->SetFont(GetFont());
}
void MainColumnVisualizerTemplate::OnTextColorChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
text->SetColor(GetPrimaryTextColor());
}
void MainColumnVisualizerTemplate::OnSmallImageChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
auto imageData = GetSmallImage();
if (imageData)
{
image->SetImage(imageData->GetImage(), imageData->GetFrameIndex());
}
else
{
image->SetImage(nullptr);
}
}
MainColumnVisualizerTemplate::MainColumnVisualizerTemplate()
{
GuiTableComposition* table = new GuiTableComposition;
table->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
table->SetRowsAndColumns(3, 2);
table->SetRowOption(0, GuiCellOption::PercentageOption(0.5));
table->SetRowOption(1, GuiCellOption::MinSizeOption());
table->SetRowOption(2, GuiCellOption::PercentageOption(0.5));
table->SetColumnOption(0, GuiCellOption::MinSizeOption());
table->SetColumnOption(1, GuiCellOption::PercentageOption(1.0));
table->SetCellPadding(2);
{
GuiCellComposition* cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(1, 0, 1, 1);
cell->SetPreferredMinSize(Size(16, 16));
image = GuiImageFrameElement::Create();
image->SetStretch(true);
cell->SetOwnedElement(Ptr(image));
}
{
GuiCellComposition* cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(0, 1, 3, 1);
auto textBounds = new GuiBoundsComposition;
cell->AddChild(textBounds);
textBounds->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElement);
textBounds->SetAlignmentToParent(Margin(0, 0, 8, 0));
text = GuiSolidLabelElement::Create();
text->SetAlignments(Alignment::Left, Alignment::Center);
text->SetEllipse(true);
textBounds->SetOwnedElement(Ptr(text));
}
table->SetAlignmentToParent(Margin(0, 0, 0, 0));
SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
AddChild(table);
TextChanged.AttachMethod(this, &MainColumnVisualizerTemplate::OnTextChanged);
FontChanged.AttachMethod(this, &MainColumnVisualizerTemplate::OnFontChanged);
PrimaryTextColorChanged.AttachMethod(this, &MainColumnVisualizerTemplate::OnTextColorChanged);
SmallImageChanged.AttachMethod(this, &MainColumnVisualizerTemplate::OnSmallImageChanged);
TextChanged.Execute(compositions::GuiEventArgs(this));
FontChanged.Execute(compositions::GuiEventArgs(this));
PrimaryTextColorChanged.Execute(compositions::GuiEventArgs(this));
SmallImageChanged.Execute(compositions::GuiEventArgs(this));
}
MainColumnVisualizerTemplate::~MainColumnVisualizerTemplate()
{
}
/***********************************************************************
SubColumnVisualizerTemplate
***********************************************************************/
void SubColumnVisualizerTemplate::OnTextChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
text->SetText(GetText());
}
void SubColumnVisualizerTemplate::OnFontChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
text->SetFont(GetFont());
}
void SubColumnVisualizerTemplate::OnTextColorChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
text->SetColor(GetSecondaryTextColor());
}
void SubColumnVisualizerTemplate::Initialize(bool fixTextColor)
{
SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
auto textBounds = new GuiBoundsComposition;
AddChild(textBounds);
textBounds->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElement);
textBounds->SetAlignmentToParent(Margin(8, 0, 8, 0));
text = GuiSolidLabelElement::Create();
text->SetVerticalAlignment(Alignment::Center);
text->SetEllipse(true);
textBounds->SetOwnedElement(Ptr(text));
TextChanged.AttachMethod(this, &SubColumnVisualizerTemplate::OnTextChanged);
FontChanged.AttachMethod(this, &SubColumnVisualizerTemplate::OnFontChanged);
if (!fixTextColor)
{
SecondaryTextColorChanged.AttachMethod(this, &SubColumnVisualizerTemplate::OnTextColorChanged);
}
TextChanged.Execute(compositions::GuiEventArgs(this));
FontChanged.Execute(compositions::GuiEventArgs(this));
if (!fixTextColor)
{
SecondaryTextColorChanged.Execute(compositions::GuiEventArgs(this));
}
}
SubColumnVisualizerTemplate::SubColumnVisualizerTemplate(bool fixTextColor)
{
Initialize(fixTextColor);
}
SubColumnVisualizerTemplate::SubColumnVisualizerTemplate()
{
Initialize(false);
}
SubColumnVisualizerTemplate::~SubColumnVisualizerTemplate()
{
}
/***********************************************************************
HyperlinkVisualizerTemplate
***********************************************************************/
void HyperlinkVisualizerTemplate::label_MouseEnter(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
FontProperties font = text->GetFont();
font.underline = true;
text->SetFont(font);
}
void HyperlinkVisualizerTemplate::label_MouseLeave(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
FontProperties font = text->GetFont();
font.underline = false;
text->SetFont(font);
}
HyperlinkVisualizerTemplate::HyperlinkVisualizerTemplate()
:SubColumnVisualizerTemplate(true)
{
text->SetColor(Color(0, 0, 255));
text->SetEllipse(true);
GetEventReceiver()->mouseEnter.AttachMethod(this, &HyperlinkVisualizerTemplate::label_MouseEnter);
GetEventReceiver()->mouseLeave.AttachMethod(this, &HyperlinkVisualizerTemplate::label_MouseLeave);
SetAssociatedCursor(GetCurrentController()->ResourceService()->GetSystemCursor(INativeCursor::Hand));
}
HyperlinkVisualizerTemplate::~HyperlinkVisualizerTemplate()
{
}
/***********************************************************************
CellBorderVisualizerTemplate
***********************************************************************/
void FocusRectangleVisualizerTemplate::OnSelectedChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
focusComposition->SetVisible(GetSelected());
}
FocusRectangleVisualizerTemplate::FocusRectangleVisualizerTemplate()
{
SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
focusComposition = new GuiBoundsComposition();
{
auto focus = Ptr(GuiFocusRectangleElement::Create());
focusComposition->SetOwnedElement(focus);
focusComposition->SetAlignmentToParent(Margin(1, 1, 1, 1));
}
auto container = new GuiBoundsComposition();
{
container->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
container->SetAlignmentToParent(Margin(2, 2, 2, 2));
}
AddChild(focusComposition);
AddChild(container);
SetContainerComposition(container);
SelectedChanged.AttachMethod(this, &FocusRectangleVisualizerTemplate::OnSelectedChanged);
SelectedChanged.Execute(compositions::GuiEventArgs(this));
}
FocusRectangleVisualizerTemplate::~FocusRectangleVisualizerTemplate()
{
}
/***********************************************************************
CellBorderVisualizerTemplate
***********************************************************************/
void CellBorderVisualizerTemplate::OnItemSeparatorColorChanged(GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
border1->SetColor(GetItemSeparatorColor());
border2->SetColor(GetItemSeparatorColor());
}
CellBorderVisualizerTemplate::CellBorderVisualizerTemplate()
{
SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
auto bounds1 = new GuiBoundsComposition;
{
border1 = GuiSolidBorderElement::Create();
bounds1->SetOwnedElement(Ptr(border1));
bounds1->SetAlignmentToParent(Margin(-1, 0, 0, 0));
}
auto bounds2 = new GuiBoundsComposition;
{
border2 = GuiSolidBorderElement::Create();
bounds2->SetOwnedElement(Ptr(border2));
bounds2->SetAlignmentToParent(Margin(0, -1, 0, 0));
}
auto container = new GuiBoundsComposition();
{
container->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
container->SetAlignmentToParent(Margin(0, 0, 1, 1));
}
AddChild(bounds1);
AddChild(bounds2);
AddChild(container);
SetContainerComposition(container);
ItemSeparatorColorChanged.AttachMethod(this, &CellBorderVisualizerTemplate::OnItemSeparatorColorChanged);
ItemSeparatorColorChanged.Execute(compositions::GuiEventArgs(this));
}
CellBorderVisualizerTemplate::~CellBorderVisualizerTemplate()
{
}
}
}
}
}
/***********************************************************************
.\CONTROLS\LISTCONTROLPACKAGE\GUILISTCONTROLITEMARRANGERS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace collections;
using namespace elements;
using namespace compositions;
namespace list
{
/***********************************************************************
RangedItemArrangerBase (ItemSource)
***********************************************************************/
class ArrangerItemSource : public Object, public virtual description::IValueObservableList
{
protected:
list::IItemProvider* itemProvider = nullptr;
public:
ArrangerItemSource(list::IItemProvider* _itemProvider)
: itemProvider(_itemProvider)
{
}
vint GetCount() override
{
return itemProvider->Count();
}
description::Value Get(vint index) override
{
return itemProvider->GetBindingValue(index);
}
Ptr<description::IValueEnumerator> CreateEnumerator() override { CHECK_FAIL(L"ArrangerItemSource::CreateEnumerator should not be called."); }
bool Contains(const description::Value& value) override { CHECK_FAIL(L"ArrangerItemSource::Contains should not be called."); }
vint IndexOf(const description::Value& value) override { CHECK_FAIL(L"ArrangerItemSource::IndexOf should not be called."); }
void Set(vint index, const description::Value& value) override { CHECK_FAIL(L"ArrangerItemSource::Set should not be called."); }
vint Add(const description::Value& value) override { CHECK_FAIL(L"ArrangerItemSource::Add should not be called."); }
vint Insert(vint index, const description::Value& value) override { CHECK_FAIL(L"ArrangerItemSource::Insert should not be called."); }
bool Remove(const description::Value& value) override { CHECK_FAIL(L"ArrangerItemSource::Remove should not be called."); }
bool RemoveAt(vint index) override { CHECK_FAIL(L"ArrangerItemSource::RemoveAt should not be called."); }
void Clear() override { CHECK_FAIL(L"ArrangerItemSource::Clear should not be called."); }
};
/***********************************************************************
RangedItemArrangerBase
***********************************************************************/
void RangedItemArrangerBase::OnViewLocationChanged(compositions::GuiGraphicsComposition* composition, compositions::GuiEventArgs& arguments)
{
if (callback)
{
callback->SetViewLocation(repeat->GetViewLocation());
}
}
void RangedItemArrangerBase::OnTotalSizeChanged(compositions::GuiGraphicsComposition* composition, compositions::GuiEventArgs& arguments)
{
if (callback)
{
callback->OnTotalSizeChanged();
}
}
void RangedItemArrangerBase::OnAdoptedSizeInvalidated(compositions::GuiGraphicsComposition* composition, compositions::GuiEventArgs& arguments)
{
if (callback)
{
callback->OnAdoptedSizeChanged();
}
}
RangedItemArrangerBase::RangedItemArrangerBase(compositions::GuiVirtualRepeatCompositionBase* _repeat)
: repeat(_repeat)
{
repeat->ViewLocationChanged.AttachMethod(this, &RangedItemArrangerBase::OnViewLocationChanged);
repeat->TotalSizeChanged.AttachMethod(this, &RangedItemArrangerBase::OnTotalSizeChanged);
repeat->AdoptedSizeInvalidated.AttachMethod(this, &RangedItemArrangerBase::OnAdoptedSizeInvalidated);
}
RangedItemArrangerBase::~RangedItemArrangerBase()
{
SafeDeleteComposition(repeat);
}
void RangedItemArrangerBase::OnAttached(list::IItemProvider* provider)
{
itemProvider = provider;
if (provider)
{
itemSource = Ptr(new ArrangerItemSource(provider));
repeat->SetItemSource(itemSource);
}
else
{
repeat->SetItemSource(nullptr);
itemSource = nullptr;
}
}
void RangedItemArrangerBase::OnItemModified(vint start, vint count, vint newCount, bool itemReferenceUpdated)
{
if (itemSource && itemReferenceUpdated)
{
itemSource->ItemChanged(start, count, newCount);
}
}
void RangedItemArrangerBase::AttachListControl(GuiListControl* value)
{
listControl = value;
repeat->SetAxis(Ptr(listControl->GetAxis()));
}
void RangedItemArrangerBase::DetachListControl()
{
repeat->SetAxis(nullptr);
listControl = nullptr;
}
GuiListControl::IItemArrangerCallback* RangedItemArrangerBase::GetCallback()
{
return callback;
}
void RangedItemArrangerBase::SetCallback(GuiListControl::IItemArrangerCallback* value)
{
if (callback != value)
{
if (callback)
{
repeat->GetParent()->RemoveChild(repeat);
repeat->SetItemTemplate({});
}
callback = value;
if (callback)
{
callback->GetContainerComposition()->AddChild(repeat);
repeat->SetItemTemplate([](const description::Value&)->templates::GuiTemplate*
{
CHECK_FAIL(L"This function should not be called, it is used to enable the virtual repeat composition.");
});
}
}
}
Size RangedItemArrangerBase::GetTotalSize()
{
if (callback && repeat)
{
return repeat->GetTotalSize();
}
return Size(0, 0);
}
GuiListControl::ItemStyle* RangedItemArrangerBase::GetVisibleStyle(vint itemIndex)
{
auto bounds = repeat->GetVisibleStyle(itemIndex);
return bounds ? callback->GetItem(bounds) : nullptr;
}
vint RangedItemArrangerBase::GetVisibleIndex(GuiListControl::ItemStyle* style)
{
auto bounds = callback->GetItemBounds(style);
return repeat->GetVisibleIndex(bounds);
}
void RangedItemArrangerBase::ReloadVisibleStyles()
{
if (repeat) repeat->ResetLayout(true);
}
void RangedItemArrangerBase::OnViewChanged(Rect bounds)
{
repeat->SetViewLocation(bounds.LeftTop());
repeat->SetExpectedBounds(Rect({ 0,0 }, bounds.GetSize()));
}
vint RangedItemArrangerBase::FindItemByVirtualKeyDirection(vint itemIndex, compositions::KeyDirection key)
{
return repeat->FindItemByVirtualKeyDirection(itemIndex, key);
}
GuiListControl::EnsureItemVisibleResult RangedItemArrangerBase::EnsureItemVisible(vint itemIndex)
{
switch (repeat->EnsureItemVisible(itemIndex))
{
case VirtualRepeatEnsureItemVisibleResult::Moved:
return GuiListControl::EnsureItemVisibleResult::Moved;
case VirtualRepeatEnsureItemVisibleResult::NotMoved:
return GuiListControl::EnsureItemVisibleResult::NotMoved;
default:
return GuiListControl::EnsureItemVisibleResult::ItemNotExists;
}
}
Size RangedItemArrangerBase::GetAdoptedSize(Size expectedSize)
{
return repeat->GetAdoptedSize(expectedSize);
}
/***********************************************************************
VirtualRepeatRangedItemArrangerBase
***********************************************************************/
FreeHeightItemArranger::FreeHeightItemArranger()
{
}
FreeHeightItemArranger::~FreeHeightItemArranger()
{
}
FixedHeightItemArranger::FixedHeightItemArranger()
{
}
FixedHeightItemArranger::~FixedHeightItemArranger()
{
}
FixedSizeMultiColumnItemArranger::FixedSizeMultiColumnItemArranger()
{
}
FixedSizeMultiColumnItemArranger::~FixedSizeMultiColumnItemArranger()
{
}
FixedHeightMultiColumnItemArranger::FixedHeightMultiColumnItemArranger()
{
}
FixedHeightMultiColumnItemArranger::~FixedHeightMultiColumnItemArranger()
{
}
}
}
}
}
/***********************************************************************
.\CONTROLS\LISTCONTROLPACKAGE\GUILISTCONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace collections;
using namespace elements;
using namespace compositions;
/***********************************************************************
GuiListControl::ItemCallback
***********************************************************************/
GuiListControl::ItemStyleRecord GuiListControl::ItemCallback::InstallStyle(ItemStyle* style, vint itemIndex)
{
templates::GuiTemplate* bounds = style;
if (listControl->GetDisplayItemBackground())
{
style->SetAlignmentToParent(Margin(0, 0, 0, 0));
auto backgroundButton = new GuiSelectableButton(theme::ThemeName::ListItemBackground);
if (auto backgroundStyle = listControl->TypedControlTemplateObject(true)->GetBackgroundTemplate())
{
backgroundButton->SetControlTemplate(backgroundStyle);
}
backgroundButton->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
backgroundButton->SetAutoFocus(false);
backgroundButton->SetAutoSelection(false);
backgroundButton->SetSelected(style->GetSelected());
backgroundButton->GetContainerComposition()->AddChild(style);
bounds = new templates::GuiTemplate;
bounds->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
bounds->AddChild(backgroundButton->GetBoundsComposition());
style->SelectedChanged.AttachLambda([=](GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
backgroundButton->SetSelected(style->GetSelected());
});
}
listControl->OnStyleInstalled(itemIndex, style, false);
return { style,bounds };
}
GuiListControl::ItemStyleRecord GuiListControl::ItemCallback::UninstallStyle(vint index)
{
auto style = installedStyles.Keys()[index];
auto bounds = installedStyles.Values()[index];
listControl->OnStyleUninstalled(style);
return { style,bounds };
}
GuiListControl::ItemCallback::ItemCallback(GuiListControl* _listControl)
:listControl(_listControl)
{
}
GuiListControl::ItemCallback::~ItemCallback()
{
ClearCache();
}
void GuiListControl::ItemCallback::ClearCache()
{
// TODO: (enumerable) foreach:indexed
for (vint i = 0; i < installedStyles.Count(); i++)
{
auto [style, bounds] = UninstallStyle(i);
SafeDeleteComposition(bounds);
}
installedStyles.Clear();
}
void GuiListControl::ItemCallback::OnAttached(list::IItemProvider* provider)
{
itemProvider = provider;
}
void GuiListControl::ItemCallback::OnItemModified(vint start, vint count, vint newCount, bool itemReferenceUpdated)
{
listControl->OnItemModified(start, count, newCount, itemReferenceUpdated);
}
GuiListControl::ItemStyle* GuiListControl::ItemCallback::CreateItem(vint itemIndex)
{
#define ERROR_MESSAGE_PREFIX L"GuiListControl::ItemCallback::RequestItem(vint)#"
CHECK_ERROR(0 <= itemIndex && itemIndex < itemProvider->Count(), ERROR_MESSAGE_PREFIX L"Index out of range.");
CHECK_ERROR(listControl->itemStyleProperty, ERROR_MESSAGE_PREFIX L"SetItemTemplate function should be called before adding items to the list control.");
auto style = listControl->itemStyleProperty(itemProvider->GetBindingValue(itemIndex));
auto record = InstallStyle(style, itemIndex);
installedStyles.Add(record);
return style;
#undef ERROR_MESSAGE_PREFIX
}
GuiListControl::ItemStyleBounds* GuiListControl::ItemCallback::GetItemBounds(ItemStyle * style)
{
#define ERROR_MESSAGE_PREFIX L"GuiListControl::ItemCallback::GetItemBounds(GuiListItemTemplate*)#The style is not created from CreateItem."
vint index = installedStyles.Keys().IndexOf(style);
CHECK_ERROR(index != -1, ERROR_MESSAGE_PREFIX);
return installedStyles.Values()[index];
#undef ERROR_MESSAGE_PREFIX
}
GuiListControl::ItemStyle* GuiListControl::ItemCallback::GetItem(ItemStyleBounds* bounds)
{
#define ERROR_MESSAGE_PREFIX L"GuiListControl::ItemCallback::GetItem(GuiTemplate*)#The bounds is not created from CreateItem."
auto style = dynamic_cast<ItemStyle*>(bounds);
if (style) return style;
CHECK_ERROR(bounds->Children().Count() == 1, ERROR_MESSAGE_PREFIX);
auto backgroundButton = dynamic_cast<GuiSelectableButton*>(bounds->Children()[0]->GetAssociatedControl());
CHECK_ERROR(backgroundButton != nullptr, ERROR_MESSAGE_PREFIX);
CHECK_ERROR(backgroundButton->GetContainerComposition()->Children().Count() == 1, ERROR_MESSAGE_PREFIX);
style = dynamic_cast<ItemStyle*>(backgroundButton->GetContainerComposition()->Children()[0]);
CHECK_ERROR(style != nullptr, ERROR_MESSAGE_PREFIX);
vint index = installedStyles.Keys().IndexOf(style);
CHECK_ERROR(index != -1, ERROR_MESSAGE_PREFIX);
CHECK_ERROR(installedStyles.Values()[index] == bounds, ERROR_MESSAGE_PREFIX);
return style;
#undef ERROR_MESSAGE_PREFIX
}
void GuiListControl::ItemCallback::ReleaseItem(ItemStyle* style)
{
#define ERROR_MESSAGE_PREFIX L"GuiListControl::ItemCallback::GetItemBounds(GuiListItemTemplate*)#The style is not created from CreateItem."
vint index = installedStyles.Keys().IndexOf(style);
CHECK_ERROR(index != -1, ERROR_MESSAGE_PREFIX);
auto bounds = UninstallStyle(index).value;
installedStyles.Remove(style);
SafeDeleteComposition(bounds);
#undef ERROR_MESSAGE_PREFIX
}
void GuiListControl::ItemCallback::SetViewLocation(Point value)
{
listControl->SetViewPosition(value);
}
compositions::GuiGraphicsComposition* GuiListControl::ItemCallback::GetContainerComposition()
{
return listControl->GetContainerComposition();
}
void GuiListControl::ItemCallback::OnTotalSizeChanged()
{
listControl->CalculateView();
}
void GuiListControl::ItemCallback::OnAdoptedSizeChanged()
{
listControl->AdoptedSizeInvalidated.Execute(listControl->GetNotifyEventArguments());
}
/***********************************************************************
GuiListControl
***********************************************************************/
void GuiListControl::BeforeControlTemplateUninstalled_()
{
}
void GuiListControl::AfterControlTemplateInstalled_(bool initialize)
{
if (itemArranger)
{
itemArranger->ReloadVisibleStyles();
CalculateView();
}
}
void GuiListControl::OnItemModified(vint start, vint count, vint newCount, bool itemReferenceUpdated)
{
// this function is executed before RangedItemArrangerBase::OnItemModified
// but we only handle itemReferenceUpdated==false
// so RangedItemArrangerBase::GetVisibleStyle is good here
// even it is possible that the style object will be replaced later
// OnStyleInstalled will be executed on affected style objects anyway
if (!itemReferenceUpdated && itemArranger && count == newCount)
{
for (vint i = 0; i < newCount; i++)
{
vint index = start + i;
if (auto style = itemArranger->GetVisibleStyle(index))
{
OnStyleInstalled(index, style, true);
}
}
}
}
void GuiListControl::OnStyleInstalled(vint itemIndex, ItemStyle* style, bool refreshPropertiesOnly)
{
style->SetFont(GetDisplayFont());
style->SetContext(GetContext());
style->SetText(itemProvider->GetTextValue(itemIndex));
style->SetVisuallyEnabled(GetVisuallyEnabled());
style->SetSelected(false);
style->SetIndex(itemIndex);
style->SetAssociatedListControl(this);
if (!refreshPropertiesOnly)
{
AttachItemEvents(style);
}
}
void GuiListControl::OnStyleUninstalled(ItemStyle* style)
{
DetachItemEvents(style);
}
void GuiListControl::OnRenderTargetChanged(elements::IGuiGraphicsRenderTarget* renderTarget)
{
SetStyleAndArranger(itemStyleProperty, itemArranger);
GuiScrollView::OnRenderTargetChanged(renderTarget);
}
void GuiListControl::OnBeforeReleaseGraphicsHost()
{
GuiScrollView::OnBeforeReleaseGraphicsHost();
SetStyleAndArranger({}, nullptr);
}
Size GuiListControl::QueryFullSize()
{
fullSize = itemArranger ? itemArranger->GetTotalSize() : Size(0, 0);
return fullSize;
}
void GuiListControl::UpdateView(Rect viewBounds)
{
if (itemArranger)
{
itemArranger->OnViewChanged(viewBounds);
}
}
void GuiListControl::OnBoundsMouseButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if(GetVisuallyEnabled())
{
SetFocused();
}
}
void GuiListControl::SetStyleAndArranger(ItemStyleProperty styleProperty, Ptr<IItemArranger> arranger)
{
if (itemArranger)
{
itemProvider->DetachCallback(itemArranger.Obj());
itemArranger->DetachListControl();
itemArranger->SetCallback(nullptr);
}
callback->ClearCache();
itemStyleProperty = styleProperty;
itemArranger = arranger;
if (itemArranger)
{
itemArranger->SetCallback(callback.Obj());
itemArranger->AttachListControl(this);
itemProvider->AttachCallback(itemArranger.Obj());
}
if (auto scroll = GetVerticalScroll())
{
scroll->SetPosition(0);
}
if (auto scroll = GetHorizontalScroll())
{
scroll->SetPosition(0);
}
CalculateView();
}
void GuiListControl::UpdateDisplayFont()
{
GuiControl::UpdateDisplayFont();
for (auto style : visibleStyles.Keys())
{
style->SetFont(GetDisplayFont());
}
}
void GuiListControl::OnVisuallyEnabledChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
for (auto style : visibleStyles.Keys())
{
style->SetVisuallyEnabled(GetVisuallyEnabled());
}
}
void GuiListControl::OnContextChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
for (auto style : visibleStyles.Keys())
{
style->SetContext(GetContext());
}
}
void GuiListControl::OnItemMouseEvent(compositions::GuiItemMouseEvent& itemEvent, ItemStyle* style, compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if (itemArranger && GetVisuallyEnabled())
{
vint itemIndex = itemArranger->GetVisibleIndex(style);
if (itemIndex != -1)
{
GuiItemMouseEventArgs redirectArguments;
(GuiMouseEventArgs&)redirectArguments = arguments;
redirectArguments.compositionSource = boundsComposition;
redirectArguments.eventSource = boundsComposition;
redirectArguments.itemIndex = itemIndex;
itemEvent.Execute(redirectArguments);
arguments = redirectArguments;
}
}
}
void GuiListControl::OnItemNotifyEvent(compositions::GuiItemNotifyEvent& itemEvent, ItemStyle* style, compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (itemArranger && GetVisuallyEnabled())
{
vint itemIndex = itemArranger->GetVisibleIndex(style);
if (itemIndex != -1)
{
GuiItemEventArgs redirectArguments;
(GuiEventArgs&)redirectArguments = arguments;
redirectArguments.compositionSource = boundsComposition;
redirectArguments.eventSource = boundsComposition;
redirectArguments.itemIndex = itemIndex;
itemEvent.Execute(redirectArguments);
arguments = redirectArguments;
}
}
}
#define ATTACH_ITEM_MOUSE_EVENT(EVENTNAME, ITEMEVENTNAME)\
{\
helper->EVENTNAME##Handler = style->GetEventReceiver()->EVENTNAME.AttachFunction(\
[this, style](GuiGraphicsComposition* sender, GuiMouseEventArgs& args){ OnItemMouseEvent(ITEMEVENTNAME, style, sender, args); }\
);\
}\
#define ATTACH_ITEM_NOTIFY_EVENT(EVENTNAME, ITEMEVENTNAME)\
{\
helper->EVENTNAME##Handler = style->GetEventReceiver()->EVENTNAME.AttachFunction(\
[this, style](GuiGraphicsComposition* sender, GuiEventArgs& args){ OnItemNotifyEvent(ITEMEVENTNAME, style, sender, args); }\
);\
}\
void GuiListControl::AttachItemEvents(ItemStyle* style)
{
vint index=visibleStyles.Keys().IndexOf(style);
if(index==-1)
{
auto helper=Ptr(new VisibleStyleHelper);
visibleStyles.Add(style, helper);
ATTACH_ITEM_MOUSE_EVENT(leftButtonDown, ItemLeftButtonDown);
ATTACH_ITEM_MOUSE_EVENT(leftButtonUp, ItemLeftButtonUp);
ATTACH_ITEM_MOUSE_EVENT(leftButtonDoubleClick, ItemLeftButtonDoubleClick);
ATTACH_ITEM_MOUSE_EVENT(middleButtonDown, ItemMiddleButtonDown);
ATTACH_ITEM_MOUSE_EVENT(middleButtonUp, ItemMiddleButtonUp);
ATTACH_ITEM_MOUSE_EVENT(middleButtonDoubleClick, ItemMiddleButtonDoubleClick);
ATTACH_ITEM_MOUSE_EVENT(rightButtonDown, ItemRightButtonDown);
ATTACH_ITEM_MOUSE_EVENT(rightButtonUp, ItemRightButtonUp);
ATTACH_ITEM_MOUSE_EVENT(rightButtonDoubleClick, ItemRightButtonDoubleClick);
ATTACH_ITEM_MOUSE_EVENT(mouseMove, ItemMouseMove);
ATTACH_ITEM_NOTIFY_EVENT(mouseEnter, ItemMouseEnter);
ATTACH_ITEM_NOTIFY_EVENT(mouseLeave, ItemMouseLeave);
}
}
#undef ATTACH_ITEM_MOUSE_EVENT
#undef ATTACH_ITEM_NOTIFY_EVENT
#define DETACH_ITEM_EVENT(EVENTNAME) style->GetEventReceiver()->EVENTNAME.Detach(helper->EVENTNAME##Handler)
void GuiListControl::DetachItemEvents(ItemStyle* style)
{
vint index=visibleStyles.Keys().IndexOf(style);
if(index!=-1)
{
Ptr<VisibleStyleHelper> helper=visibleStyles.Values().Get(index);
visibleStyles.Remove(style);
DETACH_ITEM_EVENT(leftButtonDown);
DETACH_ITEM_EVENT(leftButtonUp);
DETACH_ITEM_EVENT(leftButtonDoubleClick);
DETACH_ITEM_EVENT(middleButtonDown);
DETACH_ITEM_EVENT(middleButtonUp);
DETACH_ITEM_EVENT(middleButtonDoubleClick);
DETACH_ITEM_EVENT(rightButtonDown);
DETACH_ITEM_EVENT(rightButtonUp);
DETACH_ITEM_EVENT(rightButtonDoubleClick);
DETACH_ITEM_EVENT(mouseMove);
DETACH_ITEM_EVENT(mouseEnter);
DETACH_ITEM_EVENT(mouseLeave);
}
}
#undef DETACH_ITEM_EVENT
GuiListControl::GuiListControl(theme::ThemeName themeName, list::IItemProvider* _itemProvider, bool acceptFocus)
:GuiScrollView(themeName)
, itemProvider(_itemProvider)
{
ContextChanged.AttachMethod(this, &GuiListControl::OnContextChanged);
VisuallyEnabledChanged.AttachMethod(this, &GuiListControl::OnVisuallyEnabledChanged);
ItemTemplateChanged.SetAssociatedComposition(boundsComposition);
ArrangerChanged.SetAssociatedComposition(boundsComposition);
AxisChanged.SetAssociatedComposition(boundsComposition);
AdoptedSizeInvalidated.SetAssociatedComposition(boundsComposition);
ItemLeftButtonDown.SetAssociatedComposition(boundsComposition);
ItemLeftButtonUp.SetAssociatedComposition(boundsComposition);
ItemLeftButtonDoubleClick.SetAssociatedComposition(boundsComposition);
ItemMiddleButtonDown.SetAssociatedComposition(boundsComposition);
ItemMiddleButtonUp.SetAssociatedComposition(boundsComposition);
ItemMiddleButtonDoubleClick.SetAssociatedComposition(boundsComposition);
ItemRightButtonDown.SetAssociatedComposition(boundsComposition);
ItemRightButtonUp.SetAssociatedComposition(boundsComposition);
ItemRightButtonDoubleClick.SetAssociatedComposition(boundsComposition);
ItemMouseMove.SetAssociatedComposition(boundsComposition);
ItemMouseEnter.SetAssociatedComposition(boundsComposition);
ItemMouseLeave.SetAssociatedComposition(boundsComposition);
callback = Ptr(new ItemCallback(this));
itemProvider->AttachCallback(callback.Obj());
axis = Ptr(new GuiDefaultAxis);
if (acceptFocus)
{
boundsComposition->GetEventReceiver()->leftButtonDown.AttachMethod(this, &GuiListControl::OnBoundsMouseButtonDown);
boundsComposition->GetEventReceiver()->middleButtonDown.AttachMethod(this, &GuiListControl::OnBoundsMouseButtonDown);
boundsComposition->GetEventReceiver()->rightButtonDown.AttachMethod(this, &GuiListControl::OnBoundsMouseButtonDown);
SetFocusableComposition(boundsComposition);
}
}
GuiListControl::~GuiListControl()
{
if(itemArranger)
{
itemProvider->DetachCallback(itemArranger.Obj());
}
callback->ClearCache();
itemStyleProperty = {};
itemArranger = nullptr;
}
list::IItemProvider* GuiListControl::GetItemProvider()
{
return itemProvider.Obj();
}
GuiListControl::ItemStyleProperty GuiListControl::GetItemTemplate()
{
return itemStyleProperty;
}
void GuiListControl::SetItemTemplate(ItemStyleProperty value)
{
SetStyleAndArranger(value, itemArranger);
ItemTemplateChanged.Execute(GetNotifyEventArguments());
}
GuiListControl::IItemArranger* GuiListControl::GetArranger()
{
return itemArranger.Obj();
}
void GuiListControl::SetArranger(Ptr<IItemArranger> value)
{
SetStyleAndArranger(itemStyleProperty, value);
ArrangerChanged.Execute(GetNotifyEventArguments());
}
compositions::IGuiAxis* GuiListControl::GetAxis()
{
return axis.Obj();
}
void GuiListControl::SetAxis(Ptr<compositions::IGuiAxis> value)
{
Ptr<IGuiAxis> old = axis;
axis = value;
SetStyleAndArranger(itemStyleProperty, itemArranger);
AxisChanged.Execute(GetNotifyEventArguments());
}
bool GuiListControl::EnsureItemVisible(vint itemIndex)
{
if (itemIndex < 0 || itemIndex >= itemProvider->Count())
{
return false;
}
if (!itemArranger) return false;
auto result = itemArranger->EnsureItemVisible(itemIndex);
if (result == EnsureItemVisibleResult::Moved)
{
if (auto host = GetBoundsComposition()->GetRelatedGraphicsHost())
{
auto flag = GetDisposedFlag();
host->InvokeAfterRendering([=]()
{
if (!flag->IsDisposed())
{
EnsureItemVisible(itemIndex);
}
}, { this,0 });
}
}
return result != EnsureItemVisibleResult::ItemNotExists;
}
Size GuiListControl::GetAdoptedSize(Size expectedSize)
{
if (itemArranger)
{
Size controlSize = boundsComposition->GetCachedBounds().GetSize();
Size viewSize = containerComposition->GetCachedBounds().GetSize();
vint dx = controlSize.x - viewSize.x;
vint dy = controlSize.y - viewSize.y;
if (dx < 0) dx = 0;
if (dy < 0) dy = 0;
auto hscroll = GetHorizontalScroll();
auto vscroll = GetVerticalScroll();
if (!vscroll || vscroll->GetBoundsComposition()->GetEventuallyVisible())
{
if (adoptedSizeDiffWithScroll.x < dx) adoptedSizeDiffWithScroll.x = dx;
}
if (!vscroll || !vscroll->GetBoundsComposition()->GetEventuallyVisible())
{
if (adoptedSizeDiffWithoutScroll.x < dx) adoptedSizeDiffWithoutScroll.x = dx;
}
if (!hscroll || hscroll->GetBoundsComposition()->GetEventuallyVisible())
{
if (adoptedSizeDiffWithScroll.y < dy) adoptedSizeDiffWithScroll.y = dy;
}
if (!hscroll || !hscroll->GetBoundsComposition()->GetEventuallyVisible())
{
if (adoptedSizeDiffWithoutScroll.y < dy) adoptedSizeDiffWithoutScroll.y = dy;
}
vint x = adoptedSizeDiffWithoutScroll.x != -1 ? adoptedSizeDiffWithoutScroll.x : adoptedSizeDiffWithScroll.x;
vint y = adoptedSizeDiffWithoutScroll.y != -1 ? adoptedSizeDiffWithoutScroll.y : adoptedSizeDiffWithScroll.y;
Size expectedViewSize(expectedSize.x - x, expectedSize.y - y);
Size adoptedViewSize = itemArranger->GetAdoptedSize(expectedViewSize);
Size adoptedSize = Size(adoptedViewSize.x + x, adoptedViewSize.y + y);
return adoptedSize;
}
return expectedSize;
}
bool GuiListControl::GetDisplayItemBackground()
{
return displayItemBackground;
}
void GuiListControl::SetDisplayItemBackground(bool value)
{
if (displayItemBackground != value)
{
displayItemBackground = value;
SetStyleAndArranger(itemStyleProperty, itemArranger);
}
}
/***********************************************************************
GuiSelectableListControl
***********************************************************************/
void GuiSelectableListControl::NotifySelectionChanged(bool triggeredByItemContentModified)
{
SelectionChanged.Execute(GetNotifyEventArguments());
}
void GuiSelectableListControl::OnItemModified(vint start, vint count, vint newCount, bool itemReferenceUpdated)
{
GuiListControl::OnItemModified(start, count, newCount, itemReferenceUpdated);
if (count != newCount)
{
ClearSelection();
}
else if (itemReferenceUpdated)
{
if (selectedItems.Count() > 0)
{
vint cmin = start;
vint cmax = start + count - 1;
vint smin = selectedItems[0];
vint smax = selectedItems[selectedItems.Count() - 1];
if (cmin <= smax && smin <= cmax)
{
ClearSelection();
}
}
}
else
{
if (GetSelectedItemIndex() == start)
{
NotifySelectionChanged(true);
}
}
}
void GuiSelectableListControl::OnStyleInstalled(vint itemIndex, ItemStyle* style, bool refreshPropertiesOnly)
{
GuiListControl::OnStyleInstalled(itemIndex, style, refreshPropertiesOnly);
style->SetSelected(selectedItems.Contains(itemIndex));
}
void GuiSelectableListControl::OnItemSelectionChanged(vint itemIndex, bool value)
{
if(auto style = itemArranger->GetVisibleStyle(itemIndex))
{
style->SetSelected(value);
}
}
void GuiSelectableListControl::OnItemSelectionCleared()
{
for (auto style : visibleStyles.Keys())
{
style->SetSelected(false);
}
}
void GuiSelectableListControl::OnItemLeftButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiItemMouseEventArgs& arguments)
{
if(GetVisuallyEnabled())
{
SelectItemsByClick(arguments.itemIndex, arguments.ctrl, arguments.shift, true);
}
}
void GuiSelectableListControl::OnItemRightButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiItemMouseEventArgs& arguments)
{
if(GetVisuallyEnabled())
{
SelectItemsByClick(arguments.itemIndex, arguments.ctrl, arguments.shift, false);
}
}
void GuiSelectableListControl::NormalizeSelectedItemIndexStartEnd()
{
if (selectedItemIndexStart < 0 || selectedItemIndexStart >= itemProvider->Count())
{
selectedItemIndexStart = 0;
}
if (selectedItemIndexEnd < 0 || selectedItemIndexEnd >= itemProvider->Count())
{
selectedItemIndexEnd = 0;
}
}
void GuiSelectableListControl::SetMultipleItemsSelectedSilently(vint start, vint end, bool selected)
{
if(start>end)
{
vint temp=start;
start=end;
end=temp;
}
vint count=itemProvider->Count();
if(start<0) start=0;
if(end>=count) end=count-1;
for(vint i=start;i<=end;i++)
{
if(selected)
{
if(!selectedItems.Contains(i))
{
selectedItems.Add(i);
}
}
else
{
selectedItems.Remove(i);
}
OnItemSelectionChanged(i, selected);
}
}
void GuiSelectableListControl::OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments)
{
if(GetVisuallyEnabled())
{
if(SelectItemsByKey(arguments.code, arguments.ctrl, arguments.shift))
{
arguments.handled=true;
}
}
}
vint GuiSelectableListControl::FindItemByVirtualKeyDirection(vint index, compositions::KeyDirection keyDirection)
{
return GetArranger()->FindItemByVirtualKeyDirection(selectedItemIndexEnd, keyDirection);
}
GuiSelectableListControl::GuiSelectableListControl(theme::ThemeName themeName, list::IItemProvider* _itemProvider)
:GuiListControl(themeName, _itemProvider, true)
, multiSelect(false)
, selectedItemIndexStart(-1)
, selectedItemIndexEnd(-1)
{
SelectionChanged.SetAssociatedComposition(boundsComposition);
ItemLeftButtonDown.AttachMethod(this, &GuiSelectableListControl::OnItemLeftButtonDown);
ItemRightButtonDown.AttachMethod(this, &GuiSelectableListControl::OnItemRightButtonDown);
if (focusableComposition)
{
focusableComposition->GetEventReceiver()->keyDown.AttachMethod(this, &GuiSelectableListControl::OnKeyDown);
}
}
GuiSelectableListControl::~GuiSelectableListControl()
{
}
bool GuiSelectableListControl::GetMultiSelect()
{
return multiSelect;
}
void GuiSelectableListControl::SetMultiSelect(bool value)
{
if (multiSelect != value)
{
multiSelect = value;
ClearSelection();
}
}
const collections::SortedList<vint>& GuiSelectableListControl::GetSelectedItems()
{
return selectedItems;
}
vint GuiSelectableListControl::GetSelectedItemIndex()
{
return selectedItems.Count() == 1 ? selectedItems[0] : -1;
}
WString GuiSelectableListControl::GetSelectedItemText()
{
vint index = GetSelectedItemIndex();
if (index != -1)
{
return itemProvider->GetTextValue(index);
}
return L"";
}
bool GuiSelectableListControl::GetSelected(vint itemIndex)
{
return selectedItems.Contains(itemIndex);
}
void GuiSelectableListControl::SetSelected(vint itemIndex, bool value)
{
if (0 <= itemIndex && itemIndex < itemProvider->Count())
{
if (value)
{
if (!selectedItems.Contains(itemIndex))
{
if (!multiSelect)
{
selectedItems.Clear();
OnItemSelectionCleared();
}
selectedItems.Add(itemIndex);
OnItemSelectionChanged(itemIndex, value);
NotifySelectionChanged(false);
}
}
else
{
if (selectedItems.Remove(itemIndex))
{
OnItemSelectionChanged(itemIndex, value);
NotifySelectionChanged(false);
}
}
selectedItemIndexStart = itemIndex;
selectedItemIndexEnd = itemIndex;
}
}
bool GuiSelectableListControl::SelectItemsByClick(vint itemIndex, bool ctrl, bool shift, bool leftButton)
{
NormalizeSelectedItemIndexStartEnd();
if (0 <= itemIndex && itemIndex < itemProvider->Count())
{
if (!leftButton)
{
if (selectedItems.Contains(itemIndex))
{
return true;
}
}
if (!multiSelect)
{
shift = false;
ctrl = false;
}
if (shift)
{
if (!ctrl)
{
selectedItems.Clear();
OnItemSelectionCleared();
}
selectedItemIndexEnd = itemIndex;
SetMultipleItemsSelectedSilently(selectedItemIndexStart, selectedItemIndexEnd, true);
NotifySelectionChanged(false);
}
else
{
if (ctrl)
{
vint index = selectedItems.IndexOf(itemIndex);
if (index == -1)
{
selectedItems.Add(itemIndex);
}
else
{
selectedItems.RemoveAt(index);
}
OnItemSelectionChanged(itemIndex, index == -1);
NotifySelectionChanged(false);
}
else
{
selectedItems.Clear();
OnItemSelectionCleared();
selectedItems.Add(itemIndex);
OnItemSelectionChanged(itemIndex, true);
NotifySelectionChanged(false);
}
selectedItemIndexStart = itemIndex;
selectedItemIndexEnd = itemIndex;
}
return true;
}
return false;
}
bool GuiSelectableListControl::SelectItemsByKey(VKEY code, bool ctrl, bool shift)
{
if (!GetArranger()) return false;
NormalizeSelectedItemIndexStartEnd();
KeyDirection keyDirection = KeyDirection::Up;
switch (code)
{
case VKEY::KEY_UP:
keyDirection = KeyDirection::Up;
break;
case VKEY::KEY_DOWN:
keyDirection = KeyDirection::Down;
break;
case VKEY::KEY_LEFT:
keyDirection = KeyDirection::Left;
break;
case VKEY::KEY_RIGHT:
keyDirection = KeyDirection::Right;
break;
case VKEY::KEY_HOME:
keyDirection = KeyDirection::Home;
break;
case VKEY::KEY_END:
keyDirection = KeyDirection::End;
break;
case VKEY::KEY_PRIOR:
keyDirection = KeyDirection::PageUp;
break;
case VKEY::KEY_NEXT:
keyDirection = KeyDirection::PageDown;
break;
default:
return false;
}
if (GetAxis())
{
keyDirection = GetAxis()->RealKeyDirectionToVirtualKeyDirection(keyDirection);
}
vint itemIndex = FindItemByVirtualKeyDirection(selectedItemIndexEnd, keyDirection);
if (SelectItemsByClick(itemIndex, ctrl, shift, true))
{
return EnsureItemVisible(itemIndex);
}
else
{
return false;
}
}
void GuiSelectableListControl::ClearSelection()
{
if(selectedItems.Count()>0)
{
selectedItems.Clear();
selectedItemIndexStart = -1;
selectedItemIndexEnd = -1;
OnItemSelectionCleared();
NotifySelectionChanged(false);
}
}
}
}
}
/***********************************************************************
.\CONTROLS\LISTCONTROLPACKAGE\GUILISTVIEWCONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace elements;
using namespace compositions;
using namespace collections;
using namespace reflection::description;
/***********************************************************************
GuiListViewColumnHeader
***********************************************************************/
void GuiListViewColumnHeader::BeforeControlTemplateUninstalled_()
{
}
void GuiListViewColumnHeader::AfterControlTemplateInstalled_(bool initialize)
{
TypedControlTemplateObject(true)->SetSortingState(columnSortingState);
}
GuiListViewColumnHeader::GuiListViewColumnHeader(theme::ThemeName themeName)
:GuiMenuButton(themeName)
{
}
GuiListViewColumnHeader::~GuiListViewColumnHeader()
{
}
bool GuiListViewColumnHeader::IsAltAvailable()
{
return false;
}
ColumnSortingState GuiListViewColumnHeader::GetColumnSortingState()
{
return columnSortingState;
}
void GuiListViewColumnHeader::SetColumnSortingState(ColumnSortingState value)
{
if (columnSortingState != value)
{
columnSortingState = value;
TypedControlTemplateObject(true)->SetSortingState(columnSortingState);
}
}
/***********************************************************************
GuiListViewBase
***********************************************************************/
void GuiListViewBase::BeforeControlTemplateUninstalled_()
{
}
void GuiListViewBase::AfterControlTemplateInstalled_(bool initialize)
{
}
GuiListViewBase::GuiListViewBase(theme::ThemeName themeName, list::IItemProvider* _itemProvider)
:GuiSelectableListControl(themeName, _itemProvider)
{
ColumnClicked.SetAssociatedComposition(boundsComposition);
}
GuiListViewBase::~GuiListViewBase()
{
}
namespace list
{
const wchar_t* const IListViewItemView::Identifier = L"vl::presentation::controls::list::IListViewItemView";
/***********************************************************************
ListViewColumnItemArranger::ColumnItemViewCallback
***********************************************************************/
ListViewColumnItemArranger::ColumnItemViewCallback::ColumnItemViewCallback(ListViewColumnItemArranger* _arranger)
:arranger(_arranger)
{
}
ListViewColumnItemArranger::ColumnItemViewCallback::~ColumnItemViewCallback()
{
}
void ListViewColumnItemArranger::ColumnItemViewCallback::OnColumnRebuilt()
{
arranger->RebuildColumns();
}
void ListViewColumnItemArranger::ColumnItemViewCallback::OnColumnChanged(bool needToRefreshItems)
{
arranger->RefreshColumns();
}
/***********************************************************************
ListViewColumnItemArranger::ColumnItemArrangerRepeatComposition
***********************************************************************/
void ListViewColumnItemArranger::ColumnItemArrangerRepeatComposition::Layout_EndLayout(bool totalSizeUpdated)
{
TBase::ArrangerRepeatComposition::Layout_EndLayout(totalSizeUpdated);
arranger->FixColumnsAfterLayout();
}
void ListViewColumnItemArranger::ColumnItemArrangerRepeatComposition::Layout_CalculateTotalSize(Size& full, Size& minimum)
{
TBase::ArrangerRepeatComposition::Layout_CalculateTotalSize(full, minimum);
full.x += arranger->SplitterWidth;
minimum.x += arranger->SplitterWidth;
}
ListViewColumnItemArranger::ColumnItemArrangerRepeatComposition::ColumnItemArrangerRepeatComposition(ListViewColumnItemArranger* _arranger)
: TBase::ArrangerRepeatComposition(_arranger)
, arranger(_arranger)
{
}
/***********************************************************************
ListViewColumnItemArranger
***********************************************************************/
const wchar_t* const ListViewColumnItemArranger::IColumnItemView::Identifier = L"vl::presentation::controls::list::ListViewColumnItemArranger::IColumnItemView";
void ListViewColumnItemArranger::OnViewLocationChanged(compositions::GuiGraphicsComposition* composition, compositions::GuiEventArgs& arguments)
{
FixColumnsAfterViewLocationChanged();
}
void ListViewColumnItemArranger::ColumnClicked(vint index, compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
GuiItemEventArgs args(listView->ColumnClicked.GetAssociatedComposition());
args.itemIndex=index;
listView->ColumnClicked.Execute(args);
}
void ListViewColumnItemArranger::ColumnCachedBoundsChanged(vint index, compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
GuiBoundsComposition* buttonBounds=columnHeaderButtons[index]->GetBoundsComposition();
vint size=buttonBounds->GetCachedBounds().Width();
if(size>columnItemView->GetColumnSize(index))
{
columnItemView->SetColumnSize(index, size);
}
}
void ListViewColumnItemArranger::ColumnHeaderSplitterLeftButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if(listView->GetVisuallyEnabled())
{
arguments.handled=true;
splitterDragging=true;
splitterLatestX=arguments.x;
}
}
void ListViewColumnItemArranger::ColumnHeaderSplitterLeftButtonUp(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if(listView->GetVisuallyEnabled())
{
arguments.handled=true;
splitterDragging=false;
splitterLatestX=0;
}
}
void ListViewColumnItemArranger::ColumnHeaderSplitterMouseMove(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if(splitterDragging)
{
vint offset=arguments.x-splitterLatestX;
vint index=columnHeaderSplitters.IndexOf(dynamic_cast<GuiBoundsComposition*>(sender));
if(index!=-1)
{
GuiBoundsComposition* buttonBounds=columnHeaderButtons[index]->GetBoundsComposition();
Rect bounds=buttonBounds->GetCachedBounds();
Rect newBounds(bounds.LeftTop(), Size(bounds.Width()+offset, bounds.Height()));
buttonBounds->SetExpectedBounds(newBounds);
vint finalSize=buttonBounds->GetCachedBounds().Width();
columnItemView->SetColumnSize(index, finalSize);
}
}
}
void ListViewColumnItemArranger::ColumnHeadersCachedBoundsChanged(compositions::GuiGraphicsComposition* composition, compositions::GuiEventArgs& arguments)
{
UpdateRepeatConfig();
}
void ListViewColumnItemArranger::FixColumnsAfterViewLocationChanged()
{
vint x = GetRepeatComposition()->GetViewLocation().x;
columnHeaders->SetExpectedBounds(Rect(Point(-x, 0), Size(0, 0)));
}
void ListViewColumnItemArranger::FixColumnsAfterLayout()
{
vint count = columnHeaders->GetParent()->Children().Count();
columnHeaders->GetParent()->MoveChild(columnHeaders, count - 1);
FixColumnsAfterViewLocationChanged();
}
vint ListViewColumnItemArranger::GetColumnsWidth()
{
vint width=columnHeaders->GetCachedBounds().Width()-SplitterWidth;
if(width<SplitterWidth)
{
width=SplitterWidth;
}
return width;
}
vint ListViewColumnItemArranger::GetColumnsYOffset()
{
return columnHeaders->GetCachedBounds().Height();
}
void ListViewColumnItemArranger::DeleteColumnButtons()
{
// TODO: (enumerable) foreach:reversed
for(vint i=columnHeaders->GetStackItems().Count()-1;i>=0;i--)
{
GuiStackItemComposition* item=columnHeaders->GetStackItems().Get(i);
columnHeaders->RemoveChild(item);
GuiControl* button=item->Children().Get(0)->GetAssociatedControl();
if(button)
{
item->RemoveChild(button->GetBoundsComposition());
delete button;
}
delete item;
}
columnHeaderButtons.Clear();
columnHeaderSplitters.Clear();
}
void ListViewColumnItemArranger::RebuildColumns()
{
if (columnItemView && columnHeaderButtons.Count() == listViewItemView->GetColumnCount())
{
for (vint i = 0; i < listViewItemView->GetColumnCount(); i++)
{
GuiListViewColumnHeader* button = columnHeaderButtons[i];
button->SetText(listViewItemView->GetColumnText(i));
button->SetSubMenu(columnItemView->GetDropdownPopup(i), false);
button->SetColumnSortingState(columnItemView->GetSortingState(i));
button->GetBoundsComposition()->SetExpectedBounds(Rect(Point(0, 0), Size(columnItemView->GetColumnSize(i), 0)));
}
}
else
{
DeleteColumnButtons();
if (columnItemView && listViewItemView)
{
for (vint i = 0; i < listViewItemView->GetColumnCount(); i++)
{
GuiBoundsComposition* splitterComposition = new GuiBoundsComposition;
splitterComposition->SetAlignmentToParent(Margin(0, 0, 0, 0));
splitterComposition->SetAssociatedCursor(GetCurrentController()->ResourceService()->GetSystemCursor(INativeCursor::SizeWE));
splitterComposition->SetAlignmentToParent(Margin(0, 0, -1, 0));
splitterComposition->SetPreferredMinSize(Size(SplitterWidth, 0));
columnHeaderSplitters.Add(splitterComposition);
splitterComposition->GetEventReceiver()->leftButtonDown.AttachMethod(this, &ListViewColumnItemArranger::ColumnHeaderSplitterLeftButtonDown);
splitterComposition->GetEventReceiver()->leftButtonUp.AttachMethod(this, &ListViewColumnItemArranger::ColumnHeaderSplitterLeftButtonUp);
splitterComposition->GetEventReceiver()->mouseMove.AttachMethod(this, &ListViewColumnItemArranger::ColumnHeaderSplitterMouseMove);
}
for (vint i = 0; i < listViewItemView->GetColumnCount(); i++)
{
GuiListViewColumnHeader* button = new GuiListViewColumnHeader(theme::ThemeName::Unknown);
button->SetAutoFocus(false);
button->SetControlTemplate(listView->TypedControlTemplateObject(true)->GetColumnHeaderTemplate());
button->Clicked.AttachLambda([this, i](GuiGraphicsComposition* sender, GuiEventArgs& args) { ColumnClicked(i, sender, args); });
button->GetBoundsComposition()->CachedBoundsChanged.AttachLambda([this, i](GuiGraphicsComposition* sender, GuiEventArgs& args) { ColumnCachedBoundsChanged(i, sender, args); });
columnHeaderButtons.Add(button);
if (i > 0)
{
button->GetContainerComposition()->AddChild(columnHeaderSplitters[i - 1]);
}
GuiStackItemComposition* item = new GuiStackItemComposition;
item->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
item->AddChild(button->GetBoundsComposition());
columnHeaders->AddChild(item);
}
if (listViewItemView->GetColumnCount() > 0)
{
GuiBoundsComposition* splitterComposition = columnHeaderSplitters[listViewItemView->GetColumnCount() - 1];
GuiStackItemComposition* item = new GuiStackItemComposition;
item->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
item->AddChild(splitterComposition);
columnHeaders->AddChild(item);
}
}
}
RefreshColumns();
callback->OnTotalSizeChanged();
}
void ListViewColumnItemArranger::UpdateRepeatConfig()
{
GetRepeatComposition()->SetItemWidth(GetColumnsWidth());
GetRepeatComposition()->SetItemYOffset(GetColumnsYOffset());
}
void ListViewColumnItemArranger::RefreshColumns()
{
if (columnItemView && listViewItemView)
{
for (vint i = 0; i < listViewItemView->GetColumnCount(); i++)
{
auto button = columnHeaderButtons[i];
button->SetText(listViewItemView->GetColumnText(i));
button->SetSubMenu(columnItemView->GetDropdownPopup(i), false);
button->SetColumnSortingState(columnItemView->GetSortingState(i));
button->GetBoundsComposition()->SetExpectedBounds(Rect(Point(0, 0), Size(columnItemView->GetColumnSize(i), 0)));
}
columnHeaders->ForceCalculateSizeImmediately();
UpdateRepeatConfig();
}
}
ListViewColumnItemArranger::ListViewColumnItemArranger()
: TBase(new TBase::ArrangerRepeatComposition(this))
{
columnHeaders = new GuiStackComposition;
columnHeaders->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
columnHeaders->CachedBoundsChanged.AttachMethod(this, &ListViewColumnItemArranger::ColumnHeadersCachedBoundsChanged);
columnItemViewCallback = Ptr(new ColumnItemViewCallback(this));
GetRepeatComposition()->ViewLocationChanged.AttachMethod(this, &ListViewColumnItemArranger::OnViewLocationChanged);
}
ListViewColumnItemArranger::~ListViewColumnItemArranger()
{
if(!columnHeaders->GetParent())
{
DeleteColumnButtons();
delete columnHeaders;
}
}
Size ListViewColumnItemArranger::GetTotalSize()
{
Size size = TBase::GetTotalSize();
size.x += SplitterWidth;
return size;
}
void ListViewColumnItemArranger::AttachListControl(GuiListControl* value)
{
TBase::AttachListControl(value);
listView = dynamic_cast<GuiListViewBase*>(value);
if (listView)
{
listViewItemView = dynamic_cast<IListViewItemView*>(listView->GetItemProvider()->RequestView(WString::Unmanaged(IListViewItemView::Identifier)));
columnItemView = dynamic_cast<IColumnItemView*>(listView->GetItemProvider()->RequestView(WString::Unmanaged(IColumnItemView::Identifier)));
listView->GetContainerComposition()->AddChild(columnHeaders);
if (columnItemView)
{
columnItemView->AttachCallback(columnItemViewCallback.Obj());
RebuildColumns();
}
}
}
void ListViewColumnItemArranger::DetachListControl()
{
if (listView)
{
if (columnItemView)
{
columnItemView->DetachCallback(columnItemViewCallback.Obj());
columnItemView = nullptr;
}
listViewItemView = nullptr;
listView->GetContainerComposition()->RemoveChild(columnHeaders);
listView = nullptr;
}
TBase::DetachListControl();
}
const ListViewColumnItemArranger::ColumnHeaderButtonList& ListViewColumnItemArranger::GetColumnButtons()
{
return columnHeaderButtons;
}
const ListViewColumnItemArranger::ColumnHeaderSplitterList& ListViewColumnItemArranger::GetColumnSplitters()
{
return columnHeaderSplitters;
}
/***********************************************************************
ListViewSubItems
***********************************************************************/
void ListViewSubItems::NotifyUpdateInternal(vint start, vint count, vint newCount)
{
owner->NotifyUpdate();
}
/***********************************************************************
ListViewItem
***********************************************************************/
void ListViewItem::NotifyUpdate()
{
if (owner)
{
vint index = owner->IndexOf(this);
owner->InvokeOnItemModified(index, 1, 1, false);
}
}
ListViewItem::ListViewItem()
:owner(0)
{
subItems.owner = this;
}
ListViewSubItems& ListViewItem::GetSubItems()
{
return subItems;
}
Ptr<GuiImageData> ListViewItem::GetSmallImage()
{
return smallImage;
}
void ListViewItem::SetSmallImage(Ptr<GuiImageData> value)
{
smallImage = value;
NotifyUpdate();
}
Ptr<GuiImageData> ListViewItem::GetLargeImage()
{
return largeImage;
}
void ListViewItem::SetLargeImage(Ptr<GuiImageData> value)
{
largeImage = value;
NotifyUpdate();
}
const WString& ListViewItem::GetText()
{
return text;
}
void ListViewItem::SetText(const WString& value)
{
text = value;
NotifyUpdate();
}
description::Value ListViewItem::GetTag()
{
return tag;
}
void ListViewItem::SetTag(const description::Value& value)
{
tag = value;
NotifyUpdate();
}
/***********************************************************************
ListViewColumn
***********************************************************************/
void ListViewColumn::NotifyRebuilt()
{
if (owner)
{
vint index = owner->IndexOf(this);
if (index != -1)
{
owner->NotifyColumnRebuilt(index);
}
}
}
void ListViewColumn::NotifyChanged(bool needToRefreshItems)
{
if (owner)
{
vint index = owner->IndexOf(this);
if (index != -1)
{
owner->NotifyColumnChanged(index, needToRefreshItems);
}
}
}
ListViewColumn::ListViewColumn(const WString& _text, vint _size)
:text(_text)
,size(_size)
{
}
ListViewColumn::~ListViewColumn()
{
if (dropdownPopup && ownPopup)
{
SafeDeleteControl(dropdownPopup);
}
}
const WString& ListViewColumn::GetText()
{
return text;
}
void ListViewColumn::SetText(const WString& value)
{
if (text != value)
{
text = value;
NotifyChanged(false);
}
}
ItemProperty<WString> ListViewColumn::GetTextProperty()
{
return textProperty;
}
void ListViewColumn::SetTextProperty(const ItemProperty<WString>& value)
{
textProperty = value;
NotifyChanged(true);
}
vint ListViewColumn::GetSize()
{
return size;
}
void ListViewColumn::SetSize(vint value)
{
if (size != value)
{
size = value;
NotifyChanged(true);
}
}
bool ListViewColumn::GetOwnPopup()
{
return ownPopup;
}
void ListViewColumn::SetOwnPopup(bool value)
{
ownPopup = value;
}
GuiMenu* ListViewColumn::GetDropdownPopup()
{
return dropdownPopup;
}
void ListViewColumn::SetDropdownPopup(GuiMenu* value)
{
if (dropdownPopup != value)
{
dropdownPopup = value;
NotifyChanged(false);
}
}
ColumnSortingState ListViewColumn::GetSortingState()
{
return sortingState;
}
void ListViewColumn::SetSortingState(ColumnSortingState value)
{
if (sortingState != value)
{
sortingState = value;
NotifyChanged(false);
}
}
/***********************************************************************
ListViewDataColumns
***********************************************************************/
void ListViewDataColumns::NotifyUpdateInternal(vint start, vint count, vint newCount)
{
itemProvider->RefreshAllItems();
}
ListViewDataColumns::ListViewDataColumns(IListViewItemProvider* _itemProvider)
:itemProvider(_itemProvider)
{
}
ListViewDataColumns::~ListViewDataColumns()
{
}
/***********************************************************************
ListViewColumns
***********************************************************************/
void ListViewColumns::NotifyColumnRebuilt(vint column)
{
NotifyUpdate(column, 1);
}
void ListViewColumns::NotifyColumnChanged(vint column, bool needToRefreshItems)
{
itemProvider->NotifyColumnChanged();
}
void ListViewColumns::AfterInsert(vint index, const Ptr<ListViewColumn>& value)
{
collections::ObservableListBase<Ptr<ListViewColumn>>::AfterInsert(index, value);
value->owner = this;
}
void ListViewColumns::BeforeRemove(vint index, const Ptr<ListViewColumn>& value)
{
value->owner = 0;
collections::ObservableListBase<Ptr<ListViewColumn>>::BeforeRemove(index, value);
}
void ListViewColumns::NotifyUpdateInternal(vint start, vint count, vint newCount)
{
itemProvider->NotifyColumnRebuilt();
}
ListViewColumns::ListViewColumns(IListViewItemProvider* _itemProvider)
:itemProvider(_itemProvider)
{
}
ListViewColumns::~ListViewColumns()
{
}
/***********************************************************************
ListViewItemProvider
***********************************************************************/
void ListViewItemProvider::AfterInsert(vint index, const Ptr<ListViewItem>& value)
{
ListProvider<Ptr<ListViewItem>>::AfterInsert(index, value);
value->owner = this;
}
void ListViewItemProvider::BeforeRemove(vint index, const Ptr<ListViewItem>& value)
{
value->owner = 0;
ListProvider<Ptr<ListViewItem>>::AfterInsert(index, value);
}
void ListViewItemProvider::RebuildAllItems()
{
InvokeOnItemModified(0, Count(), Count(), true);
}
void ListViewItemProvider::RefreshAllItems()
{
InvokeOnItemModified(0, Count(), Count(), false);
}
void ListViewItemProvider::NotifyColumnRebuilt()
{
for (auto callback : columnItemViewCallbacks)
{
callback->OnColumnRebuilt();
}
RefreshAllItems();
}
void ListViewItemProvider::NotifyColumnChanged()
{
for (auto callback : columnItemViewCallbacks)
{
callback->OnColumnChanged(true);
}
RefreshAllItems();
}
ListViewItemProvider::ListViewItemProvider()
:columns(this)
, dataColumns(this)
{
}
ListViewItemProvider::~ListViewItemProvider()
{
}
WString ListViewItemProvider::GetTextValue(vint itemIndex)
{
return GetText(itemIndex);
}
description::Value ListViewItemProvider::GetBindingValue(vint itemIndex)
{
return Value::From(Get(itemIndex));
}
IDescriptable* ListViewItemProvider::RequestView(const WString& identifier)
{
if (identifier == IListViewItemView::Identifier)
{
return (IListViewItemView*)this;
}
else if (identifier == ListViewColumnItemArranger::IColumnItemView::Identifier)
{
return (ListViewColumnItemArranger::IColumnItemView*)this;
}
else
{
return 0;
}
}
Ptr<GuiImageData> ListViewItemProvider::GetSmallImage(vint itemIndex)
{
return Get(itemIndex)->smallImage;
}
Ptr<GuiImageData> ListViewItemProvider::GetLargeImage(vint itemIndex)
{
return Get(itemIndex)->largeImage;
}
WString ListViewItemProvider::GetText(vint itemIndex)
{
return Get(itemIndex)->text;
}
WString ListViewItemProvider::GetSubItem(vint itemIndex, vint index)
{
Ptr<ListViewItem> item=Get(itemIndex);
if(index<0 || index>=item->GetSubItems().Count())
{
return L"";
}
else
{
return item->GetSubItems()[index];
}
}
vint ListViewItemProvider::GetDataColumnCount()
{
return dataColumns.Count();
}
vint ListViewItemProvider::GetDataColumn(vint index)
{
return dataColumns[index];
}
vint ListViewItemProvider::GetColumnCount()
{
return columns.Count();
}
WString ListViewItemProvider::GetColumnText(vint index)
{
if (index<0 || index >= columns.Count())
{
return L"";
}
else
{
return columns[index]->GetText();
}
}
bool ListViewItemProvider::AttachCallback(ListViewColumnItemArranger::IColumnItemViewCallback* value)
{
if(columnItemViewCallbacks.Contains(value))
{
return false;
}
else
{
columnItemViewCallbacks.Add(value);
return true;
}
}
bool ListViewItemProvider::DetachCallback(ListViewColumnItemArranger::IColumnItemViewCallback* value)
{
vint index=columnItemViewCallbacks.IndexOf(value);
if(index==-1)
{
return false;
}
else
{
columnItemViewCallbacks.Remove(value);
return true;
}
}
vint ListViewItemProvider::GetColumnSize(vint index)
{
if(index<0 || index>=columns.Count())
{
return 0;
}
else
{
return columns[index]->GetSize();
}
}
void ListViewItemProvider::SetColumnSize(vint index, vint value)
{
if(index>=0 && index<columns.Count())
{
columns[index]->SetSize(value);
}
}
GuiMenu* ListViewItemProvider::GetDropdownPopup(vint index)
{
if(index<0 || index>=columns.Count())
{
return 0;
}
else
{
return columns[index]->GetDropdownPopup();
}
}
ColumnSortingState ListViewItemProvider::GetSortingState(vint index)
{
if (index < 0 || index >= columns.Count())
{
return ColumnSortingState::NotSorted;
}
else
{
return columns[index]->GetSortingState();
}
}
ListViewDataColumns& ListViewItemProvider::GetDataColumns()
{
return dataColumns;
}
ListViewColumns& ListViewItemProvider::GetColumns()
{
return columns;
}
}
/***********************************************************************
GuiListView
***********************************************************************/
void GuiVirtualListView::OnStyleInstalled(vint itemIndex, ItemStyle* style, bool refreshPropertiesOnly)
{
GuiListViewBase::OnStyleInstalled(itemIndex, style, refreshPropertiesOnly);
if (auto textItemStyle = dynamic_cast<templates::GuiTextListItemTemplate*>(style))
{
textItemStyle->SetTextColor(TypedControlTemplateObject(true)->GetPrimaryTextColor());
}
if (refreshPropertiesOnly)
{
if (auto predefinedItemStyle = dynamic_cast<list::DefaultListViewItemTemplate*>(style))
{
predefinedItemStyle->RefreshItem();
}
}
}
void GuiVirtualListView::OnItemTemplateChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
view = ListViewView::Unknown;
}
GuiVirtualListView::GuiVirtualListView(theme::ThemeName themeName, list::IItemProvider* _itemProvider)
:GuiListViewBase(themeName, _itemProvider)
{
SetView(ListViewView::Detail);
}
GuiVirtualListView::~GuiVirtualListView()
{
}
ListViewView GuiVirtualListView::GetView()
{
return view;
}
void GuiVirtualListView::SetView(ListViewView _view)
{
switch (_view)
{
case ListViewView::BigIcon:
SetStyleAndArranger(
[](const Value&) { return new list::BigIconListViewItemTemplate; },
Ptr(new list::FixedSizeMultiColumnItemArranger)
);
break;
case ListViewView::SmallIcon:
SetStyleAndArranger(
[](const Value&) { return new list::SmallIconListViewItemTemplate; },
Ptr(new list::FixedSizeMultiColumnItemArranger)
);
break;
case ListViewView::List:
SetStyleAndArranger(
[](const Value&) { return new list::ListListViewItemTemplate; },
Ptr(new list::FixedHeightMultiColumnItemArranger)
);
break;
case ListViewView::Tile:
SetStyleAndArranger(
[](const Value&) { return new list::TileListViewItemTemplate; },
Ptr(new list::FixedSizeMultiColumnItemArranger)
);
break;
case ListViewView::Information:
SetStyleAndArranger(
[](const Value&) { return new list::InformationListViewItemTemplate; },
Ptr(new list::FixedHeightItemArranger)
);
break;
case ListViewView::Detail:
SetStyleAndArranger(
[](const Value&) { return new list::DetailListViewItemTemplate; },
Ptr(new list::ListViewColumnItemArranger)
);
break;
default:;
}
view = _view;
}
/***********************************************************************
GuiListView
***********************************************************************/
GuiListView::GuiListView(theme::ThemeName themeName)
:GuiVirtualListView(themeName, new list::ListViewItemProvider)
{
items=dynamic_cast<list::ListViewItemProvider*>(itemProvider.Obj());
}
GuiListView::~GuiListView()
{
}
list::ListViewItemProvider& GuiListView::GetItems()
{
return *items;
}
list::ListViewDataColumns& GuiListView::GetDataColumns()
{
return items->GetDataColumns();
}
list::ListViewColumns& GuiListView::GetColumns()
{
return items->GetColumns();
}
Ptr<list::ListViewItem> GuiListView::GetSelectedItem()
{
vint index = GetSelectedItemIndex();
if (index == -1) return 0;
return items->Get(index);
}
}
}
}
/***********************************************************************
.\CONTROLS\LISTCONTROLPACKAGE\GUILISTVIEWITEMTEMPLATES.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace elements;
using namespace compositions;
using namespace collections;
using namespace reflection::description;
namespace list
{
/***********************************************************************
DefaultListViewItemTemplate
***********************************************************************/
DefaultListViewItemTemplate::DefaultListViewItemTemplate()
{
SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
}
DefaultListViewItemTemplate::~DefaultListViewItemTemplate()
{
}
/***********************************************************************
BigIconListViewItemTemplate
***********************************************************************/
void BigIconListViewItemTemplate::OnInitialize()
{
{
auto table = new GuiTableComposition;
AddChild(table);
table->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
table->SetRowsAndColumns(2, 3);
table->SetRowOption(0, GuiCellOption::MinSizeOption());
table->SetRowOption(1, GuiCellOption::MinSizeOption());
table->SetColumnOption(0, GuiCellOption::PercentageOption(0.5));
table->SetColumnOption(1, GuiCellOption::MinSizeOption());
table->SetColumnOption(2, GuiCellOption::PercentageOption(0.5));
table->SetAlignmentToParent(Margin(0, 0, 0, 0));
table->SetCellPadding(5);
{
auto cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(0, 1, 1, 1);
cell->SetPreferredMinSize(Size(32, 32));
image = GuiImageFrameElement::Create();
image->SetStretch(true);
cell->SetOwnedElement(Ptr(image));
}
{
auto cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetMinSizeLimitation(GuiGraphicsComposition::NoLimit);
cell->SetSite(1, 0, 1, 3);
cell->SetPreferredMinSize(Size(64, 40));
text = GuiSolidLabelElement::Create();
text->SetAlignments(Alignment::Center, Alignment::Top);
text->SetWrapLine(true);
text->SetEllipse(true);
cell->SetOwnedElement(Ptr(text));
}
}
FontChanged.AttachMethod(this, &BigIconListViewItemTemplate::OnFontChanged);
FontChanged.Execute(compositions::GuiEventArgs(this));
}
void BigIconListViewItemTemplate::OnRefresh()
{
if (auto listView = dynamic_cast<GuiVirtualListView*>(listControl))
{
auto itemIndex = GetIndex();
if (auto view = dynamic_cast<IListViewItemView*>(listView->GetItemProvider()->RequestView(WString::Unmanaged(IListViewItemView::Identifier))))
{
auto imageData = view->GetLargeImage(itemIndex);
if (imageData)
{
image->SetImage(imageData->GetImage(), imageData->GetFrameIndex());
}
else
{
image->SetImage(nullptr);
}
text->SetText(view->GetText(itemIndex));
text->SetColor(listView->TypedControlTemplateObject(true)->GetPrimaryTextColor());
}
}
}
void BigIconListViewItemTemplate::OnFontChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
text->SetFont(GetFont());
}
BigIconListViewItemTemplate::BigIconListViewItemTemplate()
{
}
BigIconListViewItemTemplate::~BigIconListViewItemTemplate()
{
}
/***********************************************************************
SmallIconListViewItemTemplate
***********************************************************************/
void SmallIconListViewItemTemplate::OnInitialize()
{
{
auto table = new GuiTableComposition;
AddChild(table);
table->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
table->SetRowsAndColumns(3, 2);
table->SetRowOption(0, GuiCellOption::PercentageOption(0.5));
table->SetRowOption(1, GuiCellOption::MinSizeOption());
table->SetRowOption(2, GuiCellOption::PercentageOption(0.5));
table->SetColumnOption(0, GuiCellOption::MinSizeOption());
table->SetColumnOption(1, GuiCellOption::MinSizeOption());
table->SetAlignmentToParent(Margin(0, 0, 0, 0));
table->SetCellPadding(2);
{
GuiCellComposition* cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(1, 0, 1, 1);
cell->SetPreferredMinSize(Size(16, 16));
image = GuiImageFrameElement::Create();
image->SetStretch(true);
cell->SetOwnedElement(Ptr(image));
}
{
GuiCellComposition* cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(0, 1, 3, 1);
cell->SetPreferredMinSize(Size(192, 0));
text = GuiSolidLabelElement::Create();
text->SetAlignments(Alignment::Left, Alignment::Center);
text->SetEllipse(true);
cell->SetOwnedElement(Ptr(text));
}
}
FontChanged.AttachMethod(this, &SmallIconListViewItemTemplate::OnFontChanged);
FontChanged.Execute(compositions::GuiEventArgs(this));
}
void SmallIconListViewItemTemplate::OnRefresh()
{
if (auto listView = dynamic_cast<GuiVirtualListView*>(listControl))
{
auto itemIndex = GetIndex();
if (auto view = dynamic_cast<IListViewItemView*>(listView->GetItemProvider()->RequestView(WString::Unmanaged(IListViewItemView::Identifier))))
{
auto imageData = view->GetSmallImage(itemIndex);
if (imageData)
{
image->SetImage(imageData->GetImage(), imageData->GetFrameIndex());
}
else
{
image->SetImage(nullptr);
}
text->SetText(view->GetText(itemIndex));
text->SetColor(listView->TypedControlTemplateObject(true)->GetPrimaryTextColor());
}
}
}
void SmallIconListViewItemTemplate::OnFontChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
text->SetFont(GetFont());
}
SmallIconListViewItemTemplate::SmallIconListViewItemTemplate()
{
}
SmallIconListViewItemTemplate::~SmallIconListViewItemTemplate()
{
}
/***********************************************************************
ListListViewItemTemplate
***********************************************************************/
void ListListViewItemTemplate::OnInitialize()
{
{
auto table = new GuiTableComposition;
AddChild(table);
table->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
table->SetRowsAndColumns(3, 2);
table->SetRowOption(0, GuiCellOption::PercentageOption(0.5));
table->SetRowOption(1, GuiCellOption::MinSizeOption());
table->SetRowOption(2, GuiCellOption::PercentageOption(0.5));
table->SetColumnOption(0, GuiCellOption::MinSizeOption());
table->SetColumnOption(1, GuiCellOption::MinSizeOption());
table->SetAlignmentToParent(Margin(0, 0, 0, 0));
table->SetCellPadding(2);
{
auto cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(1, 0, 1, 1);
cell->SetPreferredMinSize(Size(16, 16));
image = GuiImageFrameElement::Create();
image->SetStretch(true);
cell->SetOwnedElement(Ptr(image));
}
{
auto cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(0, 1, 3, 1);
auto textBounds = new GuiBoundsComposition;
cell->AddChild(textBounds);
textBounds->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElement);
textBounds->SetAlignmentToParent(Margin(0, 0, 16, 0));
text = GuiSolidLabelElement::Create();
text->SetAlignments(Alignment::Left, Alignment::Center);
textBounds->SetOwnedElement(Ptr(text));
}
}
FontChanged.AttachMethod(this, &ListListViewItemTemplate::OnFontChanged);
FontChanged.Execute(compositions::GuiEventArgs(this));
}
void ListListViewItemTemplate::OnRefresh()
{
if (auto listView = dynamic_cast<GuiVirtualListView*>(listControl))
{
auto itemIndex = GetIndex();
if (auto view = dynamic_cast<IListViewItemView*>(listView->GetItemProvider()->RequestView(WString::Unmanaged(IListViewItemView::Identifier))))
{
auto imageData = view->GetSmallImage(itemIndex);
if (imageData)
{
image->SetImage(imageData->GetImage(), imageData->GetFrameIndex());
}
else
{
image->SetImage(nullptr);
}
text->SetText(view->GetText(itemIndex));
text->SetColor(listView->TypedControlTemplateObject(true)->GetPrimaryTextColor());
}
}
}
void ListListViewItemTemplate::OnFontChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
text->SetFont(GetFont());
}
ListListViewItemTemplate::ListListViewItemTemplate()
{
}
ListListViewItemTemplate::~ListListViewItemTemplate()
{
}
/***********************************************************************
TileListViewItemTemplate
***********************************************************************/
elements::GuiSolidLabelElement* TileListViewItemTemplate::CreateTextElement(vint textRow)
{
auto cell = new GuiCellComposition;
textTable->AddChild(cell);
cell->SetSite(textRow + 1, 0, 1, 1);
auto textElement = Ptr(GuiSolidLabelElement::Create());
textElement->SetAlignments(Alignment::Left, Alignment::Center);
textElement->SetEllipse(true);
cell->SetOwnedElement(textElement);
return textElement.Obj();
}
void TileListViewItemTemplate::ResetTextTable(vint dataColumnCount)
{
if (text && dataTexts.Count() == dataColumnCount) return;
for (vint i = textTable->Children().Count() - 1; i >= 0; i--)
{
if (auto cell = dynamic_cast<GuiCellComposition*>(textTable->Children()[i]))
{
SafeDeleteComposition(cell);
}
}
{
vint textRows = dataColumnCount + 1;
textTable->SetRowsAndColumns(textRows + 2, 1);
textTable->SetRowOption(0, GuiCellOption::PercentageOption(0.5));
for (vint i = 0; i < textRows; i++)
{
textTable->SetRowOption(i + 1, GuiCellOption::MinSizeOption());
}
textTable->SetRowOption(textRows + 1, GuiCellOption::PercentageOption(0.5));
textTable->SetColumnOption(0, GuiCellOption::PercentageOption(1.0));
}
text = CreateTextElement(0);
text->SetFont(GetFont());
{
dataTexts.Resize(dataColumnCount);
for (vint i = 0; i < dataColumnCount; i++)
{
dataTexts[i] = CreateTextElement(i + 1);
dataTexts[i]->SetFont(GetFont());
}
}
}
void TileListViewItemTemplate::OnInitialize()
{
{
auto table = new GuiTableComposition;
AddChild(table);
table->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
table->SetRowsAndColumns(3, 2);
table->SetRowOption(0, GuiCellOption::PercentageOption(0.5));
table->SetRowOption(1, GuiCellOption::MinSizeOption());
table->SetRowOption(2, GuiCellOption::PercentageOption(0.5));
table->SetColumnOption(0, GuiCellOption::MinSizeOption());
table->SetColumnOption(1, GuiCellOption::MinSizeOption());
table->SetAlignmentToParent(Margin(0, 0, 0, 0));
table->SetCellPadding(4);
{
auto cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(1, 0, 1, 1);
cell->SetPreferredMinSize(Size(32, 32));
image = GuiImageFrameElement::Create();
image->SetStretch(true);
cell->SetOwnedElement(Ptr(image));
}
{
auto cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(0, 1, 3, 1);
cell->SetPreferredMinSize(Size(224, 0));
textTable = new GuiTableComposition;
textTable->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
textTable->SetCellPadding(1);
textTable->SetAlignmentToParent(Margin(0, 0, 0, 0));
cell->AddChild(textTable);
}
}
ResetTextTable(0);
FontChanged.AttachMethod(this, &TileListViewItemTemplate::OnFontChanged);
FontChanged.Execute(compositions::GuiEventArgs(this));
}
void TileListViewItemTemplate::OnRefresh()
{
if (auto listView = dynamic_cast<GuiVirtualListView*>(listControl))
{
auto itemIndex = GetIndex();
if (auto view = dynamic_cast<IListViewItemView*>(listView->GetItemProvider()->RequestView(WString::Unmanaged(IListViewItemView::Identifier))))
{
auto imageData = view->GetLargeImage(itemIndex);
if (imageData)
{
image->SetImage(imageData->GetImage(), imageData->GetFrameIndex());
}
else
{
image->SetImage(nullptr);
}
vint subColumnCount = view->GetColumnCount() - 1;
vint dataColumnCount = view->GetDataColumnCount();
if (dataColumnCount > subColumnCount) dataColumnCount = subColumnCount;
if (dataColumnCount < 0) dataColumnCount = 0;
ResetTextTable(dataColumnCount);
text->SetText(view->GetText(itemIndex));
text->SetColor(listView->TypedControlTemplateObject(true)->GetPrimaryTextColor());
for (vint i = 0; i < dataColumnCount; i++)
{
dataTexts[i]->SetText(view->GetSubItem(itemIndex, view->GetDataColumn(i)));
dataTexts[i]->SetColor(listView->TypedControlTemplateObject(true)->GetSecondaryTextColor());
}
}
}
}
void TileListViewItemTemplate::OnFontChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (text) text->SetFont(GetFont());
for (auto dataText : dataTexts)
{
dataText->SetFont(GetFont());
}
}
TileListViewItemTemplate::TileListViewItemTemplate()
{
}
TileListViewItemTemplate::~TileListViewItemTemplate()
{
}
/***********************************************************************
InformationListViewItemTemplate
***********************************************************************/
void InformationListViewItemTemplate::ResetTextTable(vint dataColumnCount)
{
if (dataTexts.Count() == dataColumnCount) return;
for (vint i = textTable->Children().Count() - 1; i >= 0; i--)
{
if (auto cell = dynamic_cast<GuiCellComposition*>(textTable->Children()[i]))
{
SafeDeleteComposition(cell);
}
}
{
textTable->SetRowsAndColumns(dataColumnCount + 2, 1);
textTable->SetRowOption(0, GuiCellOption::PercentageOption(0.5));
for (vint i = 0; i < dataColumnCount; i++)
{
textTable->SetRowOption(i + 1, GuiCellOption::MinSizeOption());
}
textTable->SetRowOption(dataColumnCount + 1, GuiCellOption::PercentageOption(0.5));
textTable->SetColumnOption(0, GuiCellOption::PercentageOption(1.0));
}
columnTexts.Resize(dataColumnCount);
dataTexts.Resize(dataColumnCount);
for (vint i = 0; i < dataColumnCount; i++)
{
auto cell = new GuiCellComposition;
textTable->AddChild(cell);
cell->SetSite(i + 1, 0, 1, 1);
auto dataTable = new GuiTableComposition;
dataTable->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
dataTable->SetRowsAndColumns(1, 2);
dataTable->SetRowOption(0, GuiCellOption::MinSizeOption());
dataTable->SetColumnOption(0, GuiCellOption::MinSizeOption());
dataTable->SetColumnOption(1, GuiCellOption::PercentageOption(1.0));
dataTable->SetAlignmentToParent(Margin(0, 0, 0, 0));
cell->AddChild(dataTable);
{
auto cell = new GuiCellComposition;
dataTable->AddChild(cell);
cell->SetSite(0, 0, 1, 1);
columnTexts[i] = GuiSolidLabelElement::Create();
columnTexts[i]->SetFont(GetFont());
cell->SetOwnedElement(Ptr(columnTexts[i]));
}
{
auto cell = new GuiCellComposition;
dataTable->AddChild(cell);
cell->SetSite(0, 1, 1, 1);
dataTexts[i] = GuiSolidLabelElement::Create();
dataTexts[i]->SetFont(GetFont());
dataTexts[i]->SetEllipse(true);
cell->SetOwnedElement(Ptr(dataTexts[i]));
}
}
}
void InformationListViewItemTemplate::OnInitialize()
{
{
bottomLine = GuiSolidBackgroundElement::Create();
bottomLineComposition = new GuiBoundsComposition;
bottomLineComposition->SetOwnedElement(Ptr(bottomLine));
bottomLineComposition->SetAlignmentToParent(Margin(8, -1, 8, 0));
bottomLineComposition->SetPreferredMinSize(Size(0, 1));
AddChild(bottomLineComposition);
auto table = new GuiTableComposition;
AddChild(table);
table->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
table->SetRowsAndColumns(3, 3);
table->SetRowOption(0, GuiCellOption::PercentageOption(0.5));
table->SetRowOption(1, GuiCellOption::MinSizeOption());
table->SetRowOption(2, GuiCellOption::PercentageOption(0.5));
table->SetColumnOption(0, GuiCellOption::MinSizeOption());
table->SetColumnOption(1, GuiCellOption::PercentageOption(1.0));
table->SetColumnOption(2, GuiCellOption::MinSizeOption());
table->SetAlignmentToParent(Margin(0, 0, 0, 0));
table->SetCellPadding(4);
{
auto cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(1, 0, 1, 1);
cell->SetPreferredMinSize(Size(32, 32));
image = GuiImageFrameElement::Create();
image->SetStretch(true);
cell->SetOwnedElement(Ptr(image));
}
{
auto cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(0, 1, 3, 1);
text = GuiSolidLabelElement::Create();
text->SetEllipse(true);
cell->SetOwnedElement(Ptr(text));
}
{
auto cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(0, 2, 3, 1);
cell->SetPreferredMinSize(Size(224, 0));
textTable = new GuiTableComposition;
textTable->SetCellPadding(4);
textTable->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
textTable->SetAlignmentToParent(Margin(0, 0, 0, 0));
cell->AddChild(textTable);
}
}
FontChanged.AttachMethod(this, &InformationListViewItemTemplate::OnFontChanged);
FontChanged.Execute(compositions::GuiEventArgs(this));
}
void InformationListViewItemTemplate::OnRefresh()
{
if (auto listView = dynamic_cast<GuiVirtualListView*>(listControl))
{
auto itemIndex = GetIndex();
if (auto view = dynamic_cast<IListViewItemView*>(listView->GetItemProvider()->RequestView(WString::Unmanaged(IListViewItemView::Identifier))))
{
auto imageData = view->GetLargeImage(itemIndex);
if (imageData)
{
image->SetImage(imageData->GetImage(), imageData->GetFrameIndex());
}
else
{
image->SetImage(nullptr);
}
text->SetText(view->GetText(itemIndex));
text->SetColor(listView->TypedControlTemplateObject(true)->GetPrimaryTextColor());
bottomLine->SetColor(listView->TypedControlTemplateObject(true)->GetItemSeparatorColor());
vint subColumnCount = view->GetColumnCount() - 1;
vint dataColumnCount = view->GetDataColumnCount();
if (dataColumnCount > subColumnCount) dataColumnCount = subColumnCount;
if (dataColumnCount < 0) dataColumnCount = 0;
ResetTextTable(dataColumnCount);
for (vint i = 0; i < dataColumnCount; i++)
{
{
columnTexts[i]->SetText(view->GetColumnText(view->GetDataColumn(i) + 1) + L": ");
columnTexts[i]->SetColor(listView->TypedControlTemplateObject(true)->GetSecondaryTextColor());
}
{
dataTexts[i]->SetText(view->GetSubItem(itemIndex, view->GetDataColumn(i)));
dataTexts[i]->SetColor(listView->TypedControlTemplateObject(true)->GetPrimaryTextColor());
}
}
}
}
}
void InformationListViewItemTemplate::OnFontChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
{
auto font = GetFont();
font.size = (vint)(font.size * 1.2);
text->SetFont(font);
}
for (auto columnText : columnTexts)
{
columnText->SetFont(GetFont());
}
for (auto dataText : dataTexts)
{
dataText->SetFont(GetFont());
}
}
InformationListViewItemTemplate::InformationListViewItemTemplate()
{
}
InformationListViewItemTemplate::~InformationListViewItemTemplate()
{
}
/***********************************************************************
DetailListViewItemTemplate
***********************************************************************/
void DetailListViewItemTemplate::UpdateSubItemSize()
{
if (auto view = dynamic_cast<IListViewItemView*>(listControl->GetItemProvider()->RequestView(WString::Unmanaged(IListViewItemView::Identifier))))
{
if (columnItemView)
{
vint columnCount = view->GetColumnCount();
if (columnCount > textTable->GetColumns())
{
columnCount = textTable->GetColumns();
}
for (vint i = 0; i < columnCount; i++)
{
textTable->SetColumnOption(i, GuiCellOption::AbsoluteOption(columnItemView->GetColumnSize(i)));
}
}
}
}
void DetailListViewItemTemplate::ResetTextTable(vint subColumnCount)
{
if (subItemCells.Count() == subColumnCount) return;
for (auto cell : subItemCells)
{
SafeDeleteComposition(cell);
}
subItemCells.Resize(subColumnCount);
subItemTexts.Resize(subColumnCount);
textTable->SetRowsAndColumns(1, subColumnCount + 1);
for (vint i = 0; i < subColumnCount; i++)
{
auto cell = new GuiCellComposition;
textTable->AddChild(cell);
cell->SetSite(0, i + 1, 1, 1);
auto textBounds = new GuiBoundsComposition;
cell->AddChild(textBounds);
textBounds->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElement);
textBounds->SetAlignmentToParent(Margin(8, 0, 8, 0));
auto subText = GuiSolidLabelElement::Create();
subText->SetAlignments(Alignment::Left, Alignment::Center);
subText->SetFont(GetFont());
subText->SetEllipse(true);
textBounds->SetOwnedElement(Ptr(subText));
subItemCells[i] = cell;
subItemTexts[i] = subText;
}
}
void DetailListViewItemTemplate::OnInitialize()
{
columnItemView = dynamic_cast<ListViewColumnItemArranger::IColumnItemView*>(listControl->GetItemProvider()->RequestView(WString::Unmanaged(ListViewColumnItemArranger::IColumnItemView::Identifier)));
{
textTable = new GuiTableComposition;
textTable->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
textTable->SetAlignmentToParent(Margin(0, 0, 0, 0));
textTable->SetRowsAndColumns(1, 1);
textTable->SetRowOption(0, GuiCellOption::MinSizeOption());
textTable->SetColumnOption(0, GuiCellOption::AbsoluteOption(0));
AddChild(textTable);
{
auto cell = new GuiCellComposition;
textTable->AddChild(cell);
cell->SetSite(0, 0, 1, 1);
auto table = new GuiTableComposition;
cell->AddChild(table);
table->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
table->SetRowsAndColumns(3, 2);
table->SetRowOption(0, GuiCellOption::PercentageOption(0.5));
table->SetRowOption(1, GuiCellOption::MinSizeOption());
table->SetRowOption(2, GuiCellOption::PercentageOption(0.5));
table->SetColumnOption(0, GuiCellOption::MinSizeOption());
table->SetColumnOption(1, GuiCellOption::PercentageOption(1.0));
table->SetAlignmentToParent(Margin(0, 0, 0, 0));
table->SetCellPadding(2);
{
auto cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(1, 0, 1, 1);
cell->SetPreferredMinSize(Size(16, 16));
image = GuiImageFrameElement::Create();
image->SetStretch(true);
cell->SetOwnedElement(Ptr(image));
}
{
auto cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(0, 1, 3, 1);
auto textBounds = new GuiBoundsComposition;
cell->AddChild(textBounds);
textBounds->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElement);
textBounds->SetAlignmentToParent(Margin(0, 0, 8, 0));
text = GuiSolidLabelElement::Create();
text->SetAlignments(Alignment::Left, Alignment::Center);
text->SetFont(GetFont());
text->SetEllipse(true);
textBounds->SetOwnedElement(Ptr(text));
}
}
}
FontChanged.AttachMethod(this, &DetailListViewItemTemplate::OnFontChanged);
FontChanged.Execute(compositions::GuiEventArgs(this));
}
void DetailListViewItemTemplate::OnRefresh()
{
if (auto listView = dynamic_cast<GuiVirtualListView*>(listControl))
{
auto itemIndex = GetIndex();
if (auto view = dynamic_cast<IListViewItemView*>(listView->GetItemProvider()->RequestView(WString::Unmanaged(IListViewItemView::Identifier))))
{
vint subColumnCount = view->GetColumnCount() - 1;
if (subColumnCount < 0) subColumnCount = 0;
ResetTextTable(subColumnCount);
auto imageData = view->GetSmallImage(itemIndex);
if (imageData)
{
image->SetImage(imageData->GetImage(), imageData->GetFrameIndex());
}
else
{
image->SetImage(0);
}
text->SetText(view->GetText(itemIndex));
text->SetColor(listView->TypedControlTemplateObject(true)->GetPrimaryTextColor());
for (vint i = 0; i < subColumnCount; i++)
{
subItemTexts[i]->SetText(view->GetSubItem(itemIndex, i));
subItemTexts[i]->SetColor(listView->TypedControlTemplateObject(true)->GetSecondaryTextColor());
}
}
}
UpdateSubItemSize();
}
void DetailListViewItemTemplate::OnFontChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
text->SetFont(GetFont());
for (auto subText : subItemTexts)
{
subText->SetFont(GetFont());
}
}
DetailListViewItemTemplate::DetailListViewItemTemplate()
{
}
DetailListViewItemTemplate::~DetailListViewItemTemplate()
{
}
}
}
}
}
/***********************************************************************
.\CONTROLS\LISTCONTROLPACKAGE\GUITEXTLISTCONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace collections;
using namespace elements;
using namespace compositions;
using namespace reflection::description;
namespace list
{
const wchar_t* const ITextItemView::Identifier = L"vl::presentation::controls::list::ITextItemView";
/***********************************************************************
DefaultTextListItemTemplate
***********************************************************************/
TemplateProperty<DefaultTextListItemTemplate::BulletStyle> DefaultTextListItemTemplate::CreateBulletStyle()
{
return {};
}
void DefaultTextListItemTemplate::OnInitialize()
{
SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
textElement = GuiSolidLabelElement::Create();
textElement->SetAlignments(Alignment::Left, Alignment::Center);
GuiBoundsComposition* textComposition = new GuiBoundsComposition;
textComposition->SetOwnedElement(Ptr(textElement));
textComposition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElement);
if (auto bulletStyleController = CreateBulletStyle())
{
bulletButton = new GuiSelectableButton(theme::ThemeName::Unknown);
bulletButton->SetAutoFocus(false);
bulletButton->SetControlTemplate(bulletStyleController);
bulletButton->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
bulletButton->SelectedChanged.AttachMethod(this, &DefaultTextListItemTemplate::OnBulletSelectedChanged);
GuiTableComposition* table = new GuiTableComposition;
AddChild(table);
table->SetAlignmentToParent(Margin(0, 0, 0, 0));
table->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
table->SetRowsAndColumns(1, 2);
table->SetRowOption(0, GuiCellOption::PercentageOption(1.0));
table->SetColumnOption(0, GuiCellOption::MinSizeOption());
table->SetColumnOption(1, GuiCellOption::PercentageOption(1.0));
{
GuiCellComposition* cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(0, 0, 1, 1);
cell->AddChild(bulletButton->GetBoundsComposition());
}
{
GuiCellComposition* cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(0, 1, 1, 1);
cell->AddChild(textComposition);
textComposition->SetAlignmentToParent(Margin(0, 0, 0, 0));
}
}
else
{
AddChild(textComposition);
textComposition->SetAlignmentToParent(Margin(5, 2, 0, 2));
}
FontChanged.AttachMethod(this, &DefaultTextListItemTemplate::OnFontChanged);
TextChanged.AttachMethod(this, &DefaultTextListItemTemplate::OnTextChanged);
TextColorChanged.AttachMethod(this, &DefaultTextListItemTemplate::OnTextColorChanged);
CheckedChanged.AttachMethod(this, &DefaultTextListItemTemplate::OnCheckedChanged);
FontChanged.Execute(compositions::GuiEventArgs(this));
TextChanged.Execute(compositions::GuiEventArgs(this));
TextColorChanged.Execute(compositions::GuiEventArgs(this));
CheckedChanged.Execute(compositions::GuiEventArgs(this));
}
void DefaultTextListItemTemplate::OnRefresh()
{
}
void DefaultTextListItemTemplate::OnFontChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
textElement->SetFont(GetFont());
}
void DefaultTextListItemTemplate::OnTextChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
textElement->SetText(GetText());
}
void DefaultTextListItemTemplate::OnTextColorChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
textElement->SetColor(GetTextColor());
}
void DefaultTextListItemTemplate::OnCheckedChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (bulletButton)
{
supressEdit = true;
bulletButton->SetSelected(GetChecked());
supressEdit = false;
}
}
void DefaultTextListItemTemplate::OnBulletSelectedChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::controls::list::DefaultTextListItemTemplate::OnBulletSelectedChanged(GuiGraphicsComposition*, GuiEventArgs&)#"
if (!supressEdit)
{
if (auto textItemView = dynamic_cast<ITextItemView*>(listControl->GetItemProvider()->RequestView(WString::Unmanaged(ITextItemView::Identifier))))
{
listControl->GetItemProvider()->PushEditing();
textItemView->SetChecked(GetIndex(), bulletButton->GetSelected());
CHECK_ERROR(listControl->GetItemProvider()->PopEditing(), ERROR_MESSAGE_PREFIX L"BeginEditListItem and EndEditListItem calls are not paired.");
}
}
#undef ERROR_MESSAGE_PREFIX
}
DefaultTextListItemTemplate::DefaultTextListItemTemplate()
{
}
DefaultTextListItemTemplate::~DefaultTextListItemTemplate()
{
}
/***********************************************************************
DefaultCheckTextListItemTemplate
***********************************************************************/
TemplateProperty<DefaultTextListItemTemplate::BulletStyle> DefaultCheckTextListItemTemplate::CreateBulletStyle()
{
if (auto textList = dynamic_cast<GuiVirtualTextList*>(listControl))
{
auto style = textList->TypedControlTemplateObject(true)->GetCheckBulletTemplate();
if (style) return style;
}
return theme::GetCurrentTheme()->CreateStyle(theme::ThemeName::CheckTextListItem);
}
/***********************************************************************
DefaultRadioTextListItemTemplate
***********************************************************************/
TemplateProperty<DefaultTextListItemTemplate::BulletStyle> DefaultRadioTextListItemTemplate::CreateBulletStyle()
{
if (auto textList = dynamic_cast<GuiVirtualTextList*>(listControl))
{
auto style = textList->TypedControlTemplateObject(true)->GetRadioBulletTemplate();
if (style) return style;
}
return theme::GetCurrentTheme()->CreateStyle(theme::ThemeName::RadioTextListItem);
}
/***********************************************************************
TextItem
***********************************************************************/
void TextItem::NotifyUpdate(bool raiseCheckEvent)
{
if (owner)
{
vint index = owner->IndexOf(this);
owner->InvokeOnItemModified(index, 1, 1, false);
if (raiseCheckEvent)
{
GuiItemEventArgs arguments;
arguments.itemIndex = index;
owner->listControl->ItemChecked.Execute(arguments);
}
}
}
TextItem::TextItem()
:owner(0)
, checked(false)
{
}
TextItem::TextItem(const WString& _text, bool _checked)
:owner(0)
, text(_text)
, checked(_checked)
{
}
TextItem::~TextItem()
{
}
const WString& TextItem::GetText()
{
return text;
}
void TextItem::SetText(const WString& value)
{
if (text != value)
{
text = value;
NotifyUpdate(false);
}
}
bool TextItem::GetChecked()
{
return checked;
}
void TextItem::SetChecked(bool value)
{
if (checked != value)
{
checked = value;
NotifyUpdate(true);
}
}
/***********************************************************************
TextItemProvider
***********************************************************************/
void TextItemProvider::AfterInsert(vint item, const Ptr<TextItem>& value)
{
ListProvider<Ptr<TextItem>>::AfterInsert(item, value);
value->owner = this;
}
void TextItemProvider::BeforeRemove(vint item, const Ptr<TextItem>& value)
{
value->owner = 0;
ListProvider<Ptr<TextItem>>::BeforeRemove(item, value);
}
WString TextItemProvider::GetTextValue(vint itemIndex)
{
return Get(itemIndex)->GetText();
}
description::Value TextItemProvider::GetBindingValue(vint itemIndex)
{
return Value::From(Get(itemIndex));
}
bool TextItemProvider::GetChecked(vint itemIndex)
{
return Get(itemIndex)->GetChecked();
}
void TextItemProvider::SetChecked(vint itemIndex, bool value)
{
return Get(itemIndex)->SetChecked(value);
}
TextItemProvider::TextItemProvider()
:listControl(0)
{
}
TextItemProvider::~TextItemProvider()
{
}
IDescriptable* TextItemProvider::RequestView(const WString& identifier)
{
if (identifier == ITextItemView::Identifier)
{
return (ITextItemView*)this;
}
else
{
return nullptr;
}
}
}
/***********************************************************************
GuiTextList
***********************************************************************/
void GuiVirtualTextList::BeforeControlTemplateUninstalled_()
{
}
void GuiVirtualTextList::AfterControlTemplateInstalled_(bool initialize)
{
}
void GuiVirtualTextList::OnStyleInstalled(vint itemIndex, ItemStyle* style, bool refreshPropertiesOnly)
{
GuiSelectableListControl::OnStyleInstalled(itemIndex, style, refreshPropertiesOnly);
if (auto textItemStyle = dynamic_cast<templates::GuiTextListItemTemplate*>(style))
{
textItemStyle->SetTextColor(TypedControlTemplateObject(true)->GetTextColor());
if (auto textItemView = dynamic_cast<list::ITextItemView*>(itemProvider->RequestView(WString::Unmanaged(list::ITextItemView::Identifier))))
{
textItemStyle->SetChecked(textItemView->GetChecked(itemIndex));
}
}
if (refreshPropertiesOnly)
{
if (auto predefinedItemStyle = dynamic_cast<list::DefaultTextListItemTemplate*>(style))
{
predefinedItemStyle->RefreshItem();
}
}
}
void GuiVirtualTextList::OnItemTemplateChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
view = TextListView::Unknown;
}
GuiVirtualTextList::GuiVirtualTextList(theme::ThemeName themeName, list::IItemProvider* _itemProvider)
:GuiSelectableListControl(themeName, _itemProvider)
{
ItemTemplateChanged.AttachMethod(this, &GuiVirtualTextList::OnItemTemplateChanged);
ItemChecked.SetAssociatedComposition(boundsComposition);
SetView(TextListView::Text);
}
GuiVirtualTextList::~GuiVirtualTextList()
{
}
TextListView GuiVirtualTextList::GetView()
{
return view;
}
void GuiVirtualTextList::SetView(TextListView _view)
{
switch (_view)
{
case TextListView::Text:
SetStyleAndArranger(
[](const Value&) { return new list::DefaultTextListItemTemplate; },
Ptr(new list::FixedHeightItemArranger)
);
break;
case TextListView::Check:
SetStyleAndArranger(
[](const Value&) { return new list::DefaultCheckTextListItemTemplate; },
Ptr(new list::FixedHeightItemArranger)
);
break;
case TextListView::Radio:
SetStyleAndArranger(
[](const Value&) { return new list::DefaultRadioTextListItemTemplate; },
Ptr(new list::FixedHeightItemArranger)
);
break;
default:;
}
view = _view;
}
/***********************************************************************
GuiTextList
***********************************************************************/
GuiTextList::GuiTextList(theme::ThemeName themeName)
:GuiVirtualTextList(themeName, new list::TextItemProvider)
{
items=dynamic_cast<list::TextItemProvider*>(itemProvider.Obj());
items->listControl=this;
}
GuiTextList::~GuiTextList()
{
}
list::TextItemProvider& GuiTextList::GetItems()
{
return *items;
}
Ptr<list::TextItem> GuiTextList::GetSelectedItem()
{
vint index = GetSelectedItemIndex();
if (index == -1) return 0;
return items->Get(index);
}
}
}
}
/***********************************************************************
.\CONTROLS\LISTCONTROLPACKAGE\GUITREEVIEWCONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace elements;
using namespace compositions;
using namespace reflection::description;
/***********************************************************************
GuiVirtualTreeListControl
***********************************************************************/
void GuiVirtualTreeListControl::BeforeControlTemplateUninstalled_()
{
}
void GuiVirtualTreeListControl::AfterControlTemplateInstalled_(bool initialize)
{
}
void GuiVirtualTreeListControl::OnAttached(tree::INodeRootProvider* provider)
{
}
void GuiVirtualTreeListControl::OnBeforeItemModified(tree::INodeProvider* parentNode, vint start, vint count, vint newCount, bool itemReferenceUpdated)
{
}
void GuiVirtualTreeListControl::OnAfterItemModified(tree::INodeProvider* parentNode, vint start, vint count, vint newCount, bool itemReferenceUpdated)
{
}
void GuiVirtualTreeListControl::OnItemExpanded(tree::INodeProvider* node)
{
GuiNodeEventArgs arguments;
(GuiEventArgs&)arguments=GetNotifyEventArguments();
arguments.node=node;
NodeExpanded.Execute(arguments);
}
void GuiVirtualTreeListControl::OnItemCollapsed(tree::INodeProvider* node)
{
GuiNodeEventArgs arguments;
(GuiEventArgs&)arguments=GetNotifyEventArguments();
arguments.node=node;
NodeCollapsed.Execute(arguments);
}
vint GuiVirtualTreeListControl::FindItemByVirtualKeyDirection(vint index, compositions::KeyDirection keyDirection)
{
vint newIndex = GuiSelectableListControl::FindItemByVirtualKeyDirection(index, keyDirection);
if (newIndex != -1) return newIndex;
auto selectedNode = nodeItemView->RequestNode(index);
if (selectedNode)
{
bool hasChildren = selectedNode->GetChildCount() > 0;
bool expanding = selectedNode->GetExpanding();
switch (keyDirection)
{
case KeyDirection::Right:
if (hasChildren)
{
if (expanding)
{
selectedNode = selectedNode->GetChild(0);
}
else
{
selectedNode->SetExpanding(true);
}
}
break;
case KeyDirection::Left:
{
selectedNode->SetExpanding(false);
if (!expanding || !hasChildren)
{
selectedNode = selectedNode->GetParent();
}
}
break;
default:;
}
}
return selectedNode ? nodeItemView->CalculateNodeVisibilityIndex(selectedNode.Obj()) : -1;
}
void GuiVirtualTreeListControl::OnItemMouseEvent(compositions::GuiNodeMouseEvent& nodeEvent, compositions::GuiGraphicsComposition* sender, compositions::GuiItemMouseEventArgs& arguments)
{
auto node = GetNodeItemView()->RequestNode(arguments.itemIndex);
if (node)
{
GuiNodeMouseEventArgs redirectArguments;
(GuiMouseEventArgs&)redirectArguments = arguments;
redirectArguments.node = node.Obj();
nodeEvent.Execute(redirectArguments);
(GuiMouseEventArgs&)arguments = redirectArguments;
}
}
void GuiVirtualTreeListControl::OnItemNotifyEvent(compositions::GuiNodeNotifyEvent& nodeEvent, compositions::GuiGraphicsComposition* sender, compositions::GuiItemEventArgs& arguments)
{
if (auto node = GetNodeItemView()->RequestNode(arguments.itemIndex))
{
GuiNodeEventArgs redirectArguments;
(GuiEventArgs&)redirectArguments = arguments;
redirectArguments.node = node.Obj();
nodeEvent.Execute(redirectArguments);
(GuiEventArgs&)arguments = redirectArguments;
}
}
#define ATTACH_ITEM_MOUSE_EVENT(NODEEVENTNAME, ITEMEVENTNAME)\
{\
ITEMEVENTNAME.AttachFunction([this](GuiGraphicsComposition* sender, GuiItemMouseEventArgs& args){ OnItemMouseEvent(NODEEVENTNAME, sender, args); });\
}\
#define ATTACH_ITEM_NOTIFY_EVENT(NODEEVENTNAME, ITEMEVENTNAME)\
{\
ITEMEVENTNAME.AttachFunction([this](GuiGraphicsComposition* sender, GuiItemEventArgs& args){ OnItemNotifyEvent(NODEEVENTNAME, sender, args); });\
}\
void GuiVirtualTreeListControl::OnNodeLeftButtonDoubleClick(compositions::GuiGraphicsComposition* sender, compositions::GuiNodeMouseEventArgs& arguments)
{
if (arguments.node->GetChildCount() > 0)
{
arguments.node->SetExpanding(!arguments.node->GetExpanding());
}
}
GuiVirtualTreeListControl::GuiVirtualTreeListControl(theme::ThemeName themeName, Ptr<tree::INodeRootProvider> _nodeRootProvider)
:GuiSelectableListControl(themeName, new tree::NodeItemProvider(_nodeRootProvider))
{
nodeItemProvider = dynamic_cast<tree::NodeItemProvider*>(GetItemProvider());
nodeItemView = dynamic_cast<tree::INodeItemView*>(GetItemProvider()->RequestView(WString::Unmanaged(tree::INodeItemView::Identifier)));
NodeLeftButtonDown.SetAssociatedComposition(boundsComposition);
NodeLeftButtonUp.SetAssociatedComposition(boundsComposition);
NodeLeftButtonDoubleClick.SetAssociatedComposition(boundsComposition);
NodeMiddleButtonDown.SetAssociatedComposition(boundsComposition);
NodeMiddleButtonUp.SetAssociatedComposition(boundsComposition);
NodeMiddleButtonDoubleClick.SetAssociatedComposition(boundsComposition);
NodeRightButtonDown.SetAssociatedComposition(boundsComposition);
NodeRightButtonUp.SetAssociatedComposition(boundsComposition);
NodeRightButtonDoubleClick.SetAssociatedComposition(boundsComposition);
NodeMouseMove.SetAssociatedComposition(boundsComposition);
NodeMouseEnter.SetAssociatedComposition(boundsComposition);
NodeMouseLeave.SetAssociatedComposition(boundsComposition);
NodeExpanded.SetAssociatedComposition(boundsComposition);
NodeCollapsed.SetAssociatedComposition(boundsComposition);
ATTACH_ITEM_MOUSE_EVENT(NodeLeftButtonDown, ItemLeftButtonDown);
ATTACH_ITEM_MOUSE_EVENT(NodeLeftButtonUp, ItemLeftButtonUp);
ATTACH_ITEM_MOUSE_EVENT(NodeLeftButtonDoubleClick, ItemLeftButtonDoubleClick);
ATTACH_ITEM_MOUSE_EVENT(NodeMiddleButtonDown, ItemMiddleButtonDown);
ATTACH_ITEM_MOUSE_EVENT(NodeMiddleButtonUp, ItemMiddleButtonUp);
ATTACH_ITEM_MOUSE_EVENT(NodeMiddleButtonDoubleClick, ItemMiddleButtonDoubleClick);
ATTACH_ITEM_MOUSE_EVENT(NodeRightButtonDown, ItemRightButtonDown);
ATTACH_ITEM_MOUSE_EVENT(NodeRightButtonUp, ItemRightButtonUp);
ATTACH_ITEM_MOUSE_EVENT(NodeRightButtonDoubleClick, ItemRightButtonDoubleClick);
ATTACH_ITEM_MOUSE_EVENT(NodeMouseMove, ItemMouseMove);
ATTACH_ITEM_NOTIFY_EVENT(NodeMouseEnter, ItemMouseEnter);
ATTACH_ITEM_NOTIFY_EVENT(NodeMouseLeave, ItemMouseLeave);
nodeItemProvider->GetRoot()->AttachCallback(this);
NodeLeftButtonDoubleClick.AttachMethod(this, &GuiVirtualTreeListControl::OnNodeLeftButtonDoubleClick);
}
#undef ATTACH_ITEM_MOUSE_EVENT
#undef ATTACH_ITEM_NOTIFY_EVENT
GuiVirtualTreeListControl::~GuiVirtualTreeListControl()
{
}
tree::INodeItemView* GuiVirtualTreeListControl::GetNodeItemView()
{
return nodeItemView;
}
tree::INodeRootProvider* GuiVirtualTreeListControl::GetNodeRootProvider()
{
return nodeItemProvider->GetRoot().Obj();
}
namespace tree
{
/***********************************************************************
TreeViewItem
***********************************************************************/
const wchar_t* const ITreeViewItemView::Identifier = L"vl::presentation::controls::tree::ITreeViewItemView";
TreeViewItem::TreeViewItem()
{
}
TreeViewItem::TreeViewItem(const Ptr<GuiImageData>& _image, const WString& _text)
:image(_image)
,text(_text)
{
}
/***********************************************************************
TreeViewItemRootProvider
***********************************************************************/
Ptr<GuiImageData> TreeViewItemRootProvider::GetNodeImage(INodeProvider* node)
{
MemoryNodeProvider* memoryNode=dynamic_cast<MemoryNodeProvider*>(node);
if(memoryNode)
{
Ptr<TreeViewItem> data=memoryNode->GetData().Cast<TreeViewItem>();
if(data)
{
return data->image;
}
}
return 0;
}
WString TreeViewItemRootProvider::GetTextValue(INodeProvider* node)
{
MemoryNodeProvider* memoryNode = dynamic_cast<MemoryNodeProvider*>(node);
if (memoryNode)
{
Ptr<TreeViewItem> data = memoryNode->GetData().Cast<TreeViewItem>();
if (data)
{
return data->text;
}
}
return L"";
}
description::Value TreeViewItemRootProvider::GetBindingValue(INodeProvider* node)
{
return Value::From(GetTreeViewData(node));
}
TreeViewItemRootProvider::TreeViewItemRootProvider()
{
}
TreeViewItemRootProvider::~TreeViewItemRootProvider()
{
}
IDescriptable* TreeViewItemRootProvider::RequestView(const WString& identifier)
{
if(identifier==ITreeViewItemView::Identifier)
{
return (ITreeViewItemView*)this;
}
else
{
return MemoryNodeRootProvider::RequestView(identifier);
}
}
Ptr<TreeViewItem> TreeViewItemRootProvider::GetTreeViewData(INodeProvider* node)
{
MemoryNodeProvider* memoryNode=GetMemoryNode(node);
if(memoryNode)
{
return memoryNode->GetData().Cast<TreeViewItem>();
}
else
{
return 0;
}
}
void TreeViewItemRootProvider::SetTreeViewData(INodeProvider* node, Ptr<TreeViewItem> value)
{
MemoryNodeProvider* memoryNode=GetMemoryNode(node);
if(memoryNode)
{
memoryNode->SetData(value);
}
}
void TreeViewItemRootProvider::UpdateTreeViewData(INodeProvider* node)
{
MemoryNodeProvider* memoryNode=GetMemoryNode(node);
if(memoryNode)
{
memoryNode->NotifyDataModified();
}
}
}
/***********************************************************************
GuiVirtualTreeView
***********************************************************************/
templates::GuiTreeItemTemplate* GuiVirtualTreeView::GetStyleFromNode(tree::INodeProvider* node)
{
if (itemArranger)
{
vint index = nodeItemView->CalculateNodeVisibilityIndex(node);
if (index != -1)
{
auto style = itemArranger->GetVisibleStyle(index);
return dynamic_cast<templates::GuiTreeItemTemplate*>(style);
}
}
return nullptr;
}
void GuiVirtualTreeView::SetStyleExpanding(tree::INodeProvider* node, bool expanding)
{
if (auto treeItemStyle = GetStyleFromNode(node))
{
treeItemStyle->SetExpanding(expanding);
}
}
void GuiVirtualTreeView::SetStyleExpandable(tree::INodeProvider* node, bool expandable)
{
if (auto treeItemStyle = GetStyleFromNode(node))
{
treeItemStyle->SetExpandable(expandable);
}
}
void GuiVirtualTreeView::OnAfterItemModified(tree::INodeProvider* parentNode, vint start, vint count, vint newCount, bool itemReferenceUpdated)
{
GuiVirtualTreeListControl::OnAfterItemModified(parentNode, start, count, newCount, itemReferenceUpdated);
SetStyleExpandable(parentNode, parentNode->GetChildCount() > 0);
}
void GuiVirtualTreeView::OnItemExpanded(tree::INodeProvider* node)
{
GuiVirtualTreeListControl::OnItemExpanded(node);
SetStyleExpanding(node, true);
}
void GuiVirtualTreeView::OnItemCollapsed(tree::INodeProvider* node)
{
GuiVirtualTreeListControl::OnItemCollapsed(node);
SetStyleExpanding(node, false);
}
void GuiVirtualTreeView::OnStyleInstalled(vint itemIndex, ItemStyle* style, bool refreshPropertiesOnly)
{
GuiVirtualTreeListControl::OnStyleInstalled(itemIndex, style, refreshPropertiesOnly);
if (auto textItemStyle = dynamic_cast<templates::GuiTextListItemTemplate*>(style))
{
textItemStyle->SetTextColor(TypedControlTemplateObject(true)->GetTextColor());
}
if (auto treeItemStyle = dynamic_cast<templates::GuiTreeItemTemplate*>(style))
{
treeItemStyle->SetTextColor(TypedControlTemplateObject(true)->GetTextColor());
if (treeViewItemView)
{
if (auto node = nodeItemView->RequestNode(itemIndex))
{
treeItemStyle->SetImage(treeViewItemView->GetNodeImage(node.Obj()));
treeItemStyle->SetExpanding(node->GetExpanding());
treeItemStyle->SetExpandable(node->GetChildCount() > 0);
{
vint level = -1;
auto current = node;
while (current->GetParent())
{
level++;
current = current->GetParent();
}
treeItemStyle->SetLevel(level);
}
}
}
}
if (refreshPropertiesOnly)
{
if (auto predefinedItemStyle = dynamic_cast<tree::DefaultTreeItemTemplate*>(style))
{
predefinedItemStyle->RefreshItem();
}
}
}
GuiVirtualTreeView::GuiVirtualTreeView(theme::ThemeName themeName, Ptr<tree::INodeRootProvider> _nodeRootProvider)
:GuiVirtualTreeListControl(themeName, _nodeRootProvider)
{
treeViewItemView = dynamic_cast<tree::ITreeViewItemView*>(GetNodeRootProvider()->RequestView(WString::Unmanaged(tree::ITreeViewItemView::Identifier)));
SetStyleAndArranger(
[](const Value&) { return new tree::DefaultTreeItemTemplate; },
Ptr(new list::FixedHeightItemArranger)
);
}
GuiVirtualTreeView::~GuiVirtualTreeView()
{
}
/***********************************************************************
GuiTreeView
***********************************************************************/
GuiTreeView::GuiTreeView(theme::ThemeName themeName)
:GuiVirtualTreeView(themeName, Ptr(new tree::TreeViewItemRootProvider))
{
nodes = nodeItemProvider->GetRoot().Cast<tree::TreeViewItemRootProvider>();
}
GuiTreeView::~GuiTreeView()
{
}
Ptr<tree::TreeViewItemRootProvider> GuiTreeView::Nodes()
{
return nodes;
}
Ptr<tree::TreeViewItem> GuiTreeView::GetSelectedItem()
{
Ptr<tree::TreeViewItem> result;
vint index = GetSelectedItemIndex();
if (index != -1)
{
if (auto node = nodeItemView->RequestNode(index))
{
if (auto memoryNode = node.Cast<tree::MemoryNodeProvider>())
{
result = memoryNode->GetData().Cast<tree::TreeViewItem>();
}
}
}
return result;
}
namespace tree
{
/***********************************************************************
DefaultTreeItemTemplate
***********************************************************************/
void DefaultTreeItemTemplate::OnInitialize()
{
SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
table = new GuiTableComposition;
AddChild(table);
table->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
table->SetRowsAndColumns(3, 4);
table->SetRowOption(0, GuiCellOption::PercentageOption(0.5));
table->SetRowOption(1, GuiCellOption::MinSizeOption());
table->SetRowOption(2, GuiCellOption::PercentageOption(0.5));
table->SetColumnOption(0, GuiCellOption::AbsoluteOption(0));
table->SetColumnOption(1, GuiCellOption::MinSizeOption());
table->SetColumnOption(2, GuiCellOption::MinSizeOption());
table->SetColumnOption(3, GuiCellOption::MinSizeOption());
table->SetAlignmentToParent(Margin(0, 0, 0, 0));
table->SetCellPadding(2);
{
GuiCellComposition* cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(0, 1, 3, 1);
cell->SetPreferredMinSize(Size(16, 16));
expandingButton = new GuiSelectableButton(theme::ThemeName::TreeItemExpander);
if (auto treeView = dynamic_cast<GuiVirtualTreeView*>(listControl))
{
if (auto expanderStyle = treeView->TypedControlTemplateObject(true)->GetExpandingDecoratorTemplate())
{
expandingButton->SetControlTemplate(expanderStyle);
}
}
expandingButton->SetAutoFocus(false);
expandingButton->SetAutoSelection(false);
expandingButton->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
expandingButton->GetBoundsComposition()->GetEventReceiver()->leftButtonDoubleClick.AttachMethod(this, &DefaultTreeItemTemplate::OnExpandingButtonDoubleClick);
expandingButton->Clicked.AttachMethod(this, &DefaultTreeItemTemplate::OnExpandingButtonClicked);
cell->AddChild(expandingButton->GetBoundsComposition());
}
{
GuiCellComposition* cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(1, 2, 1, 1);
cell->SetPreferredMinSize(Size(16, 16));
imageElement = GuiImageFrameElement::Create();
imageElement->SetStretch(true);
cell->SetOwnedElement(Ptr(imageElement));
}
{
GuiCellComposition* cell = new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(0, 3, 3, 1);
cell->SetPreferredMinSize(Size(192, 0));
textElement = GuiSolidLabelElement::Create();
textElement->SetAlignments(Alignment::Left, Alignment::Center);
textElement->SetEllipse(true);
cell->SetOwnedElement(Ptr(textElement));
}
FontChanged.AttachMethod(this, &DefaultTreeItemTemplate::OnFontChanged);
TextChanged.AttachMethod(this, &DefaultTreeItemTemplate::OnTextChanged);
TextColorChanged.AttachMethod(this, &DefaultTreeItemTemplate::OnTextColorChanged);
ExpandingChanged.AttachMethod(this, &DefaultTreeItemTemplate::OnExpandingChanged);
ExpandableChanged.AttachMethod(this, &DefaultTreeItemTemplate::OnExpandableChanged);
LevelChanged.AttachMethod(this, &DefaultTreeItemTemplate::OnLevelChanged);
ImageChanged.AttachMethod(this, &DefaultTreeItemTemplate::OnImageChanged);
FontChanged.Execute(compositions::GuiEventArgs(this));
TextChanged.Execute(compositions::GuiEventArgs(this));
TextColorChanged.Execute(compositions::GuiEventArgs(this));
ExpandingChanged.Execute(compositions::GuiEventArgs(this));
ExpandableChanged.Execute(compositions::GuiEventArgs(this));
LevelChanged.Execute(compositions::GuiEventArgs(this));
ImageChanged.Execute(compositions::GuiEventArgs(this));
}
void DefaultTreeItemTemplate::OnRefresh()
{
}
void DefaultTreeItemTemplate::OnFontChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
textElement->SetFont(GetFont());
}
void DefaultTreeItemTemplate::OnTextChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
textElement->SetText(GetText());
}
void DefaultTreeItemTemplate::OnTextColorChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
textElement->SetColor(GetTextColor());
}
void DefaultTreeItemTemplate::OnExpandingChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
expandingButton->SetSelected(GetExpanding());
}
void DefaultTreeItemTemplate::OnExpandableChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
expandingButton->SetVisible(GetExpandable());
}
void DefaultTreeItemTemplate::OnLevelChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
table->SetColumnOption(0, GuiCellOption::AbsoluteOption(GetLevel() * 12));
}
void DefaultTreeItemTemplate::OnImageChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (auto imageData = GetImage())
{
imageElement->SetImage(imageData->GetImage(), imageData->GetFrameIndex());
}
else
{
imageElement->SetImage(nullptr);
}
}
void DefaultTreeItemTemplate::OnExpandingButtonDoubleClick(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
arguments.handled = true;
}
void DefaultTreeItemTemplate::OnExpandingButtonClicked(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (expandingButton->GetVisuallyEnabled())
{
if (auto treeControl = dynamic_cast<GuiVirtualTreeListControl*>(listControl))
{
if (auto view = treeControl->GetNodeItemView())
{
vint index = treeControl->GetArranger()->GetVisibleIndex(this);
if (index != -1)
{
if (auto node = view->RequestNode(index))
{
bool expanding = node->GetExpanding();
node->SetExpanding(!expanding);
}
}
}
}
}
}
DefaultTreeItemTemplate::DefaultTreeItemTemplate()
{
}
DefaultTreeItemTemplate::~DefaultTreeItemTemplate()
{
}
}
}
}
}
/***********************************************************************
.\CONTROLS\TEMPLATES\GUIANIMATION.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace collections;
using namespace reflection::description;
/***********************************************************************
GuiTimedAnimation
***********************************************************************/
class GuiTimedAnimation : public Object, public virtual IGuiAnimation
{
protected:
DateTime startUtcTime;
vuint64_t time;
bool running = false;
public:
GuiTimedAnimation()
{
}
~GuiTimedAnimation()
{
}
void Start()override
{
startUtcTime = DateTime::UtcTime();
time = 0;
running = true;
}
void Pause()override
{
time = GetTime();
running = false;
}
void Resume()override
{
startUtcTime = DateTime::UtcTime();
running = true;
}
vuint64_t GetTime()
{
if (running)
{
return time + (DateTime::UtcTime().osMilliseconds - startUtcTime.osMilliseconds);
}
else
{
return time;
}
}
};
/***********************************************************************
GuiFiniteAnimation
***********************************************************************/
class GuiFiniteAnimation : public GuiTimedAnimation
{
protected:
vuint64_t length = 0;
vuint64_t currentTime = 0;
Func<void(vuint64_t)> run;
public:
GuiFiniteAnimation(const Func<void(vuint64_t)>& _run, vuint64_t _length)
:run(_run)
, length(_length)
{
}
~GuiFiniteAnimation()
{
}
void Run()override
{
currentTime = GetTime();
if (currentTime < length && run)
{
run(currentTime);
}
}
bool GetStopped()override
{
return currentTime >= length;
}
};
/***********************************************************************
GuiInfiniteAnimation
***********************************************************************/
class GuiInfiniteAnimation : public GuiTimedAnimation
{
protected:
Func<void(vuint64_t)> run;
public:
GuiInfiniteAnimation(const Func<void(vuint64_t)>& _run)
:run(_run)
{
}
~GuiInfiniteAnimation()
{
}
void Run()override
{
if (run)
{
run(GetTime());
}
}
bool GetStopped()override
{
return false;
}
};
/***********************************************************************
IGuiAnimation
***********************************************************************/
Ptr<IGuiAnimation> IGuiAnimation::CreateAnimation(const Func<void(vuint64_t)>& run, vuint64_t milliseconds)
{
return Ptr(new GuiFiniteAnimation(run, milliseconds));
}
Ptr<IGuiAnimation> IGuiAnimation::CreateAnimation(const Func<void(vuint64_t)>& run)
{
return Ptr(new GuiInfiniteAnimation(run));
}
/***********************************************************************
IGuiAnimationCoroutine
***********************************************************************/
class GuiCoroutineAnimation : public Object, public virtual IGuiAnimationCoroutine::IImpl
{
protected:
IGuiAnimationCoroutine::Creator creator;
Ptr<ICoroutine> coroutine;
Ptr<IGuiAnimation> waitingAnimation;
vint waitingGroup = -1;
Group<vint, Ptr<IGuiAnimation>> groupAnimations;
public:
GuiCoroutineAnimation(const IGuiAnimationCoroutine::Creator& _creator)
:creator(_creator)
{
}
~GuiCoroutineAnimation()
{
}
void OnPlayAndWait(Ptr<IGuiAnimation> animation)override
{
CHECK_ERROR(!waitingAnimation && waitingGroup == -1, L"GuiCoroutineAnimation::OnPlayAndWait(Ptr<IGuiAnimation>)#Cannot be called when an animation or a group has already been waiting for.");
waitingAnimation = animation;
waitingAnimation->Start();
}
void OnPlayInGroup(Ptr<IGuiAnimation> animation, vint groupId)override
{
groupAnimations.Add(groupId, animation);
animation->Start();
}
void OnWaitForGroup(vint groupId)override
{
CHECK_ERROR(!waitingAnimation && waitingGroup == -1, L"GuiCoroutineAnimation::OnWaitForGroup(vint)#Cannot be called when an animation or a group has already been waiting for.");
if (groupAnimations.Keys().Contains(groupId))
{
waitingGroup = groupId;
}
}
void Start()override
{
CHECK_ERROR(!coroutine, L"GuiCoroutineAnimation::Start()#Cannot be called more than once.");
coroutine = creator(this);
}
void Pause()override
{
if (waitingAnimation)
{
waitingAnimation->Pause();
}
// TODO: (enumerable) foreach on group
for (vint i = 0; i < groupAnimations.Count(); i++)
{
for (auto animation : groupAnimations.GetByIndex(i))
{
animation->Pause();
}
}
}
void Resume()override
{
if (waitingAnimation)
{
waitingAnimation->Resume();
}
// TODO: (enumerable) foreach on group
for (vint i = 0; i < groupAnimations.Count(); i++)
{
for (auto animation : groupAnimations.GetByIndex(i))
{
animation->Resume();
}
}
}
void Run()override
{
CHECK_ERROR(coroutine, L"GuiCoroutineAnimation::Run()#Cannot be called before calling Start.");
if (waitingAnimation)
{
waitingAnimation->Run();
if (waitingAnimation->GetStopped())
{
waitingAnimation = nullptr;
}
}
// TODO: (enumerable) foreach:reversed on group
for (vint i = groupAnimations.Count() - 1; i >= 0; i--)
{
auto& animations = groupAnimations.GetByIndex(i);
for (vint j = animations.Count() - 1; j >= 0; j--)
{
auto animation = animations[j];
animation->Run();
if (animation->GetStopped())
{
groupAnimations.Remove(i, animation.Obj());
}
}
}
if (waitingGroup != -1 && !groupAnimations.Keys().Contains(waitingGroup))
{
waitingGroup = -1;
}
if (coroutine->GetStatus() == CoroutineStatus::Waiting)
{
if (waitingAnimation || waitingGroup != -1)
{
return;
}
coroutine->Resume(true, nullptr);
}
}
bool GetStopped()override
{
if (!coroutine) return false;
if (coroutine->GetStatus() != CoroutineStatus::Stopped) return false;
if (waitingAnimation || groupAnimations.Count() > 0) return false;
return true;
}
};
void IGuiAnimationCoroutine::WaitAndPause(IImpl* impl, vuint64_t milliseconds)
{
return PlayAndWaitAndPause(impl, IGuiAnimation::CreateAnimation({}, milliseconds));
}
void IGuiAnimationCoroutine::PlayAndWaitAndPause(IImpl* impl, Ptr<IGuiAnimation> animation)
{
impl->OnPlayAndWait(animation);
}
void IGuiAnimationCoroutine::PlayInGroupAndPause(IImpl* impl, Ptr<IGuiAnimation> animation, vint groupId)
{
impl->OnPlayInGroup(animation, groupId);
}
void IGuiAnimationCoroutine::WaitForGroupAndPause(IImpl* impl, vint groupId)
{
impl->OnWaitForGroup(groupId);
}
void IGuiAnimationCoroutine::ReturnAndExit(IImpl* impl)
{
}
Ptr<IGuiAnimation> IGuiAnimationCoroutine::Create(const Creator& creator)
{
return Ptr(new GuiCoroutineAnimation(creator));
}
}
}
}
/***********************************************************************
.\CONTROLS\TEMPLATES\GUICOMMONTEMPLATES.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace templates
{
using namespace elements;
using namespace compositions;
using namespace templates;
using namespace controls;
using namespace theme;
/***********************************************************************
GuiCommonDatePickerLook
***********************************************************************/
vint GetDayCountForMonth(vint year, vint month)
{
bool isLeapYear = (year % 100 == 0) ? (year % 400 == 0) : (year % 4 == 0);
switch (month)
{
case 1:case 3:case 5:case 7:case 8:case 10:case 12:
return 31;
case 4:case 6:case 9:case 11:
return 30;
default:
return isLeapYear ? 29 : 28;
}
}
void StepPreviousMonth(vint& year, vint& month)
{
if (month == 1)
{
year--;
month = 12;
}
else
{
month--;
}
}
void StepNextMonth(vint& year, vint& month)
{
if (month == 12)
{
year++;
month = 1;
}
else
{
month++;
}
}
void GuiCommonDatePickerLook::SetDay(const DateTime& day, vint& index, vint monthOffset)
{
dateDays[index] = day;
GuiSolidLabelElement* label = labelDays[index];
label->SetText(itow(day.day));
label->SetColor(monthOffset == 0 ? primaryTextColor : secondaryTextColor);
wchar_t alt[] = L"D00";
if (monthOffset == -1) alt[0] = L'C';
else if (monthOffset == 1) alt[0] = L'E';
alt[1] = (wchar_t)(L'0' + day.day / 10);
alt[2] = (wchar_t)(L'0' + day.day % 10);
buttonDays[index]->SetAlt(alt);
index++;
}
void GuiCommonDatePickerLook::comboYearMonth_SelectedIndexChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (!preventComboEvent)
{
if (comboYear->GetSelectedIndex() != -1 && comboMonth->GetSelectedIndex() != -1)
{
vint year = comboYear->GetSelectedIndex() + YearFirst;
vint month = comboMonth->GetSelectedIndex() + 1;
SetDate(DateTime::FromDateTime(year, month, 1));
GuiEventArgs arguments(this);
DateChanged.Execute(arguments);
commands->NotifyDateChanged();
commands->NotifyDateNavigated();
}
}
}
void GuiCommonDatePickerLook::buttonDay_SelectedChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (!preventButtonEvent)
{
GuiSelectableButton* button = dynamic_cast<GuiSelectableButton*>(sender->GetRelatedControl());
if (button->GetSelected())
{
vint index = buttonDays.IndexOf(button);
if (index != -1)
{
DateTime day = dateDays[index];
if (day.year != currentDate.year || day.month != currentDate.month)
{
SetDate(day);
}
else
{
currentDate = day;
}
GuiEventArgs arguments(this);
DateChanged.Execute(arguments);
commands->NotifyDateChanged();
commands->NotifyDateSelected();
}
}
}
}
void GuiCommonDatePickerLook::DisplayMonth(vint year, vint month)
{
if (YearFirst <= year && year <= YearLast && 1 <= month && month <= 12)
{
preventComboEvent = true;
comboYear->SetSelectedIndex(year - YearFirst);
comboMonth->SetSelectedIndex(month - 1);
preventComboEvent = false;
}
vint yearPrev = year, yearNext = year, monthPrev = month, monthNext = month;
StepPreviousMonth(yearPrev, monthPrev);
StepNextMonth(yearNext, monthNext);
vint countPrev = GetDayCountForMonth(yearPrev, monthPrev);
vint count = GetDayCountForMonth(year, month);
vint countNext = GetDayCountForMonth(yearNext, monthNext);
DateTime firstDay = DateTime::FromDateTime(year, month, 1);
vint showPrev = firstDay.dayOfWeek;
if (showPrev == 0) showPrev = DaysOfWeek;
vint show = count;
vint showNext = DaysOfWeek*DayRows - showPrev - show;
vint index = 0;
for (vint i = 0; i < showPrev; i++)
{
DateTime day = DateTime::FromDateTime(yearPrev, monthPrev, countPrev - (showPrev - i - 1));
SetDay(day, index, -1);
}
for (vint i = 0; i < show; i++)
{
DateTime day = DateTime::FromDateTime(year, month, i + 1);
SetDay(day, index, 0);
}
for (vint i = 0; i < showNext; i++)
{
DateTime day = DateTime::FromDateTime(yearNext, monthNext, i + 1);
SetDay(day, index, 1);
}
}
void GuiCommonDatePickerLook::SelectDay(vint day)
{
// TODO: (enumerable) foreach:indexed
for (vint i = 0; i < dateDays.Count(); i++)
{
const DateTime& dt = dateDays[i];
if (dt.year == currentDate.year && dt.month == currentDate.month && dt.day == day)
{
preventButtonEvent = true;
buttonDays[i]->SetSelected(true);
preventButtonEvent = false;
break;
}
}
}
GuiCommonDatePickerLook::GuiCommonDatePickerLook(Color _backgroundColor, Color _primaryTextColor, Color _secondaryTextColor)
:backgroundColor(_backgroundColor)
, primaryTextColor(_primaryTextColor)
, secondaryTextColor(_secondaryTextColor)
{
DateChanged.SetAssociatedComposition(this);
SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
GuiTableComposition* monthTable = 0;
GuiTableComposition* dayTable = 0;
{
listYears = new GuiTextList(theme::ThemeName::TextList);
listYears->SetHorizontalAlwaysVisible(false);
for (vint i = YearFirst; i <= YearLast; i++)
{
listYears->GetItems().Add(Ptr(new list::TextItem(itow(i))));
}
comboYear = new GuiComboBoxListControl(theme::ThemeName::ComboBox, listYears);
comboYear->SetAlt(L"Y");
comboYear->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 2, 0));
comboYear->SelectedIndexChanged.AttachMethod(this, &GuiCommonDatePickerLook::comboYearMonth_SelectedIndexChanged);
}
{
listMonths = new GuiTextList(theme::ThemeName::TextList);
listMonths->SetHorizontalAlwaysVisible(false);
comboMonth = new GuiComboBoxListControl(theme::ThemeName::ComboBox, listMonths);
comboMonth->SetAlt(L"M");
comboMonth->GetBoundsComposition()->SetAlignmentToParent(Margin(2, 0, 0, 0));
comboMonth->SelectedIndexChanged.AttachMethod(this, &GuiCommonDatePickerLook::comboYearMonth_SelectedIndexChanged);
}
{
monthTable = new GuiTableComposition;
monthTable->SetAlignmentToParent(Margin(0, 0, 0, 0));
monthTable->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
monthTable->SetRowsAndColumns(1, 2);
monthTable->SetRowOption(0, GuiCellOption::MinSizeOption());
monthTable->SetColumnOption(0, GuiCellOption::PercentageOption(0.5));
monthTable->SetColumnOption(1, GuiCellOption::PercentageOption(0.5));
{
GuiCellComposition* cell = new GuiCellComposition;
monthTable->AddChild(cell);
cell->SetSite(0, 0, 1, 1);
cell->AddChild(comboYear->GetBoundsComposition());
}
{
GuiCellComposition* cell = new GuiCellComposition;
monthTable->AddChild(cell);
cell->SetSite(0, 1, 1, 1);
cell->AddChild(comboMonth->GetBoundsComposition());
}
}
{
dayTable = new GuiTableComposition;
dayTable->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
dayTable->SetCellPadding(4);
dayTable->SetRowsAndColumns(DayRows + DayRowStart, DaysOfWeek);
for (vint i = 0; i < DayRowStart; i++)
{
dayTable->SetRowOption(i, GuiCellOption::MinSizeOption());
}
for (vint i = 0; i < DayRows; i++)
{
dayTable->SetRowOption(i + DayRowStart, GuiCellOption::PercentageOption(1.0));
}
for (vint i = 0; i < DaysOfWeek; i++)
{
dayTable->SetColumnOption(i, GuiCellOption::PercentageOption(1.0));
}
{
GuiCellComposition* cell = new GuiCellComposition;
dayTable->AddChild(cell);
cell->SetSite(0, 0, 1, DaysOfWeek);
cell->AddChild(monthTable);
}
labelDaysOfWeek.Resize(7);
for (vint i = 0; i < DaysOfWeek; i++)
{
GuiCellComposition* cell = new GuiCellComposition;
dayTable->AddChild(cell);
cell->SetSite(1, i, 1, 1);
auto element = Ptr(GuiSolidLabelElement::Create());
element->SetAlignments(Alignment::Center, Alignment::Center);
element->SetColor(primaryTextColor);
labelDaysOfWeek[i] = element.Obj();
cell->SetOwnedElement(element);
}
buttonDays.Resize(DaysOfWeek*DayRows);
labelDays.Resize(DaysOfWeek*DayRows);
dateDays.Resize(DaysOfWeek*DayRows);
auto dayMutexController = new GuiSelectableButton::MutexGroupController;
AddComponent(dayMutexController);
for (vint i = 0; i < DaysOfWeek; i++)
{
for (vint j = 0; j < DayRows; j++)
{
GuiCellComposition* cell = new GuiCellComposition;
dayTable->AddChild(cell);
cell->SetSite(j + DayRowStart, i, 1, 1);
GuiSelectableButton* button = new GuiSelectableButton(theme::ThemeName::CheckBox);
button->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
button->SetGroupController(dayMutexController);
button->SelectedChanged.AttachMethod(this, &GuiCommonDatePickerLook::buttonDay_SelectedChanged);
cell->AddChild(button->GetBoundsComposition());
buttonDays[j*DaysOfWeek + i] = button;
auto element = Ptr(GuiSolidLabelElement::Create());
element->SetAlignments(Alignment::Center, Alignment::Center);
element->SetText(L"0");
labelDays[j*DaysOfWeek + i] = element.Obj();
GuiBoundsComposition* elementBounds = new GuiBoundsComposition;
elementBounds->SetOwnedElement(element);
elementBounds->SetAlignmentToParent(Margin(0, 0, 0, 0));
elementBounds->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElement);
button->GetContainerComposition()->AddChild(elementBounds);
}
}
}
{
auto element = Ptr(GuiSolidBackgroundElement::Create());
element->SetColor(backgroundColor);
dayTable->SetOwnedElement(element);
}
dayTable->SetAlignmentToParent(Margin(0, 0, 0, 0));
AddChild(dayTable);
SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
SetFont(font);
}
GuiCommonDatePickerLook::~GuiCommonDatePickerLook()
{
FinalizeInstanceRecursively(this);
}
controls::IDatePickerCommandExecutor* GuiCommonDatePickerLook::GetCommands()
{
return commands;
}
void GuiCommonDatePickerLook::SetCommands(controls::IDatePickerCommandExecutor* value)
{
commands = value;
}
TemplateProperty<GuiSelectableButtonTemplate> GuiCommonDatePickerLook::GetDateButtonTemplate()
{
return dateButtonTemplate;
}
void GuiCommonDatePickerLook::SetDateButtonTemplate(const TemplateProperty<GuiSelectableButtonTemplate>& value)
{
dateButtonTemplate = value;
for (auto button : buttonDays)
{
button->SetControlTemplate(value);
}
}
TemplateProperty<GuiTextListTemplate> GuiCommonDatePickerLook::GetDateTextListTemplate()
{
return dateTextListTemplate;
}
void GuiCommonDatePickerLook::SetDateTextListTemplate(const TemplateProperty<GuiTextListTemplate>& value)
{
dateTextListTemplate = value;
listYears->SetControlTemplate(value);
listMonths->SetControlTemplate(value);
}
TemplateProperty<GuiComboBoxTemplate> GuiCommonDatePickerLook::GetDateComboBoxTemplate()
{
return dateComboBoxTemplate;
}
void GuiCommonDatePickerLook::SetDateComboBoxTemplate(const TemplateProperty<GuiComboBoxTemplate>& value)
{
dateComboBoxTemplate = value;
comboYear->SetControlTemplate(value);
comboMonth->SetControlTemplate(value);
}
const Locale& GuiCommonDatePickerLook::GetDateLocale()
{
return dateLocale;
}
void GuiCommonDatePickerLook::SetDateLocale(const Locale& value)
{
if (dateLocale != value)
{
dateLocale = value;
for (vint i = 0; i < DaysOfWeek; i++)
{
labelDaysOfWeek[i]->SetText(dateLocale.GetShortDayOfWeekName(i));
}
listMonths->GetItems().Clear();
for (vint i = 1; i <= 12; i++)
{
listMonths->GetItems().Add(Ptr(new list::TextItem(dateLocale.GetLongMonthName(i))));
}
SetDate(currentDate);
}
}
const DateTime& GuiCommonDatePickerLook::GetDate()
{
return currentDate;
}
void GuiCommonDatePickerLook::SetDate(const DateTime& value)
{
currentDate = value;
DisplayMonth(value.year, value.month);
SelectDay(value.day);
}
const FontProperties& GuiCommonDatePickerLook::GetFont()
{
return font;
}
void GuiCommonDatePickerLook::SetFont(const FontProperties& value)
{
if (font != value)
{
font = value;
comboYear->SetFont(value);
listYears->SetFont(value);
comboMonth->SetFont(value);
listMonths->SetFont(value);
for (auto label : From(labelDaysOfWeek).Concat(labelDays))
{
label->SetFont(value);
}
}
}
controls::GuiComboBoxListControl* GuiCommonDatePickerLook::GetYearCombo()
{
return comboYear;
}
controls::GuiComboBoxListControl* GuiCommonDatePickerLook::GetMonthCombo()
{
return comboMonth;
}
vint GuiCommonDatePickerLook::GetDayRows()
{
return DaysOfWeek;
}
vint GuiCommonDatePickerLook::GetDayColumns()
{
return DayRows;
}
controls::GuiSelectableButton* GuiCommonDatePickerLook::GetDayButton(vint row, vint column)
{
return buttonDays[row * DaysOfWeek + column];
}
DateTime GuiCommonDatePickerLook::GetDateOfDayButton(vint row, vint column)
{
return dateDays[row * DaysOfWeek + column];
}
/***********************************************************************
GuiCommonScrollViewLook
***********************************************************************/
void GuiCommonScrollViewLook::UpdateTable()
{
if (horizontalScroll->GetVisible())
{
tableComposition->SetRowOption(1, GuiCellOption::AbsoluteOption(defaultScrollSize));
}
else
{
tableComposition->SetRowOption(1, GuiCellOption::AbsoluteOption(0));
}
if (verticalScroll->GetVisible())
{
tableComposition->SetColumnOption(1, GuiCellOption::AbsoluteOption(defaultScrollSize));
}
else
{
tableComposition->SetColumnOption(1, GuiCellOption::AbsoluteOption(0));
}
}
void GuiCommonScrollViewLook::hScroll_OnVisibleChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
UpdateTable();
}
void GuiCommonScrollViewLook::vScroll_OnVisibleChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
UpdateTable();
}
GuiCommonScrollViewLook::GuiCommonScrollViewLook(vint _defaultScrollSize)
:defaultScrollSize(_defaultScrollSize)
{
SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
horizontalScroll = new GuiScroll(theme::ThemeName::HScroll);
horizontalScroll->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
horizontalScroll->SetEnabled(false);
horizontalScroll->SetAutoFocus(false);
verticalScroll = new GuiScroll(theme::ThemeName::VScroll);
verticalScroll->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
verticalScroll->SetEnabled(false);
verticalScroll->SetAutoFocus(false);
tableComposition = new GuiTableComposition;
AddChild(tableComposition);
tableComposition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
tableComposition->SetAlignmentToParent(Margin(0, 0, 0, 0));
tableComposition->SetRowsAndColumns(2, 2);
tableComposition->SetRowOption(0, GuiCellOption::PercentageOption(1.0));
tableComposition->SetRowOption(1, GuiCellOption::MinSizeOption());
tableComposition->SetColumnOption(0, GuiCellOption::PercentageOption(1.0));
tableComposition->SetColumnOption(1, GuiCellOption::MinSizeOption());
UpdateTable();
{
GuiCellComposition* cell = new GuiCellComposition;
tableComposition->AddChild(cell);
cell->SetSite(1, 0, 1, 1);
cell->AddChild(horizontalScroll->GetBoundsComposition());
}
{
GuiCellComposition* cell = new GuiCellComposition;
tableComposition->AddChild(cell);
cell->SetSite(0, 1, 1, 1);
cell->AddChild(verticalScroll->GetBoundsComposition());
}
containerCellComposition = new GuiCellComposition;
tableComposition->AddChild(containerCellComposition);
containerCellComposition->SetSite(0, 0, 1, 1);
containerComposition = new GuiBoundsComposition;
containerComposition->SetAlignmentToParent(Margin(0, 0, 0, 0));
containerCellComposition->AddChild(containerComposition);
horizontalScroll->VisibleChanged.AttachMethod(this, &GuiCommonScrollViewLook::hScroll_OnVisibleChanged);
verticalScroll->VisibleChanged.AttachMethod(this, &GuiCommonScrollViewLook::vScroll_OnVisibleChanged);
UpdateTable();
}
GuiCommonScrollViewLook::~GuiCommonScrollViewLook()
{
}
controls::GuiScroll* GuiCommonScrollViewLook::GetHScroll()
{
return horizontalScroll;
}
controls::GuiScroll* GuiCommonScrollViewLook::GetVScroll()
{
return verticalScroll;
}
compositions::GuiGraphicsComposition* GuiCommonScrollViewLook::GetContainerComposition()
{
return containerComposition;
}
TemplateProperty<GuiScrollTemplate> GuiCommonScrollViewLook::GetHScrollTemplate()
{
return hScrollTemplate;
}
void GuiCommonScrollViewLook::SetHScrollTemplate(const TemplateProperty<GuiScrollTemplate>& value)
{
hScrollTemplate = value;
horizontalScroll->SetControlTemplate(value);
}
TemplateProperty<GuiScrollTemplate> GuiCommonScrollViewLook::GetVScrollTemplate()
{
return vScrollTemplate;
}
void GuiCommonScrollViewLook::SetVScrollTemplate(const TemplateProperty<GuiScrollTemplate>& value)
{
vScrollTemplate = value;
verticalScroll->SetControlTemplate(value);
}
/***********************************************************************
GuiCommonScrollBehavior
***********************************************************************/
void GuiCommonScrollBehavior::SetScroll(vint totalPixels, vint newOffset)
{
vint totalSize = scrollTemplate->GetTotalSize();
double ratio = (double)newOffset / totalPixels;
vint newPosition = (vint)round(ratio * totalSize);
vint offset1 = (vint)round(((double)newPosition / totalSize) * totalPixels);
vint offset2 = (vint)round(((double)(newPosition + 1)) / totalSize * totalPixels);
vint delta1 = offset1 - newOffset;
vint delta2 = offset2 - newOffset;
if (delta1 < 0) { delta1 = -delta1; }
if (delta2 < 0) { delta2 = -delta2; }
if (delta1 < delta2)
{
scrollTemplate->GetCommands()->SetPosition(newPosition);
}
else
{
scrollTemplate->GetCommands()->SetPosition(newPosition + 1);
}
}
void GuiCommonScrollBehavior::AttachHandle(compositions::GuiGraphicsComposition* handle)
{
handle->GetEventReceiver()->leftButtonDown.AttachLambda([=](GuiGraphicsComposition*, GuiMouseEventArgs& arguments)
{
if (scrollTemplate->GetVisuallyEnabled())
{
dragging = true;
location.x = arguments.x;
location.y = arguments.y;
}
});
handle->GetEventReceiver()->leftButtonUp.AttachLambda([=](GuiGraphicsComposition*, GuiMouseEventArgs&)
{
if (scrollTemplate->GetVisuallyEnabled())
{
dragging = false;
}
});
}
GuiCommonScrollBehavior::GuiCommonScrollBehavior()
{
}
GuiCommonScrollBehavior::~GuiCommonScrollBehavior()
{
}
void GuiCommonScrollBehavior::AttachScrollTemplate(GuiScrollTemplate* value)
{
scrollTemplate = value;
}
void GuiCommonScrollBehavior::AttachDecreaseButton(controls::GuiButton* button)
{
button->Clicked.AttachLambda([=](GuiGraphicsComposition*, GuiEventArgs&)
{
scrollTemplate->GetCommands()->SmallDecrease();
});
}
void GuiCommonScrollBehavior::AttachIncreaseButton(controls::GuiButton* button)
{
button->Clicked.AttachLambda([=](GuiGraphicsComposition*, GuiEventArgs&)
{
scrollTemplate->GetCommands()->SmallIncrease();
});
}
void GuiCommonScrollBehavior::AttachHorizontalScrollHandle(compositions::GuiPartialViewComposition* partialView)
{
partialView->GetParent()->GetEventReceiver()->leftButtonDown.AttachLambda([=](GuiGraphicsComposition*, GuiMouseEventArgs& arguments)
{
if (scrollTemplate->GetVisuallyEnabled())
{
if (arguments.x < partialView->GetCachedBounds().x1)
{
scrollTemplate->GetCommands()->BigDecrease();
}
else if (arguments.x >= partialView->GetCachedBounds().x2)
{
scrollTemplate->GetCommands()->BigIncrease();
}
}
});
AttachHorizontalTrackerHandle(partialView);
}
void GuiCommonScrollBehavior::AttachVerticalScrollHandle(compositions::GuiPartialViewComposition* partialView)
{
partialView->GetParent()->GetEventReceiver()->leftButtonDown.AttachLambda([=](GuiGraphicsComposition*, GuiMouseEventArgs& arguments)
{
if (scrollTemplate->GetVisuallyEnabled())
{
if (arguments.y < partialView->GetCachedBounds().y1)
{
scrollTemplate->GetCommands()->BigDecrease();
}
else if (arguments.y >= partialView->GetCachedBounds().y2)
{
scrollTemplate->GetCommands()->BigIncrease();
}
}
});
AttachVerticalTrackerHandle(partialView);
}
void GuiCommonScrollBehavior::AttachHorizontalTrackerHandle(compositions::GuiPartialViewComposition* partialView)
{
partialView->GetEventReceiver()->mouseMove.AttachLambda([=](GuiGraphicsComposition*, GuiMouseEventArgs& arguments)
{
if (dragging)
{
auto bounds = partialView->GetParent()->GetCachedBounds();
vint totalPixels = bounds.x2 - bounds.x1;
vint currentOffset = partialView->GetCachedBounds().x1;
vint newOffset = currentOffset + (arguments.x - location.x);
SetScroll(totalPixels, newOffset);
}
});
AttachHandle(partialView);
}
void GuiCommonScrollBehavior::AttachVerticalTrackerHandle(compositions::GuiPartialViewComposition* partialView)
{
partialView->GetEventReceiver()->mouseMove.AttachLambda([=](GuiGraphicsComposition*, GuiMouseEventArgs& arguments)
{
if (dragging)
{
auto bounds = partialView->GetParent()->GetCachedBounds();
vint totalPixels = bounds.y2 - bounds.y1;
vint currentOffset = partialView->GetCachedBounds().y1;
vint newOffset = currentOffset + (arguments.y - location.y);
SetScroll(totalPixels, newOffset);
}
});
AttachHandle(partialView);
}
vint GuiCommonScrollBehavior::GetHorizontalTrackerHandlerPosition(compositions::GuiBoundsComposition* handle, vint totalSize, vint pageSize, vint position)
{
vint width = handle->GetParent()->GetCachedBounds().Width() - handle->GetCachedBounds().Width();
vint max = totalSize - pageSize;
return max == 0 ? 0 : width * position / max;
}
vint GuiCommonScrollBehavior::GetVerticalTrackerHandlerPosition(compositions::GuiBoundsComposition* handle, vint totalSize, vint pageSize, vint position)
{
vint height = handle->GetParent()->GetCachedBounds().Height() - handle->GetCachedBounds().Height();
vint max = totalSize - pageSize;
return max == 0 ? 0 : height * position / max;
}
}
}
}
/***********************************************************************
.\CONTROLS\TEMPLATES\GUICONTROLTEMPLATES.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace templates
{
using namespace collections;
using namespace controls;
using namespace compositions;
using namespace elements;
/***********************************************************************
Template Declarations
***********************************************************************/
GUI_CONTROL_TEMPLATE_DECL(GUI_TEMPLATE_CLASS_IMPL)
GUI_ITEM_TEMPLATE_DECL(GUI_TEMPLATE_CLASS_IMPL)
}
}
}
/***********************************************************************
.\CONTROLS\TEMPLATES\GUITHEMESTYLEFACTORY.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace theme
{
using namespace collections;
using namespace controls;
using namespace templates;
class Theme : public Object, public virtual theme::ITheme
{
public:
Dictionary<WString, Ptr<ThemeTemplates>> templates;
ThemeTemplates* first = nullptr;
ThemeTemplates* last = nullptr;
bool RegisterTheme(const WString& name, Ptr<ThemeTemplates> theme)
{
CHECK_ERROR(theme->previous == nullptr, L"vl::presentation::theme::RegisterTheme(const WString&, Ptr<ThemeTemplates>)#Theme object has been registered");
CHECK_ERROR(theme->next == nullptr, L"vl::presentation::theme::RegisterTheme(const WString&, Ptr<ThemeTemplates>)#Theme object has been registered");
if (templates.Keys().Contains(name))
{
return false;
}
templates.Add(name, theme);
if (!first)
{
first = theme.Obj();
}
if (last)
{
last->next = theme.Obj();
}
theme->previous = last;
last = theme.Obj();
return true;
}
Ptr<ThemeTemplates> UnregisterTheme(const WString& name)
{
vint index = templates.Keys().IndexOf(name);
if (index == -1)
{
return nullptr;
}
auto themeTemplates = templates.Values().Get(index);
if (themeTemplates->previous)
{
themeTemplates->previous->next = themeTemplates->next;
}
else
{
first = themeTemplates->next;
}
if (themeTemplates->next)
{
themeTemplates->next->previous = themeTemplates->previous;
}
else
{
last = themeTemplates->previous;
}
templates.Remove(name);
return themeTemplates;
}
TemplateProperty<GuiControlTemplate> CreateStyle(ThemeName themeName)override
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::theme::ITheme::CreateStyle(ThemeName)#"
if (themeName == ThemeName::Window)
{
bool preferCustomFrameWindow = true;
auto current = last;
while (current)
{
if (current->PreferCustomFrameWindow)
{
preferCustomFrameWindow = current->PreferCustomFrameWindow.Value();
break;
}
current = current->previous;
}
CHECK_ERROR(current, ERROR_MESSAGE_PREFIX L"At least one ThemeTemplates::PreferCustomFrameWindow should be defined.");
if (preferCustomFrameWindow)
{
themeName = ThemeName::CustomFrameWindow;
}
else
{
themeName = ThemeName::SystemFrameWindow;
}
}
switch (themeName)
{
#define GUI_DEFINE_ITEM_PROPERTY(TEMPLATE, CONTROL) \
case ThemeName::CONTROL:\
{\
auto current = last;\
while (current) \
{\
if (current->CONTROL)\
{\
return current->CONTROL; \
}\
current = current->previous;\
}\
throw Exception(L"Control template for \"" L ## #CONTROL L"\" is not defined.");\
}\
GUI_CONTROL_TEMPLATE_TYPES(GUI_DEFINE_ITEM_PROPERTY)
#undef GUI_DEFINE_ITEM_PROPERTY
default:
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unknown theme name.");
}
#undef ERROR_MESSAGE_PREFIX
}
};
controls::GuiControlHost* ThemeTemplates::GetControlHostForInstance()
{
return nullptr;
}
ThemeTemplates::~ThemeTemplates()
{
FinalizeAggregation();
}
Theme* currentTheme = nullptr;
ITheme* GetCurrentTheme()
{
return currentTheme;
}
void InitializeTheme()
{
CHECK_ERROR(currentTheme == nullptr, L"vl::presentation::theme::InitializeTheme()#Theme has already been initialized");
currentTheme = new Theme;
}
void FinalizeTheme()
{
CHECK_ERROR(currentTheme != nullptr, L"vl::presentation::theme::FinalizeTheme()#Theme has not been initialized");
delete currentTheme;
currentTheme = nullptr;
}
bool RegisterTheme(Ptr<ThemeTemplates> theme)
{
CHECK_ERROR(currentTheme != nullptr, L"vl::presentation::theme::RegisterTheme(const WString&, Ptr<ThemeTemplates>)#Theme has already been initialized");
return currentTheme->RegisterTheme(theme->Name, theme);
}
Ptr<ThemeTemplates> UnregisterTheme(const WString& name)
{
CHECK_ERROR(currentTheme != nullptr, L"vl::presentation::theme::UnregisterTheme(const WString&)#Theme has already been initialized");
return currentTheme->UnregisterTheme(name);
}
}
}
}
/***********************************************************************
.\CONTROLS\TEXTEDITORPACKAGE\GUIDOCUMENTVIEWER.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace collections;
using namespace elements;
using namespace compositions;
/***********************************************************************
GuiDocumentItem
***********************************************************************/
GuiDocumentItem::GuiDocumentItem(const WString& _name)
:name(_name)
{
container = new GuiBoundsComposition;
container->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
container->SetAssociatedCursor(GetCurrentController()->ResourceService()->GetSystemCursor(INativeCursor::Arrow));
}
GuiDocumentItem::~GuiDocumentItem()
{
if (!owned)
{
SafeDeleteComposition(container);
}
}
compositions::GuiGraphicsComposition* GuiDocumentItem::GetContainer()
{
return container;
}
WString GuiDocumentItem::GetName()
{
return name;
}
/***********************************************************************
GuiDocumentCommonInterface
***********************************************************************/
void GuiDocumentCommonInterface::InvokeUndoRedoChanged()
{
UndoRedoChanged.Execute(documentControl->GetNotifyEventArguments());
}
void GuiDocumentCommonInterface::InvokeModifiedChanged()
{
ModifiedChanged.Execute(documentControl->GetNotifyEventArguments());
}
void GuiDocumentCommonInterface::UpdateCaretPoint()
{
GuiGraphicsHost* host=documentComposition->GetRelatedGraphicsHost();
if(host)
{
Rect caret=documentElement->GetCaretBounds(documentElement->GetCaretEnd(), documentElement->IsCaretEndPreferFrontSide());
Point view=GetDocumentViewPosition();
vint x=caret.x1-view.x;
vint y=caret.y2-view.y;
host->SetCaretPoint(Point(x, y), documentComposition);
}
}
void GuiDocumentCommonInterface::EnsureDocumentRectVisible(Rect bounds)
{
if (bounds != Rect())
{
bounds.x1 -= 15;
bounds.y1 -= 15;
bounds.x2 += 15;
bounds.y2 += 15;
EnsureRectVisible(bounds);
}
}
void GuiDocumentCommonInterface::Move(TextPos caret, bool shift, bool frontSide)
{
TextPos begin=documentElement->GetCaretBegin();
TextPos end=documentElement->GetCaretEnd();
TextPos newBegin=shift?begin:caret;
TextPos newEnd=caret;
documentElement->SetCaret(newBegin, newEnd, frontSide);
documentElement->SetCaretVisible(true);
EnsureDocumentRectVisible(documentElement->GetCaretBounds(newEnd, frontSide));
UpdateCaretPoint();
SelectionChanged.Execute(documentControl->GetNotifyEventArguments());
}
bool GuiDocumentCommonInterface::ProcessKey(VKEY code, bool shift, bool ctrl)
{
if(IGuiShortcutKeyItem* item=internalShortcutKeyManager->TryGetShortcut(ctrl, shift, false, code))
{
GuiEventArgs arguments(documentControl->GetBoundsComposition());
item->Executed.Execute(arguments);
return true;
}
TextPos currentCaret=documentElement->GetCaretEnd();
bool frontSide=documentElement->IsCaretEndPreferFrontSide();
TextPos begin=documentElement->GetCaretBegin();
TextPos end=documentElement->GetCaretEnd();
switch(code)
{
case VKEY::KEY_UP:
{
TextPos newCaret=documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretMoveUp, frontSide);
Move(newCaret, shift, frontSide);
}
break;
case VKEY::KEY_DOWN:
{
TextPos newCaret=documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretMoveDown, frontSide);
Move(newCaret, shift, frontSide);
}
break;
case VKEY::KEY_LEFT:
{
TextPos newCaret=documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretMoveLeft, frontSide);
Move(newCaret, shift, frontSide);
}
break;
case VKEY::KEY_RIGHT:
{
TextPos newCaret=documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretMoveRight, frontSide);
Move(newCaret, shift, frontSide);
}
break;
case VKEY::KEY_HOME:
{
TextPos newCaret=documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretLineFirst, frontSide);
if(newCaret==currentCaret)
{
newCaret=documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretFirst, frontSide);
}
Move(newCaret, shift, frontSide);
}
break;
case VKEY::KEY_END:
{
TextPos newCaret=documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretLineLast, frontSide);
if(newCaret==currentCaret)
{
newCaret=documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretLast, frontSide);
}
Move(newCaret, shift, frontSide);
}
break;
case VKEY::KEY_PRIOR:
{
}
break;
case VKEY::KEY_NEXT:
{
}
break;
case VKEY::KEY_BACK:
if(editMode==Editable)
{
if(begin==end)
{
ProcessKey(VKEY::KEY_LEFT, true, false);
}
Array<WString> text;
EditText(documentElement->GetCaretBegin(), documentElement->GetCaretEnd(), documentElement->IsCaretEndPreferFrontSide(), text);
return true;
}
break;
case VKEY::KEY_DELETE:
if(editMode==Editable)
{
if(begin==end)
{
ProcessKey(VKEY::KEY_RIGHT, true, false);
}
Array<WString> text;
EditText(documentElement->GetCaretBegin(), documentElement->GetCaretEnd(), documentElement->IsCaretEndPreferFrontSide(), text);
return true;
}
break;
case VKEY::KEY_RETURN:
if(editMode==Editable)
{
if(ctrl)
{
Array<WString> text(1);
text[0]=L"\r\n";
EditText(documentElement->GetCaretBegin(), documentElement->GetCaretEnd(), documentElement->IsCaretEndPreferFrontSide(), text);
}
else
{
Array<WString> text(2);
EditText(documentElement->GetCaretBegin(), documentElement->GetCaretEnd(), documentElement->IsCaretEndPreferFrontSide(), text);
}
return true;
}
break;
default:;
}
return false;
}
void GuiDocumentCommonInterface::InstallDocumentViewer(
GuiControl* _sender,
compositions::GuiGraphicsComposition* _mouseArea,
compositions::GuiGraphicsComposition* _container,
compositions::GuiGraphicsComposition* eventComposition,
compositions::GuiGraphicsComposition* focusableComposition
)
{
documentControl = _sender;
documentElement = GuiDocumentElement::Create();
documentElement->SetCallback(this);
documentComposition = new GuiBoundsComposition;
documentComposition->SetOwnedElement(Ptr(documentElement));
documentComposition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElement);
documentComposition->SetAlignmentToParent(Margin(5, 5, 5, 5));
_container->AddChild(documentComposition);
ReplaceMouseArea(_mouseArea);
focusableComposition->GetEventReceiver()->caretNotify.AttachMethod(this, &GuiDocumentCommonInterface::OnCaretNotify);
focusableComposition->GetEventReceiver()->gotFocus.AttachMethod(this, &GuiDocumentCommonInterface::OnGotFocus);
focusableComposition->GetEventReceiver()->lostFocus.AttachMethod(this, &GuiDocumentCommonInterface::OnLostFocus);
focusableComposition->GetEventReceiver()->keyDown.AttachMethod(this, &GuiDocumentCommonInterface::OnKeyDown);
focusableComposition->GetEventReceiver()->charInput.AttachMethod(this, &GuiDocumentCommonInterface::OnCharInput);
undoRedoProcessor->Setup(documentElement, documentComposition);
ActiveHyperlinkChanged.SetAssociatedComposition(eventComposition);
ActiveHyperlinkExecuted.SetAssociatedComposition(eventComposition);
SelectionChanged.SetAssociatedComposition(eventComposition);
UndoRedoChanged.SetAssociatedComposition(eventComposition);
ModifiedChanged.SetAssociatedComposition(eventComposition);
undoRedoProcessor->UndoRedoChanged.Add(this, &GuiDocumentCommonInterface::InvokeUndoRedoChanged);
undoRedoProcessor->ModifiedChanged.Add(this, &GuiDocumentCommonInterface::InvokeModifiedChanged);
SetDocument(Ptr(new DocumentModel));
}
void GuiDocumentCommonInterface::ReplaceMouseArea(compositions::GuiGraphicsComposition* _mouseArea)
{
if (documentMouseArea)
{
documentMouseArea->GetEventReceiver()->mouseMove.Detach(onMouseMoveHandler);
documentMouseArea->GetEventReceiver()->leftButtonDown.Detach(onMouseDownHandler);
documentMouseArea->GetEventReceiver()->leftButtonUp.Detach(onMouseUpHandler);
documentMouseArea->GetEventReceiver()->mouseLeave.Detach(onMouseLeaveHandler);
onMouseMoveHandler = nullptr;
onMouseDownHandler = nullptr;
onMouseUpHandler = nullptr;
onMouseLeaveHandler = nullptr;
}
documentMouseArea = _mouseArea;
if (documentMouseArea)
{
onMouseMoveHandler = documentMouseArea->GetEventReceiver()->mouseMove.AttachMethod(this, &GuiDocumentCommonInterface::OnMouseMove);
onMouseDownHandler = documentMouseArea->GetEventReceiver()->leftButtonDown.AttachMethod(this, &GuiDocumentCommonInterface::OnMouseDown);
onMouseUpHandler = documentMouseArea->GetEventReceiver()->leftButtonUp.AttachMethod(this, &GuiDocumentCommonInterface::OnMouseUp);
onMouseLeaveHandler = documentMouseArea->GetEventReceiver()->mouseLeave.AttachMethod(this, &GuiDocumentCommonInterface::OnMouseLeave);
}
}
void GuiDocumentCommonInterface::SetActiveHyperlink(Ptr<DocumentHyperlinkRun::Package> package)
{
ActivateActiveHyperlink(false);
activeHyperlinks =
!package ? nullptr :
package->hyperlinks.Count() == 0 ? nullptr :
package;
ActivateActiveHyperlink(true);
ActiveHyperlinkChanged.Execute(documentControl->GetNotifyEventArguments());
}
void GuiDocumentCommonInterface::ActivateActiveHyperlink(bool activate)
{
if (activeHyperlinks)
{
for (auto run : activeHyperlinks->hyperlinks)
{
run->styleName = activate ? run->activeStyleName : run->normalStyleName;
}
documentElement->NotifyParagraphUpdated(activeHyperlinks->row, 1, 1, false);
}
}
void GuiDocumentCommonInterface::AddShortcutCommand(VKEY key, const Func<void()>& eventHandler)
{
IGuiShortcutKeyItem* item=internalShortcutKeyManager->CreateNewShortcut(true, false, false, key);
item->Executed.AttachLambda([=](GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
eventHandler();
});
}
void GuiDocumentCommonInterface::EditTextInternal(TextPos begin, TextPos end, const Func<void(TextPos, TextPos, vint&, vint&)>& editor)
{
// save run before editing
if(begin>end)
{
TextPos temp=begin;
begin=end;
end=temp;
}
Ptr<DocumentModel> originalModel=documentElement->GetDocument()->CopyDocument(begin, end, true);
if(originalModel)
{
// edit
vint paragraphCount=0;
vint lastParagraphLength=0;
editor(begin, end, paragraphCount, lastParagraphLength);
// calculate new caret
TextPos caret;
if(paragraphCount==0)
{
caret=begin;
}
else if(paragraphCount==1)
{
caret=TextPos(begin.row, begin.column+lastParagraphLength);
}
else
{
caret=TextPos(begin.row+paragraphCount-1, lastParagraphLength);
}
documentElement->SetCaret(caret, caret, true);
EnsureDocumentRectVisible(documentElement->GetCaretBounds(caret, true));
documentControl->TextChanged.Execute(documentControl->GetNotifyEventArguments());
UpdateCaretPoint();
SelectionChanged.Execute(documentControl->GetNotifyEventArguments());
// save run after editing
Ptr<DocumentModel> inputModel=documentElement->GetDocument()->CopyDocument(begin, caret, true);
// submit redo-undo
GuiDocumentUndoRedoProcessor::ReplaceModelStruct arguments;
arguments.originalStart=begin;
arguments.originalEnd=end;
arguments.originalModel=originalModel;
arguments.inputStart=begin;
arguments.inputEnd=caret;
arguments.inputModel=inputModel;
undoRedoProcessor->OnReplaceModel(arguments);
}
}
void GuiDocumentCommonInterface::EditStyleInternal(TextPos begin, TextPos end, const Func<void(TextPos, TextPos)>& editor)
{
// save run before editing
if(begin>end)
{
TextPos temp=begin;
begin=end;
end=temp;
}
Ptr<DocumentModel> originalModel=documentElement->GetDocument()->CopyDocument(begin, end, true);
if(originalModel)
{
// edit
editor(begin, end);
// save run after editing
Ptr<DocumentModel> inputModel=documentElement->GetDocument()->CopyDocument(begin, end, true);
// submit redo-undo
GuiDocumentUndoRedoProcessor::ReplaceModelStruct arguments;
arguments.originalStart=begin;
arguments.originalEnd=end;
arguments.originalModel=originalModel;
arguments.inputStart=begin;
arguments.inputEnd=end;
arguments.inputModel=inputModel;
undoRedoProcessor->OnReplaceModel(arguments);
}
}
void GuiDocumentCommonInterface::MergeBaselineAndDefaultFont(Ptr<DocumentModel> document)
{
document->MergeDefaultFont(documentControl->GetDisplayFont());
if (baselineDocument)
{
document->MergeBaselineStyles(baselineDocument);
}
}
void GuiDocumentCommonInterface::OnFontChanged()
{
auto document = documentElement->GetDocument();
MergeBaselineAndDefaultFont(document);
documentElement->SetDocument(document);
}
void GuiDocumentCommonInterface::OnCaretNotify(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if(documentControl->GetVisuallyEnabled())
{
if(editMode!=ViewOnly)
{
documentElement->SetCaretVisible(!documentElement->GetCaretVisible());
}
}
}
void GuiDocumentCommonInterface::OnGotFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if(documentControl->GetVisuallyEnabled())
{
if(editMode!=ViewOnly)
{
documentElement->SetCaretVisible(true);
UpdateCaretPoint();
}
}
}
void GuiDocumentCommonInterface::OnLostFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if(documentControl->GetVisuallyEnabled())
{
documentElement->SetCaretVisible(false);
}
}
void GuiDocumentCommonInterface::OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments)
{
if(documentControl->GetVisuallyEnabled())
{
if(editMode!=ViewOnly)
{
if(ProcessKey(arguments.code, arguments.shift, arguments.ctrl))
{
arguments.handled=true;
}
}
}
}
void GuiDocumentCommonInterface::OnCharInput(compositions::GuiGraphicsComposition* sender, compositions::GuiCharEventArgs& arguments)
{
if (documentControl->GetVisuallyEnabled())
{
if (editMode == Editable &&
arguments.code != (wchar_t)VKEY::KEY_ESCAPE &&
arguments.code != (wchar_t)VKEY::KEY_BACK &&
arguments.code != (wchar_t)VKEY::KEY_RETURN &&
(arguments.code != (wchar_t)VKEY::KEY_TAB || documentControl->GetAcceptTabInput()) &&
!arguments.ctrl)
{
Array<WString> text(1);
text[0] = WString::FromChar(arguments.code);
EditText(documentElement->GetCaretBegin(), documentElement->GetCaretEnd(), documentElement->IsCaretEndPreferFrontSide(), text);
}
}
}
void GuiDocumentCommonInterface::UpdateCursor(INativeCursor* cursor)
{
if (documentMouseArea)
{
documentMouseArea->SetAssociatedCursor(cursor);
}
}
Point GuiDocumentCommonInterface::GetMouseOffset()
{
if (documentMouseArea)
{
auto documentBounds = documentComposition->GetGlobalBounds();
auto mouseAreaBounds = documentMouseArea->GetGlobalBounds();
return Point(
documentBounds.x1 - mouseAreaBounds.x1,
documentBounds.y1 - mouseAreaBounds.y1
);
}
else
{
return Point(0, 0);
}
}
void GuiDocumentCommonInterface::OnMouseMove(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
auto offset = GetMouseOffset();
auto x = arguments.x - offset.x;
auto y = arguments.y - offset.y;
if(documentControl->GetVisuallyEnabled())
{
switch(editMode)
{
case ViewOnly:
{
auto package = documentElement->GetHyperlinkFromPoint({ x, y });
bool handCursor = false;
if(dragging)
{
if(activeHyperlinks)
{
if (package && CompareEnumerable(activeHyperlinks->hyperlinks, package->hyperlinks) == 0)
{
ActivateActiveHyperlink(true);
handCursor = true;
}
else
{
ActivateActiveHyperlink(false);
}
}
}
else
{
SetActiveHyperlink(package);
handCursor = activeHyperlinks;
}
if(handCursor)
{
auto cursor = GetCurrentController()->ResourceService()->GetSystemCursor(INativeCursor::Hand);
UpdateCursor(cursor);
}
else
{
UpdateCursor(nullptr);
}
}
break;
case Selectable:
case Editable:
if(dragging)
{
TextPos caret=documentElement->CalculateCaretFromPoint(Point(x, y));
TextPos oldCaret=documentElement->GetCaretBegin();
Move(caret, true, (oldCaret==caret?documentElement->IsCaretEndPreferFrontSide():caret<oldCaret));
}
break;
}
}
}
void GuiDocumentCommonInterface::OnMouseDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
auto offset = GetMouseOffset();
auto x = arguments.x - offset.x;
auto y = arguments.y - offset.y;
if(documentControl->GetVisuallyEnabled())
{
switch(editMode)
{
case ViewOnly:
SetActiveHyperlink(documentElement->GetHyperlinkFromPoint({ x, y }));
break;
case Selectable:
case Editable:
{
documentControl->SetFocused();
TextPos caret=documentElement->CalculateCaretFromPoint(Point(x, y));
TextPos oldCaret=documentElement->GetCaretEnd();
if(caret!=oldCaret)
{
Move(caret, arguments.shift, caret<oldCaret);
}
}
break;
}
dragging=true;
}
}
void GuiDocumentCommonInterface::OnMouseUp(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
auto offset = GetMouseOffset();
auto x = arguments.x - offset.x;
auto y = arguments.y - offset.y;
if(documentControl->GetVisuallyEnabled())
{
dragging=false;
switch(editMode)
{
case ViewOnly:
{
auto package = documentElement->GetHyperlinkFromPoint({ x, y });
if(activeHyperlinks)
{
if (package && CompareEnumerable(activeHyperlinks->hyperlinks, package->hyperlinks) == 0)
{
ActiveHyperlinkExecuted.Execute(documentControl->GetNotifyEventArguments());
}
else
{
SetActiveHyperlink(nullptr);
}
}
}
break;
default:;
}
}
}
void GuiDocumentCommonInterface::OnMouseLeave(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
SetActiveHyperlink(nullptr);
}
Point GuiDocumentCommonInterface::GetDocumentViewPosition()
{
return Point(0, 0);
}
void GuiDocumentCommonInterface::EnsureRectVisible(Rect bounds)
{
}
//================ callback
void GuiDocumentCommonInterface::OnStartRender()
{
for (auto item : documentItems.Values())
{
item->visible = false;
}
}
void GuiDocumentCommonInterface::OnFinishRender()
{
for (auto item : documentItems.Values())
{
if (item->container->GetVisible() != item->visible)
{
item->container->SetVisible(item->visible);
}
}
}
Size GuiDocumentCommonInterface::OnRenderEmbeddedObject(const WString& name, const Rect& location)
{
vint index = documentItems.Keys().IndexOf(name);
if (index != -1)
{
auto item = documentItems.Values()[index];
auto size = item->container->GetCachedBounds().GetSize();
item->container->SetExpectedBounds(Rect(location.LeftTop(), Size(0, 0)));
item->visible = true;
return size;
}
return Size();
}
//================ basic
GuiDocumentCommonInterface::GuiDocumentCommonInterface()
{
undoRedoProcessor = Ptr(new GuiDocumentUndoRedoProcessor);
internalShortcutKeyManager = Ptr(new GuiShortcutKeyManager);
AddShortcutCommand(VKEY::KEY_Z, Func<bool()>(this, &GuiDocumentCommonInterface::Undo));
AddShortcutCommand(VKEY::KEY_Y, Func<bool()>(this, &GuiDocumentCommonInterface::Redo));
AddShortcutCommand(VKEY::KEY_A, Func<void()>(this, &GuiDocumentCommonInterface::SelectAll));
AddShortcutCommand(VKEY::KEY_X, Func<bool()>(this, &GuiDocumentCommonInterface::Cut));
AddShortcutCommand(VKEY::KEY_C, Func<bool()>(this, &GuiDocumentCommonInterface::Copy));
AddShortcutCommand(VKEY::KEY_V, Func<bool()>(this, &GuiDocumentCommonInterface::Paste));
}
GuiDocumentCommonInterface::~GuiDocumentCommonInterface()
{
}
Ptr<DocumentModel> GuiDocumentCommonInterface::GetDocument()
{
return documentElement->GetDocument();
}
void GuiDocumentCommonInterface::SetDocument(Ptr<DocumentModel> value)
{
SetActiveHyperlink(0);
ClearUndoRedo();
NotifyModificationSaved();
if (value)
{
if (value->paragraphs.Count() == 0)
{
value->paragraphs.Add(Ptr(new DocumentParagraphRun));
}
MergeBaselineAndDefaultFont(value);
}
documentElement->SetDocument(value);
}
//================ document items
bool GuiDocumentCommonInterface::AddDocumentItem(Ptr<GuiDocumentItem> value)
{
if (documentItems.Keys().Contains(value->GetName()))
{
return false;
}
documentItems.Add(value->GetName(), value);
documentComposition->AddChild(value->container);
value->visible = false;
value->owned = true;
value->container->SetVisible(false);
return true;
}
bool GuiDocumentCommonInterface::RemoveDocumentItem(Ptr<GuiDocumentItem> value)
{
vint index = documentItems.Keys().IndexOf(value->GetName());
if (index == -1)
{
return false;
}
if (documentItems.Values()[index] != value)
{
return false;
}
value->owned = false;
documentComposition->RemoveChild(value->container);
documentItems.Remove(value->GetName());
return true;
}
const GuiDocumentCommonInterface::DocumentItemMap& GuiDocumentCommonInterface::GetDocumentItems()
{
return documentItems;
}
//================ caret operations
TextPos GuiDocumentCommonInterface::GetCaretBegin()
{
return documentElement->GetCaretBegin();
}
TextPos GuiDocumentCommonInterface::GetCaretEnd()
{
return documentElement->GetCaretEnd();
}
void GuiDocumentCommonInterface::SetCaret(TextPos begin, TextPos end)
{
documentElement->SetCaret(begin, end, end>=begin);
UpdateCaretPoint();
SelectionChanged.Execute(documentControl->GetNotifyEventArguments());
}
TextPos GuiDocumentCommonInterface::CalculateCaretFromPoint(Point point)
{
return documentElement->CalculateCaretFromPoint(point);
}
Rect GuiDocumentCommonInterface::GetCaretBounds(TextPos caret, bool frontSide)
{
return documentElement->GetCaretBounds(caret, frontSide);
}
//================ editing operations
void GuiDocumentCommonInterface::NotifyParagraphUpdated(vint index, vint oldCount, vint newCount, bool updatedText)
{
documentElement->NotifyParagraphUpdated(index, oldCount, newCount, updatedText);
}
void GuiDocumentCommonInterface::EditRun(TextPos begin, TextPos end, Ptr<DocumentModel> model, bool copy)
{
EditTextInternal(begin, end, [=](TextPos begin, TextPos end, vint& paragraphCount, vint& lastParagraphLength)
{
documentElement->EditRun(begin, end, model, copy);
paragraphCount=model->paragraphs.Count();
lastParagraphLength=paragraphCount==0?0:model->paragraphs[paragraphCount-1]->GetText(false).Length();
});
}
void GuiDocumentCommonInterface::EditText(TextPos begin, TextPos end, bool frontSide, const collections::Array<WString>& text)
{
EditTextInternal(begin, end, [=, &text](TextPos begin, TextPos end, vint& paragraphCount, vint& lastParagraphLength)
{
documentElement->EditText(begin, end, frontSide, text);
paragraphCount=text.Count();
lastParagraphLength=paragraphCount==0?0:text[paragraphCount-1].Length();
});
}
void GuiDocumentCommonInterface::EditStyle(TextPos begin, TextPos end, Ptr<DocumentStyleProperties> style)
{
EditStyleInternal(begin, end, [=](TextPos begin, TextPos end)
{
documentElement->EditStyle(begin, end, style);
});
}
void GuiDocumentCommonInterface::EditImage(TextPos begin, TextPos end, Ptr<GuiImageData> image)
{
EditTextInternal(begin, end, [=](TextPos begin, TextPos end, vint& paragraphCount, vint& lastParagraphLength)
{
documentElement->EditImage(begin, end, image);
paragraphCount=1;
lastParagraphLength=wcslen(DocumentImageRun::RepresentationText);
});
}
void GuiDocumentCommonInterface::EditHyperlink(vint paragraphIndex, vint begin, vint end, const WString& reference, const WString& normalStyleName, const WString& activeStyleName)
{
EditStyleInternal(TextPos(paragraphIndex, begin), TextPos(paragraphIndex, end), [=](TextPos begin, TextPos end)
{
documentElement->EditHyperlink(begin.row, begin.column, end.column, reference, normalStyleName, activeStyleName);
});
}
void GuiDocumentCommonInterface::RemoveHyperlink(vint paragraphIndex, vint begin, vint end)
{
EditStyleInternal(TextPos(paragraphIndex, begin), TextPos(paragraphIndex, end), [=](TextPos begin, TextPos end)
{
documentElement->RemoveHyperlink(begin.row, begin.column, end.column);
});
}
void GuiDocumentCommonInterface::EditStyleName(TextPos begin, TextPos end, const WString& styleName)
{
EditStyleInternal(begin, end, [=](TextPos begin, TextPos end)
{
documentElement->EditStyleName(begin, end, styleName);
});
}
void GuiDocumentCommonInterface::RemoveStyleName(TextPos begin, TextPos end)
{
EditStyleInternal(begin, end, [=](TextPos begin, TextPos end)
{
documentElement->RemoveStyleName(begin, end);
});
}
void GuiDocumentCommonInterface::RenameStyle(const WString& oldStyleName, const WString& newStyleName)
{
documentElement->RenameStyle(oldStyleName, newStyleName);
// submit redo-undo
GuiDocumentUndoRedoProcessor::RenameStyleStruct arguments;
arguments.oldStyleName=oldStyleName;
arguments.newStyleName=newStyleName;
undoRedoProcessor->OnRenameStyle(arguments);
}
void GuiDocumentCommonInterface::ClearStyle(TextPos begin, TextPos end)
{
EditStyleInternal(begin, end, [=](TextPos begin, TextPos end)
{
documentElement->ClearStyle(begin, end);
});
}
Ptr<DocumentStyleProperties> GuiDocumentCommonInterface::SummarizeStyle(TextPos begin, TextPos end)
{
if (begin>end)
{
TextPos temp = begin;
begin = end;
end = temp;
}
return documentElement->SummarizeStyle(begin, end);
}
Nullable<WString> GuiDocumentCommonInterface::SummarizeStyleName(TextPos begin, TextPos end)
{
if (begin>end)
{
TextPos temp = begin;
begin = end;
end = temp;
}
return documentElement->SummarizeStyleName(begin, end);
}
void GuiDocumentCommonInterface::SetParagraphAlignments(TextPos begin, TextPos end, const collections::Array<Nullable<Alignment>>& alignments)
{
vint first = begin.row;
vint last = end.row;
if (first > last)
{
vint temp = first;
first = last;
last = temp;
}
Ptr<DocumentModel> document = documentElement->GetDocument();
if (0 <= first && first < document->paragraphs.Count() && 0 <= last && last < document->paragraphs.Count() && last - first + 1 == alignments.Count())
{
auto arguments = Ptr(new GuiDocumentUndoRedoProcessor::SetAlignmentStruct);
arguments->start = first;
arguments->end = last;
arguments->originalAlignments.Resize(alignments.Count());
arguments->inputAlignments.Resize(alignments.Count());
for (vint i = first; i <= last; i++)
{
arguments->originalAlignments[i - first] = document->paragraphs[i]->alignment;
arguments->inputAlignments[i - first] = alignments[i - first];
}
documentElement->SetParagraphAlignment(begin, end, alignments);
undoRedoProcessor->OnSetAlignment(arguments);
}
}
void GuiDocumentCommonInterface::SetParagraphAlignment(TextPos begin, TextPos end, Nullable<Alignment> alignment)
{
#if defined VCZH_GCC && defined VCZH_64
#define abs labs
#endif
Array<Nullable<Alignment>> alignments(abs(begin.row - end.row) + 1);
#if defined VCZH_GCC && defined VCZH_64
#undef abs
#endif
for (vint i = 0; i < alignments.Count(); i++)
{
alignments[i] = alignment;
}
SetParagraphAlignments(begin, end, alignments);
}
Nullable<Alignment> GuiDocumentCommonInterface::SummarizeParagraphAlignment(TextPos begin, TextPos end)
{
if (begin>end)
{
TextPos temp = begin;
begin = end;
end = temp;
}
return documentElement->SummarizeParagraphAlignment(begin, end);
}
//================ editing control
WString GuiDocumentCommonInterface::GetActiveHyperlinkReference()
{
return activeHyperlinks ? activeHyperlinks->hyperlinks[0]->reference : L"";
}
GuiDocumentCommonInterface::EditMode GuiDocumentCommonInterface::GetEditMode()
{
return editMode;
}
void GuiDocumentCommonInterface::SetEditMode(EditMode value)
{
if(activeHyperlinks)
{
SetActiveHyperlink(nullptr);
}
editMode=value;
if(editMode==ViewOnly)
{
UpdateCursor(nullptr);
}
else
{
INativeCursor* cursor=GetCurrentController()->ResourceService()->GetSystemCursor(INativeCursor::IBeam);
UpdateCursor(cursor);
}
}
//================ selection operations
void GuiDocumentCommonInterface::SelectAll()
{
vint lastIndex=documentElement->GetDocument()->paragraphs.Count()-1;
Ptr<DocumentParagraphRun> lastParagraph=documentElement->GetDocument()->paragraphs[lastIndex];
TextPos begin(0, 0);
TextPos end(lastIndex, lastParagraph->GetText(false).Length());
SetCaret(begin, end);
}
WString GuiDocumentCommonInterface::GetSelectionText()
{
TextPos begin=documentElement->GetCaretBegin();
TextPos end=documentElement->GetCaretEnd();
if(begin>end)
{
TextPos temp=begin;
begin=end;
end=temp;
}
Ptr<DocumentModel> model=documentElement->GetDocument()->CopyDocument(begin, end, false);
return model->GetText(true);
}
void GuiDocumentCommonInterface::SetSelectionText(const WString& value)
{
List<WString> paragraphs;
{
stream::StringReader reader(value);
WString paragraph;
bool empty=true;
while(!reader.IsEnd())
{
WString line=reader.ReadLine();
if(empty)
{
paragraph+=line;
empty=false;
}
else if(line!=L"")
{
paragraph+=L"\r\n"+line;
}
else
{
paragraphs.Add(paragraph);
paragraph=L"";
empty=true;
}
}
if(!empty)
{
paragraphs.Add(paragraph);
}
}
TextPos begin=documentElement->GetCaretBegin();
TextPos end=documentElement->GetCaretEnd();
if(begin>end)
{
TextPos temp=begin;
begin=end;
end=temp;
}
Array<WString> text;
CopyFrom(text, paragraphs);
EditText(begin, end, documentElement->IsCaretEndPreferFrontSide(), text);
}
Ptr<DocumentModel> GuiDocumentCommonInterface::GetSelectionModel()
{
TextPos begin=documentElement->GetCaretBegin();
TextPos end=documentElement->GetCaretEnd();
if(begin>end)
{
TextPos temp=begin;
begin=end;
end=temp;
}
Ptr<DocumentModel> model=documentElement->GetDocument()->CopyDocument(begin, end, true);
return model;
}
void GuiDocumentCommonInterface::SetSelectionModel(Ptr<DocumentModel> value)
{
TextPos begin=documentElement->GetCaretBegin();
TextPos end=documentElement->GetCaretEnd();
if(begin>end)
{
TextPos temp=begin;
begin=end;
end=temp;
}
EditRun(begin, end, value, true);
}
//================ clipboard operations
bool GuiDocumentCommonInterface::CanCut()
{
return editMode==Editable && documentElement->GetCaretBegin()!=documentElement->GetCaretEnd();
}
bool GuiDocumentCommonInterface::CanCopy()
{
return documentElement->GetCaretBegin()!=documentElement->GetCaretEnd();
}
bool GuiDocumentCommonInterface::CanPaste()
{
if (editMode == Editable)
{
auto reader = GetCurrentController()->ClipboardService()->ReadClipboard();
return reader->ContainsText() || reader->ContainsDocument() || reader->ContainsImage();
}
return false;
}
bool GuiDocumentCommonInterface::Cut()
{
if (!CanCut())return false;
auto writer = GetCurrentController()->ClipboardService()->WriteClipboard();
auto model = GetSelectionModel();
writer->SetDocument(model);
writer->Submit();
SetSelectionText(L"");
return true;
}
bool GuiDocumentCommonInterface::Copy()
{
if (!CanCopy()) return false;
auto writer = GetCurrentController()->ClipboardService()->WriteClipboard();
auto model = GetSelectionModel();
writer->SetDocument(model);
writer->Submit();
return true;
}
bool GuiDocumentCommonInterface::Paste()
{
if (!CanPaste()) return false;
auto reader = GetCurrentController()->ClipboardService()->ReadClipboard();
if (reader->ContainsDocument())
{
if (auto document = reader->GetDocument())
{
SetSelectionModel(document);
return true;
}
}
if (reader->ContainsText())
{
SetSelectionText(reader->GetText());
return true;
}
if (reader->ContainsImage())
{
if (auto image = reader->GetImage())
{
auto imageData = Ptr(new GuiImageData(image, 0));
EditImage(GetCaretBegin(), GetCaretEnd(), imageData);
return true;
}
}
return false;
}
//================ undo redo control
bool GuiDocumentCommonInterface::CanUndo()
{
return editMode==Editable && undoRedoProcessor->CanUndo();
}
bool GuiDocumentCommonInterface::CanRedo()
{
return editMode==Editable && undoRedoProcessor->CanRedo();
}
void GuiDocumentCommonInterface::ClearUndoRedo()
{
undoRedoProcessor->ClearUndoRedo();
}
bool GuiDocumentCommonInterface::GetModified()
{
return undoRedoProcessor->GetModified();
}
void GuiDocumentCommonInterface::NotifyModificationSaved()
{
undoRedoProcessor->NotifyModificationSaved();
}
bool GuiDocumentCommonInterface::Undo()
{
if(CanUndo())
{
return undoRedoProcessor->Undo();
}
else
{
return false;
}
}
bool GuiDocumentCommonInterface::Redo()
{
if(CanRedo())
{
return undoRedoProcessor->Redo();
}
else
{
return false;
}
}
/***********************************************************************
GuiDocumentViewer
***********************************************************************/
void GuiDocumentViewer::BeforeControlTemplateUninstalled_()
{
ReplaceMouseArea(nullptr);
}
void GuiDocumentViewer::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
baselineDocument = ct->GetBaselineDocument();
if (documentElement)
{
documentElement->SetCaretColor(ct->GetCaretColor());
SetDocument(GetDocument());
}
ReplaceMouseArea(containerComposition->GetParent());
}
void GuiDocumentViewer::UpdateDisplayFont()
{
GuiScrollContainer::UpdateDisplayFont();
OnFontChanged();
}
Point GuiDocumentViewer::GetDocumentViewPosition()
{
return GetViewBounds().LeftTop();
}
void GuiDocumentViewer::EnsureRectVisible(Rect bounds)
{
Rect viewBounds=GetViewBounds();
vint offset=0;
if(bounds.y1<viewBounds.y1)
{
offset=bounds.y1-viewBounds.y1;
}
else if(bounds.y2>viewBounds.y2)
{
offset=bounds.y2-viewBounds.y2;
}
if (auto scroll = GetVerticalScroll())
{
scroll->SetPosition(viewBounds.y1 + offset);
}
}
GuiDocumentViewer::GuiDocumentViewer(theme::ThemeName themeName)
:GuiScrollContainer(themeName)
{
SetAcceptTabInput(true);
SetFocusableComposition(boundsComposition);
InstallDocumentViewer(this, containerComposition->GetParent(), containerComposition, boundsComposition, focusableComposition);
SetExtendToFullWidth(true);
SetHorizontalAlwaysVisible(false);
}
GuiDocumentViewer::~GuiDocumentViewer()
{
}
const WString& GuiDocumentViewer::GetText()
{
text=documentElement->GetDocument()->GetText(true);
return text;
}
void GuiDocumentViewer::SetText(const WString& value)
{
SelectAll();
SetSelectionText(value);
}
/***********************************************************************
GuiDocumentLabel
***********************************************************************/
void GuiDocumentLabel::BeforeControlTemplateUninstalled_()
{
}
void GuiDocumentLabel::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
baselineDocument = ct->GetBaselineDocument();
if (documentElement)
{
documentElement->SetCaretColor(ct->GetCaretColor());
SetDocument(GetDocument());
}
}
void GuiDocumentLabel::UpdateDisplayFont()
{
GuiControl::UpdateDisplayFont();
OnFontChanged();
}
GuiDocumentLabel::GuiDocumentLabel(theme::ThemeName themeName)
:GuiControl(themeName)
{
SetAcceptTabInput(true);
SetFocusableComposition(boundsComposition);
InstallDocumentViewer(this, containerComposition, containerComposition, boundsComposition, focusableComposition);
}
GuiDocumentLabel::~GuiDocumentLabel()
{
}
const WString& GuiDocumentLabel::GetText()
{
text=documentElement->GetDocument()->GetText(true);
return text;
}
void GuiDocumentLabel::SetText(const WString& value)
{
SelectAll();
SetSelectionText(value);
}
}
}
}
/***********************************************************************
.\CONTROLS\TEXTEDITORPACKAGE\GUITEXTCOMMONINTERFACE.CPP
***********************************************************************/
#include <math.h>
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace elements;
using namespace elements::text;
using namespace compositions;
/***********************************************************************
GuiTextBoxCommonInterface::DefaultCallback
***********************************************************************/
GuiTextBoxCommonInterface::DefaultCallback::DefaultCallback(elements::GuiColorizedTextElement* _textElement, compositions::GuiGraphicsComposition* _textComposition)
:textElement(_textElement)
,textComposition(_textComposition)
{
}
GuiTextBoxCommonInterface::DefaultCallback::~DefaultCallback()
{
}
TextPos GuiTextBoxCommonInterface::DefaultCallback::GetLeftWord(TextPos pos)
{
return pos;
}
TextPos GuiTextBoxCommonInterface::DefaultCallback::GetRightWord(TextPos pos)
{
return pos;
}
void GuiTextBoxCommonInterface::DefaultCallback::GetWord(TextPos pos, TextPos& begin, TextPos& end)
{
begin=pos;
end=pos;
}
vint GuiTextBoxCommonInterface::DefaultCallback::GetPageRows()
{
return textComposition->GetCachedBounds().Height()/textElement->GetLines().GetRowHeight();
}
bool GuiTextBoxCommonInterface::DefaultCallback::BeforeModify(TextPos start, TextPos end, const WString& originalText, WString& inputText)
{
return true;
}
/***********************************************************************
GuiTextBoxCommonInterface
***********************************************************************/
void GuiTextBoxCommonInterface::InvokeUndoRedoChanged()
{
UndoRedoChanged.Execute(textControl->GetNotifyEventArguments());
}
void GuiTextBoxCommonInterface::InvokeModifiedChanged()
{
ModifiedChanged.Execute(textControl->GetNotifyEventArguments());
}
void GuiTextBoxCommonInterface::UpdateCaretPoint()
{
GuiGraphicsHost* host=textComposition->GetRelatedGraphicsHost();
if(host)
{
Rect caret=textElement->GetLines().GetRectFromTextPos(textElement->GetCaretEnd());
Point view=textElement->GetViewPosition();
vint x=caret.x1-view.x;
vint y=caret.y2-view.y;
host->SetCaretPoint(Point(x, y), textComposition);
}
}
void GuiTextBoxCommonInterface::Move(TextPos pos, bool shift)
{
TextPos oldBegin = textElement->GetCaretBegin();
TextPos oldEnd = textElement->GetCaretEnd();
#if defined VCZH_MSVC
if (0 <= pos.row && pos.row < textElement->GetLines().GetCount())
{
TextLine& line = textElement->GetLines().GetLine(pos.row);
if (pos.column > 0 && UTF16SPFirst(line.text[pos.column - 1]) && UTF16SPSecond(line.text[pos.column]))
{
if (pos < oldBegin)
{
pos.column--;
}
else if (pos > oldBegin)
{
pos.column++;
}
}
}
#endif
pos = textElement->GetLines().Normalize(pos);
if (!shift)
{
textElement->SetCaretBegin(pos);
}
textElement->SetCaretEnd(pos);
if (textControl)
{
GuiGraphicsHost* host = textComposition->GetRelatedGraphicsHost();
if (host)
{
if (host->GetFocusedComposition() == textControl->GetFocusableComposition())
{
textElement->SetCaretVisible(true);
}
}
}
Rect bounds = textElement->GetLines().GetRectFromTextPos(pos);
Rect view = Rect(textElement->GetViewPosition(), textComposition->GetCachedBounds().GetSize());
Point viewPoint = view.LeftTop();
if (view.x2 > view.x1 && view.y2 > view.y1)
{
if (bounds.x1 < view.x1)
{
viewPoint.x = bounds.x1;
}
else if (bounds.x2 > view.x2)
{
viewPoint.x = bounds.x2 - view.Width();
}
if (bounds.y1 < view.y1)
{
viewPoint.y = bounds.y1;
}
else if (bounds.y2 > view.y2)
{
viewPoint.y = bounds.y2 - view.Height();
}
}
callback->ScrollToView(viewPoint);
UpdateCaretPoint();
TextPos newBegin = textElement->GetCaretBegin();
TextPos newEnd = textElement->GetCaretEnd();
if (oldBegin != newBegin || oldEnd != newEnd)
{
ICommonTextEditCallback::TextCaretChangedStruct arguments;
arguments.oldBegin = oldBegin;
arguments.oldEnd = oldEnd;
arguments.newBegin = newBegin;
arguments.newEnd = newEnd;
arguments.editVersion = editVersion;
// TODO: (enumerable) foreach
for (vint i = 0; i < textEditCallbacks.Count(); i++)
{
textEditCallbacks[i]->TextCaretChanged(arguments);
}
SelectionChanged.Execute(textControl->GetNotifyEventArguments());
}
}
void GuiTextBoxCommonInterface::Modify(TextPos start, TextPos end, const WString& input, bool asKeyInput)
{
if(start>end)
{
TextPos temp=start;
start=end;
end=temp;
}
TextPos originalStart=start;
TextPos originalEnd=end;
WString originalText=textElement->GetLines().GetText(start, end);
WString inputText=input;
if(callback->BeforeModify(start, end, originalText, inputText))
{
{
ICommonTextEditCallback::TextEditPreviewStruct arguments;
arguments.originalStart=originalStart;
arguments.originalEnd=originalEnd;
arguments.originalText=originalText;
arguments.inputText=inputText;
arguments.editVersion=editVersion;
arguments.keyInput=asKeyInput;
// TODO: (enumerable) foreach
for(vint i=0;i<textEditCallbacks.Count();i++)
{
textEditCallbacks[i]->TextEditPreview(arguments);
}
inputText=arguments.inputText;
if(originalStart!=arguments.originalStart || originalEnd!=arguments.originalEnd)
{
originalStart=arguments.originalStart;
originalEnd=arguments.originalEnd;
originalText=textElement->GetLines().GetText(originalStart, originalEnd);
start=originalStart;
end=originalEnd;
}
}
SPIN_LOCK(elementModifyLock)
{
end=textElement->GetLines().Modify(start, end, inputText);
}
callback->AfterModify(originalStart, originalEnd, originalText, start, end, inputText);
editVersion++;
{
ICommonTextEditCallback::TextEditNotifyStruct arguments;
arguments.originalStart=originalStart;
arguments.originalEnd=originalEnd;
arguments.originalText=originalText;
arguments.inputStart=start;
arguments.inputEnd=end;
arguments.inputText=inputText;
arguments.editVersion=editVersion;
arguments.keyInput=asKeyInput;
// TODO: (enumerable) foreach
for(vint i=0;i<textEditCallbacks.Count();i++)
{
textEditCallbacks[i]->TextEditNotify(arguments);
}
}
Move(end, false);
// TODO: (enumerable) foreach
for(vint i=0;i<textEditCallbacks.Count();i++)
{
textEditCallbacks[i]->TextEditFinished(editVersion);
}
textControl->TextChanged.Execute(textControl->GetNotifyEventArguments());
}
}
bool GuiTextBoxCommonInterface::ProcessKey(VKEY code, bool shift, bool ctrl)
{
if(IGuiShortcutKeyItem* item=internalShortcutKeyManager->TryGetShortcut(ctrl, shift, false, code))
{
GuiEventArgs arguments(textControl->GetBoundsComposition());
item->Executed.Execute(arguments);
return true;
}
TextPos begin=textElement->GetCaretBegin();
TextPos end=textElement->GetCaretEnd();
switch(code)
{
case VKEY::KEY_ESCAPE:
if(autoComplete && autoComplete->IsListOpening() && !shift && !ctrl)
{
autoComplete->CloseList();
return true;
}
break;
case VKEY::KEY_RETURN:
if(autoComplete && autoComplete->IsListOpening() && !shift && !ctrl)
{
if(autoComplete->ApplySelectedListItem())
{
preventEnterDueToAutoComplete=true;
return true;
}
}
break;
case VKEY::KEY_UP:
if(autoComplete && autoComplete->IsListOpening() && !shift && !ctrl)
{
autoComplete->SelectPreviousListItem();
}
else
{
end.row--;
Move(end, shift);
}
return true;
case VKEY::KEY_DOWN:
if(autoComplete && autoComplete->IsListOpening() && !shift && !ctrl)
{
autoComplete->SelectNextListItem();
}
else
{
end.row++;
Move(end, shift);
}
return true;
case VKEY::KEY_LEFT:
{
if(ctrl)
{
Move(callback->GetLeftWord(end), shift);
}
else
{
if(end.column==0)
{
if(end.row>0)
{
end.row--;
end=textElement->GetLines().Normalize(end);
end.column=textElement->GetLines().GetLine(end.row).dataLength;
}
}
else
{
end.column--;
}
Move(end, shift);
}
}
return true;
case VKEY::KEY_RIGHT:
{
if(ctrl)
{
Move(callback->GetRightWord(end), shift);
}
else
{
if(end.column==textElement->GetLines().GetLine(end.row).dataLength)
{
if(end.row<textElement->GetLines().GetCount()-1)
{
end.row++;
end.column=0;
}
}
else
{
end.column++;
}
Move(end, shift);
}
}
return true;
case VKEY::KEY_HOME:
{
if(ctrl)
{
Move(TextPos(0, 0), shift);
}
else
{
end.column=0;
Move(end, shift);
}
}
return true;
case VKEY::KEY_END:
{
if(ctrl)
{
end.row=textElement->GetLines().GetCount()-1;
}
end.column=textElement->GetLines().GetLine(end.row).dataLength;
Move(end, shift);
}
return true;
case VKEY::KEY_PRIOR:
{
end.row-=callback->GetPageRows();
Move(end, shift);
}
return true;
case VKEY::KEY_NEXT:
{
end.row+=callback->GetPageRows();
Move(end, shift);
}
return true;
case VKEY::KEY_BACK:
if(!readonly)
{
if(ctrl && !shift)
{
ProcessKey(VKEY::KEY_LEFT, true, true);
ProcessKey(VKEY::KEY_BACK, false, false);
}
else if(!ctrl && shift)
{
ProcessKey(VKEY::KEY_UP, true, false);
ProcessKey(VKEY::KEY_BACK, false, false);
}
else
{
if(begin==end)
{
ProcessKey(VKEY::KEY_LEFT, true, false);
}
SetSelectionTextAsKeyInput(L"");
}
return true;
}
break;
case VKEY::KEY_DELETE:
if(!readonly)
{
if(ctrl && !shift)
{
ProcessKey(VKEY::KEY_RIGHT, true, true);
ProcessKey(VKEY::KEY_DELETE, false, false);
}
else if(!ctrl && shift)
{
ProcessKey(VKEY::KEY_DOWN, true, false);
ProcessKey(VKEY::KEY_DELETE, false, false);
}
else
{
if(begin==end)
{
ProcessKey(VKEY::KEY_RIGHT, true, false);
}
SetSelectionTextAsKeyInput(L"");
}
return true;
}
break;
default:;
}
return false;
}
void GuiTextBoxCommonInterface::OnGotFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
textElement->SetFocused(true);
textElement->SetCaretVisible(true);
UpdateCaretPoint();
}
void GuiTextBoxCommonInterface::OnLostFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
textElement->SetFocused(false);
textElement->SetCaretVisible(false);
}
void GuiTextBoxCommonInterface::OnCaretNotify(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
textElement->SetCaretVisible(!textElement->GetCaretVisible());
}
void GuiTextBoxCommonInterface::OnLeftButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if(textControl->GetVisuallyEnabled() && arguments.compositionSource==arguments.eventSource)
{
dragging=true;
TextPos pos=GetNearestTextPos(Point(arguments.x, arguments.y));
Move(pos, arguments.shift);
}
}
void GuiTextBoxCommonInterface::OnLeftButtonUp(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if(textControl->GetVisuallyEnabled() && arguments.compositionSource==arguments.eventSource)
{
dragging=false;
}
}
void GuiTextBoxCommonInterface::OnMouseMove(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if(textControl->GetVisuallyEnabled() && arguments.compositionSource==arguments.eventSource)
{
if(dragging)
{
TextPos pos=GetNearestTextPos(Point(arguments.x, arguments.y));
Move(pos, true);
}
}
}
void GuiTextBoxCommonInterface::OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments)
{
if(textControl->GetVisuallyEnabled() && arguments.compositionSource==arguments.eventSource)
{
if(ProcessKey(arguments.code, arguments.shift, arguments.ctrl))
{
arguments.handled=true;
}
}
}
void GuiTextBoxCommonInterface::OnCharInput(compositions::GuiGraphicsComposition* sender, compositions::GuiCharEventArgs& arguments)
{
if (preventEnterDueToAutoComplete)
{
preventEnterDueToAutoComplete = false;
if (arguments.code == (wchar_t)VKEY::KEY_RETURN)
{
return;
}
}
if (textControl->GetVisuallyEnabled() && arguments.compositionSource == arguments.eventSource)
{
if (!readonly &&
arguments.code != (wchar_t)VKEY::KEY_ESCAPE &&
arguments.code != (wchar_t)VKEY::KEY_BACK &&
(arguments.code != (wchar_t)VKEY::KEY_TAB || textControl->GetAcceptTabInput()) &&
!arguments.ctrl)
{
SetSelectionTextAsKeyInput(WString::FromChar(arguments.code));
}
}
}
void GuiTextBoxCommonInterface::Install(
elements::GuiColorizedTextElement* _textElement,
compositions::GuiGraphicsComposition* _textComposition,
GuiControl* _textControl,
compositions::GuiGraphicsComposition* eventComposition,
compositions::GuiGraphicsComposition* focusableComposition
)
{
textElement=_textElement;
textComposition=_textComposition;
textControl=_textControl;
textComposition->SetAssociatedCursor(GetCurrentController()->ResourceService()->GetSystemCursor(INativeCursor::IBeam));
SelectionChanged.SetAssociatedComposition(eventComposition);
UndoRedoChanged.SetAssociatedComposition(eventComposition);
ModifiedChanged.SetAssociatedComposition(eventComposition);
undoRedoProcessor->UndoRedoChanged.Add(this, &GuiTextBoxCommonInterface::InvokeUndoRedoChanged);
undoRedoProcessor->ModifiedChanged.Add(this, &GuiTextBoxCommonInterface::InvokeModifiedChanged);
focusableComposition->GetEventReceiver()->gotFocus.AttachMethod(this, &GuiTextBoxCommonInterface::OnGotFocus);
focusableComposition->GetEventReceiver()->lostFocus.AttachMethod(this, &GuiTextBoxCommonInterface::OnLostFocus);
focusableComposition->GetEventReceiver()->caretNotify.AttachMethod(this, &GuiTextBoxCommonInterface::OnCaretNotify);
textComposition->GetEventReceiver()->leftButtonDown.AttachMethod(this, &GuiTextBoxCommonInterface::OnLeftButtonDown);
textComposition->GetEventReceiver()->leftButtonUp.AttachMethod(this, &GuiTextBoxCommonInterface::OnLeftButtonUp);
textComposition->GetEventReceiver()->mouseMove.AttachMethod(this, &GuiTextBoxCommonInterface::OnMouseMove);
focusableComposition->GetEventReceiver()->keyDown.AttachMethod(this, &GuiTextBoxCommonInterface::OnKeyDown);
focusableComposition->GetEventReceiver()->charInput.AttachMethod(this, &GuiTextBoxCommonInterface::OnCharInput);
// TODO: (enumerable) foreach
for(vint i=0;i<textEditCallbacks.Count();i++)
{
textEditCallbacks[i]->Attach(textElement, elementModifyLock, textComposition ,editVersion);
}
}
GuiTextBoxCommonInterface::ICallback* GuiTextBoxCommonInterface::GetCallback()
{
return callback;
}
void GuiTextBoxCommonInterface::SetCallback(ICallback* value)
{
callback=value;
}
bool GuiTextBoxCommonInterface::AttachTextEditCallback(Ptr<ICommonTextEditCallback> value)
{
if(textEditCallbacks.Contains(value.Obj()))
{
return false;
}
else
{
textEditCallbacks.Add(value);
if(textElement)
{
value->Attach(textElement, elementModifyLock, textComposition, editVersion);
}
return true;
}
}
bool GuiTextBoxCommonInterface::DetachTextEditCallback(Ptr<ICommonTextEditCallback> value)
{
if(textEditCallbacks.Remove(value.Obj()))
{
value->Detach();
return true;
}
else
{
return false;
}
}
void GuiTextBoxCommonInterface::AddShortcutCommand(VKEY key, const Func<void()>& eventHandler)
{
IGuiShortcutKeyItem* item=internalShortcutKeyManager->CreateNewShortcut(true, false, false, key);
item->Executed.AttachLambda([=](GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
eventHandler();
});
}
elements::GuiColorizedTextElement* GuiTextBoxCommonInterface::GetTextElement()
{
return textElement;
}
void GuiTextBoxCommonInterface::UnsafeSetText(const WString& value)
{
if(textElement)
{
TextPos end;
if(textElement->GetLines().GetCount()>0)
{
end.row=textElement->GetLines().GetCount()-1;
end.column=textElement->GetLines().GetLine(end.row).dataLength;
}
Modify(TextPos(), end, value, false);
}
}
GuiTextBoxCommonInterface::GuiTextBoxCommonInterface()
:textElement(0)
,textComposition(0)
,editVersion(0)
,textControl(0)
,callback(0)
,dragging(false)
,readonly(false)
,preventEnterDueToAutoComplete(false)
{
undoRedoProcessor=Ptr(new GuiTextBoxUndoRedoProcessor);
AttachTextEditCallback(undoRedoProcessor);
internalShortcutKeyManager=Ptr(new GuiShortcutKeyManager);
AddShortcutCommand(VKEY::KEY_Z, Func<bool()>(this, &GuiTextBoxCommonInterface::Undo));
AddShortcutCommand(VKEY::KEY_Y, Func<bool()>(this, &GuiTextBoxCommonInterface::Redo));
AddShortcutCommand(VKEY::KEY_A, Func<void()>(this, &GuiTextBoxCommonInterface::SelectAll));
AddShortcutCommand(VKEY::KEY_X, Func<bool()>(this, &GuiTextBoxCommonInterface::Cut));
AddShortcutCommand(VKEY::KEY_C, Func<bool()>(this, &GuiTextBoxCommonInterface::Copy));
AddShortcutCommand(VKEY::KEY_V, Func<bool()>(this, &GuiTextBoxCommonInterface::Paste));
}
GuiTextBoxCommonInterface::~GuiTextBoxCommonInterface()
{
if(colorizer)
{
DetachTextEditCallback(colorizer);
colorizer=0;
}
if(undoRedoProcessor)
{
DetachTextEditCallback(undoRedoProcessor);
undoRedoProcessor=0;
}
// TODO: (enumerable) foreach
for(vint i=0;i<textEditCallbacks.Count();i++)
{
textEditCallbacks[i]->Detach();
}
textEditCallbacks.Clear();
}
//================ clipboard operations
bool GuiTextBoxCommonInterface::CanCut()
{
return !readonly && textElement->GetCaretBegin()!=textElement->GetCaretEnd() && textElement->GetPasswordChar()==L'\0';
}
bool GuiTextBoxCommonInterface::CanCopy()
{
return textElement->GetCaretBegin()!=textElement->GetCaretEnd() && textElement->GetPasswordChar()==L'\0';
}
bool GuiTextBoxCommonInterface::CanPaste()
{
if (!readonly && textElement->GetPasswordChar() == L'\0')
{
auto reader = GetCurrentController()->ClipboardService()->ReadClipboard();
return reader->ContainsText();
}
return false;
}
bool GuiTextBoxCommonInterface::Cut()
{
if (!CanCut()) return false;
auto writer = GetCurrentController()->ClipboardService()->WriteClipboard();
writer->SetText(GetSelectionText());
writer->Submit();
SetSelectionText(L"");
return true;
}
bool GuiTextBoxCommonInterface::Copy()
{
if (!CanCopy()) return false;
auto writer = GetCurrentController()->ClipboardService()->WriteClipboard();
writer->SetText(GetSelectionText());
writer->Submit();
return true;
}
bool GuiTextBoxCommonInterface::Paste()
{
if (!CanPaste()) return false;
auto reader = GetCurrentController()->ClipboardService()->ReadClipboard();
SetSelectionText(reader->GetText());
return true;
}
//================ editing control
bool GuiTextBoxCommonInterface::GetReadonly()
{
return readonly;
}
void GuiTextBoxCommonInterface::SetReadonly(bool value)
{
readonly=value;
}
//================ text operations
void GuiTextBoxCommonInterface::Select(TextPos begin, TextPos end)
{
Move(begin, false);
Move(end, true);
}
void GuiTextBoxCommonInterface::SelectAll()
{
vint row=textElement->GetLines().GetCount()-1;
Move(TextPos(0, 0), false);
Move(TextPos(row, textElement->GetLines().GetLine(row).dataLength), true);
}
WString GuiTextBoxCommonInterface::GetSelectionText()
{
TextPos selectionBegin=textElement->GetCaretBegin()<textElement->GetCaretEnd()?textElement->GetCaretBegin():textElement->GetCaretEnd();
TextPos selectionEnd=textElement->GetCaretBegin()>textElement->GetCaretEnd()?textElement->GetCaretBegin():textElement->GetCaretEnd();
return textElement->GetLines().GetText(selectionBegin, selectionEnd);
}
void GuiTextBoxCommonInterface::SetSelectionText(const WString& value)
{
Modify(textElement->GetCaretBegin(), textElement->GetCaretEnd(), value, false);
}
void GuiTextBoxCommonInterface::SetSelectionTextAsKeyInput(const WString& value)
{
Modify(textElement->GetCaretBegin(), textElement->GetCaretEnd(), value, true);
}
WString GuiTextBoxCommonInterface::GetRowText(vint row)
{
TextPos start=textElement->GetLines().Normalize(TextPos(row, 0));
TextPos end=TextPos(start.row, textElement->GetLines().GetLine(start.row).dataLength);
return GetFragmentText(start, end);
}
vint GuiTextBoxCommonInterface::GetRowCount()
{
return textElement->GetLines().GetCount();
}
WString GuiTextBoxCommonInterface::GetFragmentText(TextPos start, TextPos end)
{
start=textElement->GetLines().Normalize(start);
end=textElement->GetLines().Normalize(end);
return textElement->GetLines().GetText(start, end);
}
TextPos GuiTextBoxCommonInterface::GetCaretBegin()
{
return textElement->GetCaretBegin();
}
TextPos GuiTextBoxCommonInterface::GetCaretEnd()
{
return textElement->GetCaretEnd();
}
TextPos GuiTextBoxCommonInterface::GetCaretSmall()
{
TextPos c1=GetCaretBegin();
TextPos c2=GetCaretEnd();
return c1<c2?c1:c2;
}
TextPos GuiTextBoxCommonInterface::GetCaretLarge()
{
TextPos c1=GetCaretBegin();
TextPos c2=GetCaretEnd();
return c1>c2?c1:c2;
}
//================ position query
vint GuiTextBoxCommonInterface::GetRowWidth(vint row)
{
return textElement->GetLines().GetRowWidth(row);
}
vint GuiTextBoxCommonInterface::GetRowHeight()
{
return textElement->GetLines().GetRowHeight();
}
vint GuiTextBoxCommonInterface::GetMaxWidth()
{
return textElement->GetLines().GetMaxWidth();
}
vint GuiTextBoxCommonInterface::GetMaxHeight()
{
return textElement->GetLines().GetMaxHeight();
}
TextPos GuiTextBoxCommonInterface::GetTextPosFromPoint(Point point)
{
Point view=textElement->GetViewPosition();
return textElement->GetLines().GetTextPosFromPoint(Point(point.x+view.x, point.y+view.y));
}
Point GuiTextBoxCommonInterface::GetPointFromTextPos(TextPos pos)
{
Point view=textElement->GetViewPosition();
Point result=textElement->GetLines().GetPointFromTextPos(pos);
return Point(result.x-view.x, result.y-view.y);
}
Rect GuiTextBoxCommonInterface::GetRectFromTextPos(TextPos pos)
{
Point view=textElement->GetViewPosition();
Rect result=textElement->GetLines().GetRectFromTextPos(pos);
return Rect(Point(result.x1-view.x, result.y1-view.y), result.GetSize());
}
TextPos GuiTextBoxCommonInterface::GetNearestTextPos(Point point)
{
Point viewPosition=textElement->GetViewPosition();
Point mousePosition=Point(point.x+viewPosition.x, point.y+viewPosition.y);
TextPos pos=textElement->GetLines().GetTextPosFromPoint(mousePosition);
if(pos.column<textElement->GetLines().GetLine(pos.row).dataLength)
{
Rect rect=textElement->GetLines().GetRectFromTextPos(pos);
if(abs((int)(rect.x1-mousePosition.x))>=abs((int)(rect.x2-1-mousePosition.x)))
{
pos.column++;
}
}
return pos;
}
//================ colorizing
Ptr<GuiTextBoxColorizerBase> GuiTextBoxCommonInterface::GetColorizer()
{
return colorizer;
}
void GuiTextBoxCommonInterface::SetColorizer(Ptr<GuiTextBoxColorizerBase> value)
{
if (!filledDefaultColors)
{
filledDefaultColors = true;
CopyFrom(defaultColors, GetTextElement()->GetColors());
}
if(colorizer)
{
DetachTextEditCallback(colorizer);
}
colorizer=value;
if(colorizer)
{
AttachTextEditCallback(colorizer);
GetTextElement()->SetColors(colorizer->GetColors());
}
else
{
GetTextElement()->SetColors(defaultColors);
GetTextElement()->ResetTextColorIndex(0);
}
}
//================ auto complete
Ptr<GuiTextBoxAutoCompleteBase> GuiTextBoxCommonInterface::GetAutoComplete()
{
return autoComplete;
}
void GuiTextBoxCommonInterface::SetAutoComplete(Ptr<GuiTextBoxAutoCompleteBase> value)
{
if(autoComplete)
{
DetachTextEditCallback(autoComplete);
}
autoComplete=value;
if(autoComplete)
{
AttachTextEditCallback(autoComplete);
}
}
//================ undo redo control
vuint GuiTextBoxCommonInterface::GetEditVersion()
{
return editVersion;
}
bool GuiTextBoxCommonInterface::CanUndo()
{
return !readonly && undoRedoProcessor->CanUndo();
}
bool GuiTextBoxCommonInterface::CanRedo()
{
return !readonly && undoRedoProcessor->CanRedo();
}
void GuiTextBoxCommonInterface::ClearUndoRedo()
{
undoRedoProcessor->ClearUndoRedo();
}
bool GuiTextBoxCommonInterface::GetModified()
{
return undoRedoProcessor->GetModified();
}
void GuiTextBoxCommonInterface::NotifyModificationSaved()
{
undoRedoProcessor->NotifyModificationSaved();
}
bool GuiTextBoxCommonInterface::Undo()
{
if(CanUndo())
{
return undoRedoProcessor->Undo();
}
else
{
return false;
}
}
bool GuiTextBoxCommonInterface::Redo()
{
if(CanRedo())
{
return undoRedoProcessor->Redo();
}
else
{
return false;
}
}
}
}
}
/***********************************************************************
.\CONTROLS\TEXTEDITORPACKAGE\GUITEXTCONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace elements;
using namespace elements::text;
using namespace compositions;
using namespace collections;
/***********************************************************************
GuiMultilineTextBox::DefaultTextElementOperatorCallback
***********************************************************************/
GuiMultilineTextBox::TextElementOperatorCallback::TextElementOperatorCallback(GuiMultilineTextBox* _textControl)
:GuiTextBoxCommonInterface::DefaultCallback(
_textControl->textElement,
_textControl->textComposition
)
,textControl(_textControl)
{
}
void GuiMultilineTextBox::TextElementOperatorCallback::AfterModify(TextPos originalStart, TextPos originalEnd, const WString& originalText, TextPos inputStart, TextPos inputEnd, const WString& inputText)
{
textControl->CalculateView();
}
void GuiMultilineTextBox::TextElementOperatorCallback::ScrollToView(Point point)
{
point.x+=TextMargin;
point.y+=TextMargin;
Point oldPoint = textControl->GetViewPosition();
vint marginX=0;
vint marginY=0;
if(oldPoint.x<point.x)
{
marginX=TextMargin;
}
else if(oldPoint.x>point.x)
{
marginX=-TextMargin;
}
if(oldPoint.y<point.y)
{
marginY=TextMargin;
}
else if(oldPoint.y>point.y)
{
marginY=-TextMargin;
}
textControl->SetViewPosition(Point(point.x + marginX, point.y + marginY));
}
vint GuiMultilineTextBox::TextElementOperatorCallback::GetTextMargin()
{
return TextMargin;
}
/***********************************************************************
GuiMultilineTextBox::CommandExecutor
***********************************************************************/
GuiMultilineTextBox::CommandExecutor::CommandExecutor(GuiMultilineTextBox* _textBox)
:textBox(_textBox)
{
}
GuiMultilineTextBox::CommandExecutor::~CommandExecutor()
{
}
void GuiMultilineTextBox::CommandExecutor::UnsafeSetText(const WString& value)
{
textBox->UnsafeSetText(value);
}
/***********************************************************************
GuiMultilineTextBox
***********************************************************************/
void GuiMultilineTextBox::BeforeControlTemplateUninstalled_()
{
auto ct = TypedControlTemplateObject(false);
if (!ct) return;
ct->SetCommands(nullptr);
}
void GuiMultilineTextBox::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
Array<ColorEntry> colors(1);
colors[0] = ct->GetTextColor();
textElement->SetColors(colors);
textElement->SetCaretColor(ct->GetCaretColor());
ct->SetCommands(commandExecutor.Obj());
}
void GuiMultilineTextBox::UpdateVisuallyEnabled()
{
GuiControl::UpdateVisuallyEnabled();
textElement->SetVisuallyEnabled(GetVisuallyEnabled());
}
void GuiMultilineTextBox::UpdateDisplayFont()
{
GuiControl::UpdateDisplayFont();
textElement->SetFont(GetDisplayFont());
CalculateViewAndSetScroll();
}
void GuiMultilineTextBox::OnRenderTargetChanged(elements::IGuiGraphicsRenderTarget* renderTarget)
{
CalculateViewAndSetScroll();
GuiScrollView::OnRenderTargetChanged(renderTarget);
}
Size GuiMultilineTextBox::QueryFullSize()
{
TextLines& lines = textElement->GetLines();
return Size(lines.GetMaxWidth() + TextMargin * 2, lines.GetMaxHeight() + TextMargin * 2);
}
void GuiMultilineTextBox::UpdateView(Rect viewBounds)
{
textElement->SetViewPosition(viewBounds.LeftTop() - Size(TextMargin, TextMargin));
}
void GuiMultilineTextBox::CalculateViewAndSetScroll()
{
auto ct = TypedControlTemplateObject(true);
CalculateView();
vint smallMove = textElement->GetLines().GetRowHeight();
vint bigMove = smallMove * 5;
if (auto scroll = ct->GetHorizontalScroll())
{
scroll->SetSmallMove(smallMove);
scroll->SetBigMove(bigMove);
}
if (auto scroll = ct->GetVerticalScroll())
{
scroll->SetSmallMove(smallMove);
scroll->SetBigMove(bigMove);
}
}
void GuiMultilineTextBox::OnBoundsMouseButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if(GetVisuallyEnabled())
{
SetFocused();
}
}
GuiMultilineTextBox::GuiMultilineTextBox(theme::ThemeName themeName)
:GuiScrollView(themeName)
{
textElement = GuiColorizedTextElement::Create();
textElement->SetFont(GetDisplayFont());
textComposition = new GuiBoundsComposition;
textComposition->SetAlignmentToParent(Margin(0, 0, 0, 0));
textComposition->SetOwnedElement(Ptr(textElement));
containerComposition->AddChild(textComposition);
callback = Ptr(new TextElementOperatorCallback(this));
commandExecutor = Ptr(new CommandExecutor(this));
SetAcceptTabInput(true);
SetFocusableComposition(boundsComposition);
Install(textElement, textComposition, this, boundsComposition, focusableComposition);
SetCallback(callback.Obj());
boundsComposition->GetEventReceiver()->leftButtonDown.AttachMethod(this, &GuiMultilineTextBox::OnBoundsMouseButtonDown);
boundsComposition->GetEventReceiver()->middleButtonDown.AttachMethod(this, &GuiMultilineTextBox::OnBoundsMouseButtonDown);
boundsComposition->GetEventReceiver()->rightButtonDown.AttachMethod(this, &GuiMultilineTextBox::OnBoundsMouseButtonDown);
}
GuiMultilineTextBox::~GuiMultilineTextBox()
{
}
const WString& GuiMultilineTextBox::GetText()
{
text = textElement->GetLines().GetText();
return text;
}
void GuiMultilineTextBox::SetText(const WString& value)
{
UnsafeSetText(value);
textElement->SetCaretBegin(TextPos(0, 0));
textElement->SetCaretEnd(TextPos(0, 0));
CalculateView();
}
/***********************************************************************
GuiSinglelineTextBox::DefaultTextElementOperatorCallback
***********************************************************************/
GuiSinglelineTextBox::TextElementOperatorCallback::TextElementOperatorCallback(GuiSinglelineTextBox* _textControl)
:GuiTextBoxCommonInterface::DefaultCallback(
_textControl->textElement,
_textControl->textComposition
)
{
}
bool GuiSinglelineTextBox::TextElementOperatorCallback::BeforeModify(TextPos start, TextPos end, const WString& originalText, WString& inputText)
{
vint length = inputText.Length();
const wchar_t* input = inputText.Buffer();
for (vint i = 0; i < length; i++)
{
if (*input == 0 || *input == L'\r' || *input == L'\n')
{
length = i;
break;
}
}
if (length != inputText.Length())
{
if (length == 0)
{
// if the first line is empty after adjustment
// the input should just be canceled
// to prevent from making noise in undo
return false;
}
inputText = inputText.Left(length);
}
return true;
}
void GuiSinglelineTextBox::TextElementOperatorCallback::AfterModify(TextPos originalStart, TextPos originalEnd, const WString& originalText, TextPos inputStart, TextPos inputEnd, const WString& inputText)
{
}
void GuiSinglelineTextBox::TextElementOperatorCallback::ScrollToView(Point point)
{
vint newX=point.x;
vint oldX=textElement->GetViewPosition().x;
vint marginX=0;
if(oldX<newX)
{
marginX=TextMargin;
}
else if(oldX>newX)
{
marginX=-TextMargin;
}
newX+=marginX;
vint minX=-TextMargin;
vint maxX=textElement->GetLines().GetMaxWidth()+TextMargin-textComposition->GetCachedBounds().Width();
if(newX>=maxX)
{
newX=maxX-1;
}
if(newX<minX)
{
newX=minX;
}
textElement->SetViewPosition(Point(newX, -TextMargin));
}
vint GuiSinglelineTextBox::TextElementOperatorCallback::GetTextMargin()
{
return TextMargin;
}
/***********************************************************************
GuiSinglelineTextBox
***********************************************************************/
void GuiSinglelineTextBox::BeforeControlTemplateUninstalled_()
{
}
void GuiSinglelineTextBox::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
Array<ColorEntry> colors(1);
colors[0] = ct->GetTextColor();
textElement->SetColors(colors);
textElement->SetCaretColor(ct->GetCaretColor());
}
void GuiSinglelineTextBox::UpdateVisuallyEnabled()
{
GuiControl::UpdateVisuallyEnabled();
textElement->SetVisuallyEnabled(GetVisuallyEnabled());
}
void GuiSinglelineTextBox::UpdateDisplayFont()
{
GuiControl::UpdateDisplayFont();
textElement->SetFont(GetDisplayFont());
RearrangeTextElement();
}
void GuiSinglelineTextBox::RearrangeTextElement()
{
textCompositionTable->SetRowOption(
1,
GuiCellOption::AbsoluteOption(
textElement->GetLines().GetRowHeight() + 2 * TextMargin)
);
}
void GuiSinglelineTextBox::OnRenderTargetChanged(elements::IGuiGraphicsRenderTarget* renderTarget)
{
GuiControl::OnRenderTargetChanged(renderTarget);
RearrangeTextElement();
}
void GuiSinglelineTextBox::OnBoundsMouseButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
if(GetVisuallyEnabled())
{
SetFocused();
}
}
GuiSinglelineTextBox::GuiSinglelineTextBox(theme::ThemeName themeName)
:GuiControl(themeName)
{
textElement = GuiColorizedTextElement::Create();
textElement->SetFont(GetDisplayFont());
textElement->SetViewPosition(Point(-GuiSinglelineTextBox::TextMargin, -GuiSinglelineTextBox::TextMargin));
textCompositionTable = new GuiTableComposition;
textCompositionTable->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
textCompositionTable->SetAlignmentToParent(Margin(0, 0, 0, 0));
textCompositionTable->SetRowsAndColumns(3, 1);
textCompositionTable->SetRowOption(0, GuiCellOption::PercentageOption(0.5));
textCompositionTable->SetRowOption(1, GuiCellOption::AbsoluteOption(0));
textCompositionTable->SetRowOption(2, GuiCellOption::PercentageOption(0.5));
textCompositionTable->SetColumnOption(0, GuiCellOption::PercentageOption(1.0));
containerComposition->AddChild(textCompositionTable);
textComposition = new GuiCellComposition;
textComposition->SetOwnedElement(Ptr(textElement));
textCompositionTable->AddChild(textComposition);
textComposition->SetSite(1, 0, 1, 1);
callback = Ptr(new TextElementOperatorCallback(this));
SetAcceptTabInput(true);
SetFocusableComposition(boundsComposition);
Install(textElement, textComposition, this, boundsComposition, focusableComposition);
SetCallback(callback.Obj());
boundsComposition->GetEventReceiver()->leftButtonDown.AttachMethod(this, &GuiSinglelineTextBox::OnBoundsMouseButtonDown);
boundsComposition->GetEventReceiver()->middleButtonDown.AttachMethod(this, &GuiSinglelineTextBox::OnBoundsMouseButtonDown);
boundsComposition->GetEventReceiver()->rightButtonDown.AttachMethod(this, &GuiSinglelineTextBox::OnBoundsMouseButtonDown);
}
GuiSinglelineTextBox::~GuiSinglelineTextBox()
{
}
const WString& GuiSinglelineTextBox::GetText()
{
text = textElement->GetLines().GetText();
return text;
}
void GuiSinglelineTextBox::SetText(const WString& value)
{
UnsafeSetText(value);
textElement->SetCaretBegin(TextPos(0, 0));
textElement->SetCaretEnd(TextPos(0, 0));
}
wchar_t GuiSinglelineTextBox::GetPasswordChar()
{
return textElement->GetPasswordChar();
}
void GuiSinglelineTextBox::SetPasswordChar(wchar_t value)
{
textElement->SetPasswordChar(value);
}
}
}
}
/***********************************************************************
.\CONTROLS\TEXTEDITORPACKAGE\EDITORCALLBACK\GUITEXTAUTOCOMPLETE.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace collections;
/***********************************************************************
GuiTextBoxAutoCompleteBase::TextListControlProvider
***********************************************************************/
GuiTextBoxAutoCompleteBase::TextListControlProvider::TextListControlProvider(TemplateProperty<templates::GuiTextListTemplate> controlTemplate)
{
autoCompleteList = new GuiTextList(theme::ThemeName::TextList);
if (controlTemplate)
{
autoCompleteList->SetControlTemplate(controlTemplate);
}
autoCompleteList->SetHorizontalAlwaysVisible(false);
autoCompleteList->SetVerticalAlwaysVisible(false);
}
GuiTextBoxAutoCompleteBase::TextListControlProvider::~TextListControlProvider()
{
}
GuiControl* GuiTextBoxAutoCompleteBase::TextListControlProvider::GetAutoCompleteControl()
{
return autoCompleteList;
}
GuiSelectableListControl* GuiTextBoxAutoCompleteBase::TextListControlProvider::GetListControl()
{
return autoCompleteList;
}
void GuiTextBoxAutoCompleteBase::TextListControlProvider::SetSortedContent(const collections::List<AutoCompleteItem>& items)
{
autoCompleteList->GetItems().Clear();
for (auto item : items)
{
autoCompleteList->GetItems().Add(Ptr(new list::TextItem(item.text)));
}
}
vint GuiTextBoxAutoCompleteBase::TextListControlProvider::GetItemCount()
{
return autoCompleteList->GetItems().Count();
}
WString GuiTextBoxAutoCompleteBase::TextListControlProvider::GetItemText(vint index)
{
return autoCompleteList->GetItems()[index]->GetText();
}
/***********************************************************************
GuiTextBoxAutoCompleteBase
***********************************************************************/
bool GuiTextBoxAutoCompleteBase::IsPrefix(const WString& prefix, const WString& candidate)
{
if(candidate.Length()>=prefix.Length())
{
if(INVLOC.Compare(prefix, candidate.Sub(0, prefix.Length()), Locale::IgnoreCase)==0)
{
return true;
}
}
return false;
}
GuiTextBoxAutoCompleteBase::GuiTextBoxAutoCompleteBase(Ptr<IAutoCompleteControlProvider> _autoCompleteControlProvider)
:element(0)
, elementModifyLock(0)
, ownerComposition(0)
, autoCompleteControlProvider(_autoCompleteControlProvider)
{
if (!autoCompleteControlProvider)
{
autoCompleteControlProvider = Ptr(new TextListControlProvider);
}
autoCompleteControlProvider->GetAutoCompleteControl()->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
autoCompletePopup = new GuiPopup(theme::ThemeName::Menu);
autoCompletePopup->AddChild(autoCompleteControlProvider->GetAutoCompleteControl());
}
GuiTextBoxAutoCompleteBase::~GuiTextBoxAutoCompleteBase()
{
delete autoCompletePopup;
}
void GuiTextBoxAutoCompleteBase::Attach(elements::GuiColorizedTextElement* _element, SpinLock& _elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)
{
if(_element)
{
SPIN_LOCK(_elementModifyLock)
{
element=_element;
elementModifyLock=&_elementModifyLock;
ownerComposition=_ownerComposition;
}
}
}
void GuiTextBoxAutoCompleteBase::Detach()
{
if(element && elementModifyLock)
{
SPIN_LOCK(*elementModifyLock)
{
element=0;
elementModifyLock=0;
}
}
}
void GuiTextBoxAutoCompleteBase::TextEditPreview(TextEditPreviewStruct& arguments)
{
}
void GuiTextBoxAutoCompleteBase::TextEditNotify(const TextEditNotifyStruct& arguments)
{
if(element && elementModifyLock)
{
if(IsListOpening())
{
TextPos begin=GetListStartPosition();
TextPos end=arguments.inputEnd;
WString editingText=element->GetLines().GetText(begin, end);
HighlightList(editingText);
}
}
}
void GuiTextBoxAutoCompleteBase::TextCaretChanged(const TextCaretChangedStruct& arguments)
{
}
void GuiTextBoxAutoCompleteBase::TextEditFinished(vuint editVersion)
{
}
bool GuiTextBoxAutoCompleteBase::IsListOpening()
{
return autoCompletePopup->GetOpening();
}
void GuiTextBoxAutoCompleteBase::OpenList(TextPos startPosition)
{
if(element && elementModifyLock)
{
autoCompleteStartPosition=startPosition;
Rect bounds=element->GetLines().GetRectFromTextPos(startPosition);
Point viewPosition=element->GetViewPosition();
GuiControl* ownerControl=ownerComposition->GetRelatedControl();
Rect compositionBounds=ownerComposition->GetGlobalBounds();
Rect controlBounds=ownerControl->GetBoundsComposition()->GetGlobalBounds();
vint px=compositionBounds.x1-controlBounds.x1-viewPosition.x;
vint py=compositionBounds.y1-controlBounds.y1-viewPosition.y;
bounds.x1+=px;
bounds.x2+=px;
bounds.y1+=py+5;
bounds.y2+=py+5;
autoCompletePopup->ShowPopup(ownerControl, bounds, true);
}
}
void GuiTextBoxAutoCompleteBase::CloseList()
{
autoCompletePopup->Close();
}
void GuiTextBoxAutoCompleteBase::SetListContent(const collections::List<AutoCompleteItem>& items)
{
if(items.Count()==0)
{
CloseList();
}
List<AutoCompleteItem> sortedItems;
CopyFrom(
sortedItems,
From(items)
.OrderBy([](const AutoCompleteItem& a, const AutoCompleteItem& b)
{
return INVLOC.Compare(a.text, b.text, Locale::IgnoreCase) <=> 0;
})
);
autoCompleteControlProvider->SetSortedContent(sortedItems);
autoCompleteControlProvider->GetAutoCompleteControl()->GetBoundsComposition()->SetPreferredMinSize(Size(200, 200));
}
TextPos GuiTextBoxAutoCompleteBase::GetListStartPosition()
{
return autoCompleteStartPosition;
}
bool GuiTextBoxAutoCompleteBase::SelectPreviousListItem()
{
if(!IsListOpening()) return false;
if(autoCompleteControlProvider->GetListControl()->GetSelectedItems().Count()==0)
{
autoCompleteControlProvider->GetListControl()->SetSelected(0, true);
}
else
{
vint index=autoCompleteControlProvider->GetListControl()->GetSelectedItems()[0];
if (index > 0) index--;
autoCompleteControlProvider->GetListControl()->SetSelected(index, true);
autoCompleteControlProvider->GetListControl()->EnsureItemVisible(index);
}
return true;
}
bool GuiTextBoxAutoCompleteBase::SelectNextListItem()
{
if(!IsListOpening()) return false;
if (autoCompleteControlProvider->GetListControl()->GetSelectedItems().Count() == 0)
{
autoCompleteControlProvider->GetListControl()->SetSelected(0, true);
}
else
{
vint index = autoCompleteControlProvider->GetListControl()->GetSelectedItems()[0];
if (index < autoCompleteControlProvider->GetItemCount() - 1) index++;
autoCompleteControlProvider->GetListControl()->SetSelected(index, true);
autoCompleteControlProvider->GetListControl()->EnsureItemVisible(index);
}
return true;
}
bool GuiTextBoxAutoCompleteBase::ApplySelectedListItem()
{
if(!IsListOpening()) return false;
if(!ownerComposition) return false;
const auto& selectedItems = autoCompleteControlProvider->GetListControl()->GetSelectedItems();
if (selectedItems.Count() == 0) return false;
GuiTextBoxCommonInterface* ci=dynamic_cast<GuiTextBoxCommonInterface*>(ownerComposition->GetRelatedControl());
if(!ci) return false;
vint index = selectedItems[0];
WString selectedItem = autoCompleteControlProvider->GetItemText(index);
TextPos begin = autoCompleteStartPosition;
TextPos end = ci->GetCaretEnd();
ci->Select(begin, end);
ci->SetSelectionText(selectedItem);
CloseList();
return true;
}
WString GuiTextBoxAutoCompleteBase::GetSelectedListItem()
{
if(!IsListOpening()) return L"";
const auto& selectedItems = autoCompleteControlProvider->GetListControl()->GetSelectedItems();
if (selectedItems.Count() == 0) return L"";
vint index = selectedItems[0];
return autoCompleteControlProvider->GetItemText(index);
}
void GuiTextBoxAutoCompleteBase::HighlightList(const WString& editingText)
{
if(IsListOpening())
{
vint first=0;
vint last = autoCompleteControlProvider->GetItemCount() - 1;
vint selected=-1;
while (first <= last)
{
vint middle = (first + last) / 2;
WString text = autoCompleteControlProvider->GetItemText(middle);
if (IsPrefix(editingText, text))
{
selected = middle;
break;
}
vint result = INVLOC.Compare(editingText, text, Locale::IgnoreCase);
if (result <= 0)
{
last = middle - 1;
}
else
{
first = middle + 1;
}
}
while(selected>0)
{
WString text = autoCompleteControlProvider->GetItemText(selected - 1);
if (IsPrefix(editingText, text))
{
selected--;
}
else
{
break;
}
}
if(selected!=-1)
{
autoCompleteControlProvider->GetListControl()->SetSelected(selected, true);
autoCompleteControlProvider->GetListControl()->EnsureItemVisible(selected);
}
}
}
}
}
}
/***********************************************************************
.\CONTROLS\TEXTEDITORPACKAGE\EDITORCALLBACK\GUITEXTCOLORIZER.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace elements;
using namespace elements::text;
/***********************************************************************
GuiTextBoxColorizerBase
***********************************************************************/
void GuiTextBoxColorizerBase::ColorizerThreadProc(void* argument)
{
GuiTextBoxColorizerBase* colorizer=(GuiTextBoxColorizerBase*)argument;
while(!colorizer->isFinalizing)
{
vint lineIndex=-1;
wchar_t* text=0;
vuint32_t* colors=0;
vint length=0;
vint lexerState=-1;
vint contextState=-1;
SPIN_LOCK(*colorizer->elementModifyLock)
{
if(colorizer->colorizedLineCount>=colorizer->element->GetLines().GetCount())
{
colorizer->isColorizerRunning=false;
goto CANCEL_COLORIZING;
}
lineIndex=colorizer->colorizedLineCount++;
TextLine& line=colorizer->element->GetLines().GetLine(lineIndex);
length=line.dataLength;
text=new wchar_t[length+2];
colors=new vuint32_t[length+2];
memcpy(text, line.text, sizeof(wchar_t)*length);
text[length]=L'\r';
text[length+1]=L'\n';
lexerState=lineIndex==0?colorizer->GetLexerStartState():colorizer->element->GetLines().GetLine(lineIndex-1).lexerFinalState;
contextState=lineIndex==0?colorizer->GetContextStartState():colorizer->element->GetLines().GetLine(lineIndex-1).contextFinalState;
}
colorizer->ColorizeLineWithCRLF(lineIndex, text, colors, length+2, lexerState, contextState);
SPIN_LOCK(*colorizer->elementModifyLock)
{
if(lineIndex<colorizer->colorizedLineCount && lineIndex<colorizer->element->GetLines().GetCount())
{
TextLine& line=colorizer->element->GetLines().GetLine(lineIndex);
line.lexerFinalState=lexerState;
line.contextFinalState=contextState;
for(vint i=0;i<length;i++)
{
line.att[i].colorIndex=colors[i];
}
}
delete[] text;
delete[] colors;
}
}
CANCEL_COLORIZING:
colorizer->colorizerRunningEvent.Leave();
}
void GuiTextBoxColorizerBase::StartColorizer()
{
if(!isColorizerRunning)
{
isColorizerRunning=true;
colorizerRunningEvent.Enter();
ThreadPoolLite::Queue(&GuiTextBoxColorizerBase::ColorizerThreadProc, this);
}
}
void GuiTextBoxColorizerBase::StopColorizer(bool forever)
{
isFinalizing=true;
colorizerRunningEvent.Enter();
colorizerRunningEvent.Leave();
colorizedLineCount=0;
if(!forever)
{
isFinalizing=false;
}
}
void GuiTextBoxColorizerBase::StopColorizerForever()
{
StopColorizer(true);
}
GuiTextBoxColorizerBase::GuiTextBoxColorizerBase()
:element(0)
,elementModifyLock(0)
,colorizedLineCount(0)
,isColorizerRunning(false)
,isFinalizing(false)
{
}
GuiTextBoxColorizerBase::~GuiTextBoxColorizerBase()
{
StopColorizerForever();
}
void GuiTextBoxColorizerBase::Attach(elements::GuiColorizedTextElement* _element, SpinLock& _elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)
{
if(_element)
{
SPIN_LOCK(_elementModifyLock)
{
element=_element;
elementModifyLock=&_elementModifyLock;
StartColorizer();
}
}
}
void GuiTextBoxColorizerBase::Detach()
{
if(element && elementModifyLock)
{
StopColorizer(false);
SPIN_LOCK(*elementModifyLock)
{
element=0;
elementModifyLock=0;
}
}
}
void GuiTextBoxColorizerBase::TextEditPreview(TextEditPreviewStruct& arguments)
{
}
void GuiTextBoxColorizerBase::TextEditNotify(const TextEditNotifyStruct& arguments)
{
if(element && elementModifyLock)
{
SPIN_LOCK(*elementModifyLock)
{
vint line
=arguments.originalStart.row<arguments.originalEnd.row
?arguments.originalStart.row
:arguments.originalEnd.row;
if(colorizedLineCount>line)
{
colorizedLineCount=line;
}
StartColorizer();
}
}
}
void GuiTextBoxColorizerBase::TextCaretChanged(const TextCaretChangedStruct& arguments)
{
}
void GuiTextBoxColorizerBase::TextEditFinished(vuint editVersion)
{
}
void GuiTextBoxColorizerBase::RestartColorizer()
{
if(element && elementModifyLock)
{
SPIN_LOCK(*elementModifyLock)
{
colorizedLineCount=0;
StartColorizer();
}
}
}
/***********************************************************************
GuiTextBoxRegexColorizer
***********************************************************************/
struct GuiTextBoxRegexColorizerProcData
{
GuiTextBoxRegexColorizer* colorizer;
vint lineIndex;
const wchar_t* text;
vuint32_t* colors;
vint contextState;
};
void GuiTextBoxRegexColorizer::ColorizerProc(void* argument, vint start, vint length, vint token)
{
GuiTextBoxRegexColorizerProcData& data=**(GuiTextBoxRegexColorizerProcData**)argument;
data.colorizer->ColorizeTokenContextSensitive(data.lineIndex, data.text, start, length, token, data.contextState);
for(vint i=0;i<length;i++)
{
data.colors[start+i]=(int)token+1;
}
}
GuiTextBoxRegexColorizer::GuiTextBoxRegexColorizer()
{
colors.Resize(1);
}
GuiTextBoxRegexColorizer::~GuiTextBoxRegexColorizer()
{
StopColorizerForever();
}
elements::text::ColorEntry GuiTextBoxRegexColorizer::GetDefaultColor()
{
return defaultColor;
}
collections::List<WString>& GuiTextBoxRegexColorizer::GetTokenRegexes()
{
return tokenRegexes;
}
collections::List<elements::text::ColorEntry>& GuiTextBoxRegexColorizer::GetTokenColors()
{
return tokenColors;
}
collections::List<elements::text::ColorEntry>& GuiTextBoxRegexColorizer::GetExtraTokenColors()
{
return extraTokenColors;
}
vint GuiTextBoxRegexColorizer::GetExtraTokenIndexStart()
{
if(lexer)
{
return tokenColors.Count();
}
else
{
return -1;
}
}
bool GuiTextBoxRegexColorizer::SetDefaultColor(elements::text::ColorEntry value)
{
if(lexer)
{
return false;
}
else
{
defaultColor=value;
return true;
}
}
vint GuiTextBoxRegexColorizer::AddToken(const WString& regex, elements::text::ColorEntry color)
{
if(lexer)
{
return -1;
}
else
{
tokenRegexes.Add(regex);
tokenColors.Add(color);
return tokenColors.Count()-1;
}
}
vint GuiTextBoxRegexColorizer::AddExtraToken(elements::text::ColorEntry color)
{
if(lexer)
{
return -1;
}
else
{
extraTokenColors.Add(color);
return extraTokenColors.Count()-1;
}
}
void GuiTextBoxRegexColorizer::ClearTokens()
{
tokenRegexes.Clear();
tokenColors.Clear();
extraTokenColors.Clear();
lexer=0;
}
void GuiTextBoxRegexColorizer::Setup()
{
if (lexer || tokenRegexes.Count() == 0)
{
colors.Resize(1);
colors[0] = defaultColor;
}
else
{
lexer = Ptr(new regex::RegexLexer(tokenRegexes));
colors.Resize(1 + tokenRegexes.Count() + extraTokenColors.Count());
colors[0] = defaultColor;
for (vint i = 0; i < tokenColors.Count(); i++)
{
colors[i + 1] = tokenColors[i];
}
for (vint i = 0; i < extraTokenColors.Count(); i++)
{
colors[i + 1 + tokenColors.Count()] = extraTokenColors[i];
}
{
regex::RegexProc proc;
proc.colorizeProc = &GuiTextBoxRegexColorizer::ColorizerProc;
proc.argument = colorizerArgument;
colorizer = Ptr(new regex::RegexLexerColorizer(lexer->Colorize(proc)));
}
}
}
void GuiTextBoxRegexColorizer::ColorizeTokenContextSensitive(vint lineIndex, const wchar_t* text, vint start, vint length, vint& token, vint& contextState)
{
}
vint GuiTextBoxRegexColorizer::GetLexerStartState()
{
return lexer?colorizer->GetStartState():-1;
}
vint GuiTextBoxRegexColorizer::GetContextStartState()
{
return 0;
}
void GuiTextBoxRegexColorizer::ColorizeLineWithCRLF(vint lineIndex, const wchar_t* text, vuint32_t* colors, vint length, vint& lexerState, vint& contextState)
{
memset(colors, 0, sizeof(*colors)*length);
if (lexer)
{
GuiTextBoxRegexColorizerProcData data;
data.colorizer = this;
data.lineIndex = lineIndex;
data.text = text;
data.colors = colors;
data.contextState = contextState;
regex::RegexLexerColorizer::InternalState internalState;
internalState.currentState = lexerState;
colorizer->SetInternalState(internalState);
colorizerArgument[0] = &data;
colorizer->Colorize(text, length);
lexerState = colorizer->GetInternalState().currentState;
contextState = data.contextState;
}
else
{
lexerState = -1;
contextState = -1;
}
}
const GuiTextBoxRegexColorizer::ColorArray& GuiTextBoxRegexColorizer::GetColors()
{
return colors;
}
}
}
}
/***********************************************************************
.\CONTROLS\TEXTEDITORPACKAGE\EDITORCALLBACK\GUITEXTUNDOREDO.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace elements;
using namespace elements::text;
using namespace compositions;
/***********************************************************************
GuiGeneralUndoRedoProcessor
***********************************************************************/
GuiGeneralUndoRedoProcessor::GuiGeneralUndoRedoProcessor()
:firstFutureStep(0)
,savedStep(0)
,performingUndoRedo(false)
{
}
GuiGeneralUndoRedoProcessor::~GuiGeneralUndoRedoProcessor()
{
}
void GuiGeneralUndoRedoProcessor::PushStep(Ptr<IEditStep> step)
{
if(!performingUndoRedo)
{
if(firstFutureStep<savedStep)
{
savedStep=-1;
}
vint count=steps.Count()-firstFutureStep;
if(count>0)
{
steps.RemoveRange(firstFutureStep, count);
}
steps.Add(step);
firstFutureStep=steps.Count();
UndoRedoChanged();
ModifiedChanged();
}
}
bool GuiGeneralUndoRedoProcessor::CanUndo()
{
return firstFutureStep>0;
}
bool GuiGeneralUndoRedoProcessor::CanRedo()
{
return steps.Count()>firstFutureStep;
}
void GuiGeneralUndoRedoProcessor::ClearUndoRedo()
{
if(!performingUndoRedo)
{
steps.Clear();
firstFutureStep=0;
savedStep=0;
}
}
bool GuiGeneralUndoRedoProcessor::GetModified()
{
return firstFutureStep!=savedStep;
}
void GuiGeneralUndoRedoProcessor::NotifyModificationSaved()
{
if(!performingUndoRedo)
{
savedStep=firstFutureStep;
ModifiedChanged();
}
}
bool GuiGeneralUndoRedoProcessor::Undo()
{
if(!CanUndo()) return false;
performingUndoRedo=true;
firstFutureStep--;
steps[firstFutureStep]->Undo();
performingUndoRedo=false;
UndoRedoChanged();
ModifiedChanged();
return true;
}
bool GuiGeneralUndoRedoProcessor::Redo()
{
if(!CanRedo()) return false;
performingUndoRedo=true;
firstFutureStep++;
steps[firstFutureStep-1]->Redo();
performingUndoRedo=false;
UndoRedoChanged();
ModifiedChanged();
return true;
}
/***********************************************************************
GuiTextBoxUndoRedoProcessor::EditStep
***********************************************************************/
void GuiTextBoxUndoRedoProcessor::EditStep::Undo()
{
GuiTextBoxCommonInterface* ci=dynamic_cast<GuiTextBoxCommonInterface*>(processor->ownerComposition->GetRelatedControl());
if(ci)
{
ci->Select(arguments.inputStart, arguments.inputEnd);
ci->SetSelectionText(arguments.originalText);
ci->Select(arguments.originalStart, arguments.originalEnd);
}
}
void GuiTextBoxUndoRedoProcessor::EditStep::Redo()
{
GuiTextBoxCommonInterface* ci=dynamic_cast<GuiTextBoxCommonInterface*>(processor->ownerComposition->GetRelatedControl());
if(ci)
{
ci->Select(arguments.originalStart, arguments.originalEnd);
ci->SetSelectionText(arguments.inputText);
ci->Select(arguments.inputStart, arguments.inputEnd);
}
}
/***********************************************************************
GuiTextBoxUndoRedoProcessor
***********************************************************************/
GuiTextBoxUndoRedoProcessor::GuiTextBoxUndoRedoProcessor()
:ownerComposition(0)
{
}
GuiTextBoxUndoRedoProcessor::~GuiTextBoxUndoRedoProcessor()
{
}
void GuiTextBoxUndoRedoProcessor::Attach(elements::GuiColorizedTextElement* element, SpinLock& elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)
{
ownerComposition=_ownerComposition;
}
void GuiTextBoxUndoRedoProcessor::Detach()
{
ClearUndoRedo();
}
void GuiTextBoxUndoRedoProcessor::TextEditPreview(TextEditPreviewStruct& arguments)
{
}
void GuiTextBoxUndoRedoProcessor::TextEditNotify(const TextEditNotifyStruct& arguments)
{
auto step=Ptr(new EditStep);
step->processor=this;
step->arguments=arguments;
PushStep(step);
}
void GuiTextBoxUndoRedoProcessor::TextCaretChanged(const TextCaretChangedStruct& arguments)
{
}
void GuiTextBoxUndoRedoProcessor::TextEditFinished(vuint editVersion)
{
}
/***********************************************************************
GuiDocumentUndoRedoProcessor::ReplaceModelStep
***********************************************************************/
void GuiDocumentUndoRedoProcessor::ReplaceModelStep::Undo()
{
GuiDocumentCommonInterface* ci=dynamic_cast<GuiDocumentCommonInterface*>(processor->ownerComposition->GetRelatedControl());
if(ci)
{
ci->EditRun(arguments.inputStart, arguments.inputEnd, arguments.originalModel, true);
ci->SetCaret(arguments.originalStart, arguments.originalEnd);
}
}
void GuiDocumentUndoRedoProcessor::ReplaceModelStep::Redo()
{
GuiDocumentCommonInterface* ci=dynamic_cast<GuiDocumentCommonInterface*>(processor->ownerComposition->GetRelatedControl());
if(ci)
{
ci->EditRun(arguments.originalStart, arguments.originalEnd, arguments.inputModel, true);
ci->SetCaret(arguments.inputStart, arguments.inputEnd);
}
}
/***********************************************************************
GuiDocumentUndoRedoProcessor::RenameStyleStep
***********************************************************************/
void GuiDocumentUndoRedoProcessor::RenameStyleStep::Undo()
{
GuiDocumentCommonInterface* ci=dynamic_cast<GuiDocumentCommonInterface*>(processor->ownerComposition->GetRelatedControl());
if(ci)
{
ci->RenameStyle(arguments.newStyleName, arguments.oldStyleName);
}
}
void GuiDocumentUndoRedoProcessor::RenameStyleStep::Redo()
{
GuiDocumentCommonInterface* ci=dynamic_cast<GuiDocumentCommonInterface*>(processor->ownerComposition->GetRelatedControl());
if(ci)
{
ci->RenameStyle(arguments.oldStyleName, arguments.newStyleName);
}
}
/***********************************************************************
GuiDocumentUndoRedoProcessor::SetAlignmentStep
***********************************************************************/
void GuiDocumentUndoRedoProcessor::SetAlignmentStep::Undo()
{
GuiDocumentCommonInterface* ci=dynamic_cast<GuiDocumentCommonInterface*>(processor->ownerComposition->GetRelatedControl());
if(ci)
{
ci->SetParagraphAlignments(TextPos(arguments->start, 0), TextPos(arguments->end, 0), arguments->originalAlignments);
}
}
void GuiDocumentUndoRedoProcessor::SetAlignmentStep::Redo()
{
GuiDocumentCommonInterface* ci=dynamic_cast<GuiDocumentCommonInterface*>(processor->ownerComposition->GetRelatedControl());
if(ci)
{
ci->SetParagraphAlignments(TextPos(arguments->start, 0), TextPos(arguments->end, 0), arguments->inputAlignments);
}
}
/***********************************************************************
GuiDocumentUndoRedoProcessor
***********************************************************************/
GuiDocumentUndoRedoProcessor::GuiDocumentUndoRedoProcessor()
:element(0)
,ownerComposition(0)
{
}
GuiDocumentUndoRedoProcessor::~GuiDocumentUndoRedoProcessor()
{
}
void GuiDocumentUndoRedoProcessor::Setup(elements::GuiDocumentElement* _element, compositions::GuiGraphicsComposition* _ownerComposition)
{
element=_element;
ownerComposition=_ownerComposition;
}
void GuiDocumentUndoRedoProcessor::OnReplaceModel(const ReplaceModelStruct& arguments)
{
auto step=Ptr(new ReplaceModelStep);
step->processor=this;
step->arguments=arguments;
PushStep(step);
}
void GuiDocumentUndoRedoProcessor::OnRenameStyle(const RenameStyleStruct& arguments)
{
auto step=Ptr(new RenameStyleStep);
step->processor=this;
step->arguments=arguments;
PushStep(step);
}
void GuiDocumentUndoRedoProcessor::OnSetAlignment(Ptr<SetAlignmentStruct> arguments)
{
auto step=Ptr(new SetAlignmentStep);
step->processor=this;
step->arguments=arguments;
PushStep(step);
}
}
}
}
/***********************************************************************
.\CONTROLS\TEXTEDITORPACKAGE\LANGUAGESERVICE\GUILANGUAGEAUTOCOMPLETE.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace elements;
using namespace regex;
using namespace parsing;
using namespace parsing::tabling;
using namespace collections;
/***********************************************************************
GuiGrammarAutoComplete
***********************************************************************/
void GuiGrammarAutoComplete::Attach(elements::GuiColorizedTextElement* _element, SpinLock& _elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)
{
GuiTextBoxAutoCompleteBase::Attach(_element, _elementModifyLock, _ownerComposition, editVersion);
RepeatingParsingExecutor::CallbackBase::Attach(_element, _elementModifyLock, _ownerComposition, editVersion);
}
void GuiGrammarAutoComplete::Detach()
{
GuiTextBoxAutoCompleteBase::Detach();
RepeatingParsingExecutor::CallbackBase::Detach();
if(element && elementModifyLock)
{
EnsureAutoCompleteFinished();
}
}
void GuiGrammarAutoComplete::TextEditPreview(TextEditPreviewStruct& arguments)
{
GuiTextBoxAutoCompleteBase::TextEditPreview(arguments);
RepeatingParsingExecutor::CallbackBase::TextEditPreview(arguments);
if(element && elementModifyLock)
{
if(IsListOpening() && arguments.keyInput && arguments.originalText==L"" && arguments.inputText!=L"")
{
WString selectedItem=GetSelectedListItem();
if(selectedItem!=L"")
{
TextPos begin=GetListStartPosition();
TextPos end=arguments.originalStart;
WString editingText=element->GetLines().GetText(begin, end);
editingText+=arguments.inputText;
if(grammarParser->GetTable()->GetLexer().Walk().IsClosedToken(editingText))
{
arguments.originalStart=begin;
arguments.inputText=selectedItem+arguments.inputText;
CloseList();
}
}
}
}
}
void GuiGrammarAutoComplete::TextEditNotify(const TextEditNotifyStruct& arguments)
{
GuiTextBoxAutoCompleteBase::TextEditNotify(arguments);
RepeatingParsingExecutor::CallbackBase::TextEditNotify(arguments);
if(element && elementModifyLock)
{
editing=true;
SPIN_LOCK(editTraceLock)
{
editTrace.Add(arguments);
}
}
}
void GuiGrammarAutoComplete::TextCaretChanged(const TextCaretChangedStruct& arguments)
{
GuiTextBoxAutoCompleteBase::TextCaretChanged(arguments);
RepeatingParsingExecutor::CallbackBase::TextCaretChanged(arguments);
if(element && elementModifyLock)
{
SPIN_LOCK(editTraceLock)
{
// queue a fake TextEditNotifyStruct
// a fake struct can be detected by (trace.originalText==L"" && trace.inputText==L"")
TextEditNotifyStruct trace;
trace.editVersion=arguments.editVersion;
trace.originalStart=arguments.oldBegin;
trace.originalEnd=arguments.oldEnd;
trace.inputStart=arguments.newBegin;
trace.inputEnd=arguments.newEnd;
// ensure trace.originalStart<=trace.originalEnd
if(trace.originalStart>trace.originalEnd)
{
TextPos temp=trace.originalStart;
trace.originalStart=trace.originalEnd;
trace.originalEnd=temp;
}
// ensure trace.inputStart<=trace.inputEnd
if(trace.inputStart>trace.inputEnd)
{
TextPos temp=trace.inputStart;
trace.inputStart=trace.inputEnd;
trace.inputEnd=temp;
}
editTrace.Add(trace);
}
SPIN_LOCK(contextLock)
{
if(context.input.node)
{
if(editing)
{
// if the current caret changing is caused by editing
// submit a task with valid editVersion and invalid node and code
RepeatingParsingOutput input;
input.editVersion=context.input.editVersion;
SubmitTask(input);
}
else if(context.input.editVersion == arguments.editVersion)
{
// if the current caret changing is not caused by editing
// submit a task with the previous input
SubmitTask(context.input);
}
}
}
}
}
void GuiGrammarAutoComplete::TextEditFinished(vuint editVersion)
{
GuiTextBoxAutoCompleteBase::TextEditFinished(editVersion);
RepeatingParsingExecutor::CallbackBase::TextEditFinished(editVersion);
if(element && elementModifyLock)
{
editing=false;
}
}
void GuiGrammarAutoComplete::OnParsingFinishedAsync(const RepeatingParsingOutput& arguments)
{
if(element && elementModifyLock)
{
GetApplication()->InvokeInMainThread(ownerComposition->GetRelatedControlHost(), [=]()
{
// submit a task if the RepeatingParsingExecutor notices a new parsing result
SubmitTask(arguments);
});
}
}
void GuiGrammarAutoComplete::CollectLeftRecursiveRules()
{
leftRecursiveRules.Clear();
Ptr<ParsingGeneralParser> parser=parsingExecutor->GetParser();
Ptr<ParsingTable> table=parser->GetTable();
vint stateCount=table->GetStateCount();
vint tokenCount=table->GetTokenCount();
for(vint i=0;i<stateCount;i++)
{
for(vint j=0;j<tokenCount;j++)
{
Ptr<ParsingTable::TransitionBag> bag=table->GetTransitionBag(i, j);
if(bag)
{
for (auto item : bag->transitionItems)
{
for (auto ins : item->instructions)
{
if(ins.instructionType==ParsingTable::Instruction::LeftRecursiveReduce)
{
if(!leftRecursiveRules.Contains(ins.creatorRule))
{
leftRecursiveRules.Add(ins.creatorRule);
}
}
}
}
}
}
}
}
vint GuiGrammarAutoComplete::UnsafeGetEditTraceIndex(vuint editVersion)
{
// get the index of the latest TextEditNotifyStruct of a specified edit version
// this function should be called inside SPIN_LOCK(editTraceLock)
// perform a binary search
vint start = 0;
vint end = editTrace.Count() - 1;
while (start <= end)
{
vint middle = (start + end) / 2;
TextEditNotifyStruct& trace = editTrace[middle];
if (editVersion<trace.editVersion)
{
end = middle - 1;
}
else if (editVersion>trace.editVersion)
{
start = middle + 1;
}
else
{
// if multiple TextEditNotifyStruct is found, choose the latest one
while (middle < editTrace.Count() - 1)
{
if (editTrace[middle + 1].editVersion == editTrace[middle].editVersion)
{
middle++;
}
else
{
break;
}
}
return middle;
}
}
return -1;
}
TextPos GuiGrammarAutoComplete::ChooseCorrectTextPos(TextPos pos, const regex::RegexTokens& tokens)
{
Ptr<ParsingTable> table=grammarParser->GetTable();
RegexToken lastToken;
lastToken.reading=0;
for (auto token : tokens)
{
// we treat "class| Name" as editing the first token
if(TextPos(token.rowEnd, token.columnEnd+1)>=pos)
{
if(table->GetTableTokenIndex(token.token)!=-1 && lastToken.reading)
{
pos=TextPos(lastToken.rowStart, lastToken.columnStart);
}
break;
}
lastToken=token;
}
return pos;
}
void GuiGrammarAutoComplete::ExecuteRefresh(AutoCompleteContext& newContext)
{
// process the input of a task is submitted not by text editing
// find the text selection by the edit version of the input
TextPos startPos, endPos;
{
SPIN_LOCK(editTraceLock)
{
vint traceIndex = UnsafeGetEditTraceIndex(newContext.input.editVersion);
if (traceIndex == -1) return;
TextEditNotifyStruct& trace = editTrace[traceIndex];
startPos = trace.inputStart;
endPos = trace.inputEnd;
}
const RegexLexer& lexer = grammarParser->GetTable()->GetLexer();
RegexTokens tokens = lexer.Parse(newContext.input.code);
startPos = ChooseCorrectTextPos(startPos, tokens);
}
// locate the deepest node using the text selection
ParsingTextPos start(startPos.row, startPos.column);
ParsingTextPos end(endPos.row, endPos.column);
ParsingTextRange range(start, end);
ParsingTreeNode* found = newContext.input.node->FindDeepestNode(range);
ParsingTreeObject* selectedNode = 0;
// if the location failed, choose the root node
if (!found || startPos == TextPos(0, 0))
{
found = newContext.input.node.Obj();
}
if (!selectedNode)
{
// from the deepest node, traverse towards the root node
// find the deepest node whose created rule is a left recursive rule and whose parent is not
ParsingTreeObject* lrec = 0;
ParsingTreeNode* current = found;
while (current)
{
ParsingTreeObject* obj = dynamic_cast<ParsingTreeObject*>(current);
if (obj)
{
for (auto rule : obj->GetCreatorRules())
{
if (leftRecursiveRules.Contains(rule))
{
lrec = obj;
break;
}
}
if (obj && lrec && lrec != obj)
{
selectedNode = lrec;
break;
}
}
current = current->GetParent();
}
}
if (!selectedNode)
{
// if there is no left recursive rule that creates the deepest node and all indirect parents
// choose the deepest ParsingTreeObject
ParsingTreeNode* current = found;
while (current)
{
ParsingTreeObject* obj = dynamic_cast<ParsingTreeObject*>(current);
if (obj)
{
selectedNode = obj;
break;
}
current = current->GetParent();
}
}
if (selectedNode)
{
// get the code range of the selected node
start = selectedNode->GetCodeRange().start;
end = selectedNode->GetCodeRange().end;
// get all properties from the selected node
newContext.rule = selectedNode->GetCreatorRules()[selectedNode->GetCreatorRules().Count() - 1];
newContext.originalRange = selectedNode->GetCodeRange();
newContext.originalNode = Ptr(selectedNode);
newContext.modifiedNode = newContext.originalNode;
newContext.modifiedEditVersion = newContext.input.editVersion;
// get the corresponding code of the selected node
if (start.index >= 0 && end.index >= 0)
{
newContext.modifiedCode = newContext.input.code.Sub(start.index, end.index - start.index + 1).Buffer();
}
}
}
bool GuiGrammarAutoComplete::NormalizeTextPos(AutoCompleteContext& newContext, elements::text::TextLines& lines, TextPos& pos)
{
// get the start position
TextPos start(newContext.originalRange.start.row, newContext.originalRange.start.column);
// get the end position of the end of lines
TextPos end
= lines.GetCount() <= 1
? TextPos(start.row, start.column + lines.GetLine(0).dataLength)
: TextPos(start.row + lines.GetCount() - 1, lines.GetLine(lines.GetCount() - 1).dataLength)
;
if (start <= pos && pos <= end)
{
// if the pos is inside the range
// normalize the pos to a new coordinate that the beginning position of lines is (row=0, column=0)
pos.row -= start.row;
if (pos.row == 0)
{
pos.column -= start.column;
}
return true;
}
else
{
return false;
}
}
void GuiGrammarAutoComplete::ExecuteEdit(AutoCompleteContext& newContext)
{
// process the input of a task that is submitted by text editing
// this function make an approximiation to the context if the RepeatingParsingExecutor is not fast enough
// copy all TextEditNotifyStruct that is caused by a text editing before (and including) the edit version of the input
List<TextEditNotifyStruct> usedTrace;
{
SPIN_LOCK(editTraceLock)
{
CopyFrom(
usedTrace,
From(editTrace)
.Where([&newContext](const TextEditNotifyStruct& value)
{
return (value.originalText != L"" || value.inputText != L"") && value.editVersion > newContext.modifiedEditVersion;
})
);
}
}
// apply all modification to get the new modifiedCode
bool failed = false;
if (usedTrace.Count() > 0)
{
if (usedTrace[0].editVersion != newContext.modifiedEditVersion + 1)
{
// failed if any TextEditNotifyStruct is missing
failed = true;
}
else
{
// initialize a TextLines with the latest modifiedCode
text::TextLines lines(nullptr);
lines.SetText(newContext.modifiedCode);
for (auto trace : usedTrace)
{
// apply a modification to lines
TextPos start = trace.originalStart;
TextPos end = trace.originalEnd;
// only if the modification is meaningful
if (NormalizeTextPos(newContext, lines, start) && NormalizeTextPos(newContext, lines, end))
{
lines.Modify(start, end, trace.inputText);
}
else
{
// otherwise, failed
failed = true;
break;
}
}
if (!failed)
{
newContext.modifiedCode = lines.GetText();
}
}
}
if (failed)
{
// clear originalNode to notify that the current context goes wrong
newContext.originalNode = 0;
}
if (usedTrace.Count() > 0)
{
// update the edit version
newContext.modifiedEditVersion = usedTrace[usedTrace.Count() - 1].editVersion;
}
}
void GuiGrammarAutoComplete::DeleteFutures(collections::List<parsing::tabling::ParsingState::Future*>& futures)
{
// delete all futures and clear the list
for (auto future : futures)
{
delete future;
}
futures.Clear();
}
regex::RegexToken* GuiGrammarAutoComplete::TraverseTransitions(
parsing::tabling::ParsingState& state,
parsing::tabling::ParsingTransitionCollector& transitionCollector,
TextPos stopPosition,
collections::List<parsing::tabling::ParsingState::Future*>& nonRecoveryFutures,
collections::List<parsing::tabling::ParsingState::Future*>& recoveryFutures
)
{
const List<ParsingState::TransitionResult>& transitions = transitionCollector.GetTransitions();
for (vint index = 0; index < transitions.Count(); index++)
{
const ParsingState::TransitionResult& transition = transitions[index];
switch (transition.transitionType)
{
case ParsingState::TransitionResult::AmbiguityBegin:
break;
case ParsingState::TransitionResult::AmbiguityBranch:
// ambiguity branches are not nested
// tokens in different braches are the same
// so we only need to run one branch, and skip the others
index = transitionCollector.GetAmbiguityEndFromBegin(transitionCollector.GetAmbiguityBeginFromBranch(index));
break;
case ParsingState::TransitionResult::AmbiguityEnd:
break;
case ParsingState::TransitionResult::ExecuteInstructions:
{
// test does the token reach the stop position
if (transition.token)
{
// we treat "A|B" as editing A if token A is endless, otherwise treated as editing B
TextPos tokenEnd(transition.token->rowEnd, transition.token->columnEnd + 1);
// if the caret is not at the end of the token
if (tokenEnd > stopPosition)
{
// stop the traversing and return the editing token
return transition.token;
}
else if (tokenEnd == stopPosition)
{
// if the caret is at the end of the token, and it is a closed token
// e.g. identifier is not a closed token, string is a closed token
if (!grammarParser->GetTable()->GetLexer().Walk().IsClosedToken(transition.token->reading, transition.token->length))
{
// stop the traversing and return the editing token
return transition.token;
}
}
}
// traverse the PDA using the token specified in the current transition
vint tableTokenIndex = transition.tableTokenIndex;
List<ParsingState::Future*> possibilities;
if (recoveryFutures.Count() > 0)
{
for (auto future : recoveryFutures)
{
state.Explore(tableTokenIndex, future, possibilities);
}
}
else
{
for (auto future : nonRecoveryFutures)
{
state.Explore(tableTokenIndex, future, possibilities);
}
}
// delete duplicated futures
List<ParsingState::Future*> selectedPossibilities;
for (vint i = 0; i < possibilities.Count(); i++)
{
ParsingState::Future* candidateFuture = possibilities[i];
bool duplicated = false;
for (auto future : selectedPossibilities)
{
if (
candidateFuture->currentState == future->currentState &&
candidateFuture->reduceStateCount == future->reduceStateCount &&
candidateFuture->shiftStates.Count() == future->shiftStates.Count()
)
{
bool same = true;
for (vint j = 0; j < future->shiftStates.Count(); j++)
{
if (candidateFuture->shiftStates[i] != future->shiftStates[i])
{
same = false;
break;
}
}
if ((duplicated = same))
{
break;
}
}
}
if (duplicated)
{
delete candidateFuture;
}
else
{
selectedPossibilities.Add(candidateFuture);
}
}
// step forward
if (transition.token || transition.tableTokenIndex == ParsingTable::TokenBegin)
{
DeleteFutures(nonRecoveryFutures);
DeleteFutures(recoveryFutures);
CopyFrom(nonRecoveryFutures, selectedPossibilities);
}
else
{
DeleteFutures(recoveryFutures);
CopyFrom(recoveryFutures, selectedPossibilities);
}
}
break;
default:;
}
}
return 0;
}
regex::RegexToken* GuiGrammarAutoComplete::SearchValidInputToken(
parsing::tabling::ParsingState& state,
parsing::tabling::ParsingTransitionCollector& transitionCollector,
TextPos stopPosition,
AutoCompleteContext& newContext,
collections::SortedList<vint>& tableTokenIndices
)
{
// initialize the PDA state
state.Reset(newContext.rule);
List<ParsingState::Future*> nonRecoveryFutures, recoveryFutures;
nonRecoveryFutures.Add(state.ExploreCreateRootFuture());
// traverse the PDA until it reach the stop position
// nonRecoveryFutures store the state when the last token (existing) is reached
// recoveryFutures store the state when the last token (inserted by error recovery) is reached
RegexToken* token = TraverseTransitions(state, transitionCollector, stopPosition, nonRecoveryFutures, recoveryFutures);
// explore all possibilities from the last token before the stop position
List<ParsingState::Future*> possibilities;
for (vint i = 0; i < nonRecoveryFutures.Count(); i++)
{
state.Explore(ParsingTable::NormalReduce, nonRecoveryFutures[i], nonRecoveryFutures);
state.Explore(ParsingTable::LeftRecursiveReduce, nonRecoveryFutures[i], nonRecoveryFutures);
}
for (auto future : nonRecoveryFutures)
{
vint count = state.GetTable()->GetTokenCount();
for (vint i = ParsingTable::UserTokenStart; i < count; i++)
{
state.Explore(i, future, possibilities);
}
}
// get all possible tokens that marked using @AutoCompleteCandidate
for (auto future : possibilities)
{
if (!tableTokenIndices.Contains(future->selectedToken))
{
tableTokenIndices.Add(future->selectedToken);
}
}
// release all data
DeleteFutures(possibilities);
DeleteFutures(nonRecoveryFutures);
DeleteFutures(recoveryFutures);
// return the editing token
return token;
}
TextPos GuiGrammarAutoComplete::GlobalTextPosToModifiedTextPos(AutoCompleteContext& newContext, TextPos pos)
{
pos.row-=newContext.originalRange.start.row;
if(pos.row==0)
{
pos.column-=newContext.originalRange.start.column;
}
return pos;
}
TextPos GuiGrammarAutoComplete::ModifiedTextPosToGlobalTextPos(AutoCompleteContext& newContext, TextPos pos)
{
if(pos.row==0)
{
pos.column+=newContext.originalRange.start.column;
}
pos.row+=newContext.originalRange.start.row;
return pos;
}
void GuiGrammarAutoComplete::ExecuteCalculateList(AutoCompleteContext& newContext)
{
// calcuate the content of the auto complete list
// it is sad that, because the parser's algorithm is too complex
// we need to reparse and track the internal state of the PDA(push-down automaton) here.
// initialize the PDA
ParsingState state(newContext.modifiedCode, grammarParser->GetTable());
state.Reset(newContext.rule);
// prepare to get all transitions
ParsingTransitionCollector collector;
List<Ptr<ParsingError>> errors;
// reparse and get all transitions during parsing
if (grammarParser->Parse(state, collector, errors))
{
// if modifiedNode is not prepared (the task is submitted because of text editing)
// use the transition to build the syntax tree
if (!newContext.modifiedNode)
{
ParsingTreeBuilder builder;
builder.Reset();
bool succeeded = true;
for (auto transition : collector.GetTransitions())
{
if (!(succeeded = builder.Run(transition)))
{
break;
}
}
if (succeeded)
{
Ptr<ParsingTreeNode> parsedNode = builder.GetNode();
newContext.modifiedNode = parsedNode.Cast<ParsingTreeObject>();
newContext.modifiedNode->InitializeQueryCache();
}
}
if (newContext.modifiedNode)
{
// get the latest text editing trace
TextEditNotifyStruct trace;
SPIN_LOCK(editTraceLock)
{
vint index = UnsafeGetEditTraceIndex(newContext.modifiedEditVersion);
if (index == -1)
{
return;
}
else
{
trace = editTrace[index];
}
}
// calculate the stop position for PDA traversing
TextPos stopPosition = GlobalTextPosToModifiedTextPos(newContext, trace.inputStart);
// find all possible token before the current caret using the PDA
auto autoComplete = Ptr(new AutoCompleteData);
SortedList<vint> tableTokenIndices;
RegexToken* editingToken = SearchValidInputToken(state, collector, stopPosition, newContext, tableTokenIndices);
// collect all auto complete types
{
// collect all keywords that can be put into the auto complete list
for (auto token : tableTokenIndices)
{
vint regexToken = token - ParsingTable::UserTokenStart;
if (regexToken >= 0)
{
autoComplete->candidates.Add(regexToken);
if (parsingExecutor->GetTokenMetaData(regexToken).isCandidate)
{
autoComplete->shownCandidates.Add(regexToken);
}
}
}
// calculate the arranged stopPosition
if (editingToken)
{
TextPos tokenPos(editingToken->rowStart, editingToken->columnStart);
if (tokenPos < stopPosition)
{
stopPosition = tokenPos;
}
}
// calculate the start/end position for PDA traversing
TextPos startPos, endPos;
{
startPos = ModifiedTextPosToGlobalTextPos(newContext, stopPosition);
autoComplete->startPosition = startPos;
endPos = trace.inputEnd;
if (newContext.modifiedNode != newContext.originalNode)
{
startPos = GlobalTextPosToModifiedTextPos(newContext, startPos);
endPos = GlobalTextPosToModifiedTextPos(newContext, endPos);
}
if (startPos<endPos && endPos.column>0)
{
endPos.column--;
}
}
// calculate the auto complete type
if (editingToken && parsingExecutor->GetTokenMetaData(editingToken->token).hasAutoComplete)
{
ParsingTextRange range(ParsingTextPos(startPos.row, startPos.column), ParsingTextPos(endPos.row, endPos.column));
AutoCompleteData::RetriveContext(*autoComplete.Obj(), range, newContext.modifiedNode.Obj(), parsingExecutor.Obj());
}
}
newContext.autoComplete = autoComplete;
}
}
}
void GuiGrammarAutoComplete::Execute(const RepeatingParsingOutput& input)
{
SPIN_LOCK(contextLock)
{
if(input.editVersion<context.input.editVersion)
{
return;
}
}
AutoCompleteContext newContext;
bool byGlobalCorrection=false;
if(input.node)
{
newContext.input=input;
ExecuteRefresh(newContext);
byGlobalCorrection=true;
}
else
{
SPIN_LOCK(contextLock)
{
newContext=context;
newContext.modifiedNode=0;
newContext.autoComplete=0;
}
if(newContext.originalNode)
{
ExecuteEdit(newContext);
}
}
if(newContext.originalNode)
{
ExecuteCalculateList(newContext);
}
SPIN_LOCK(contextLock)
{
context=newContext;
}
if(newContext.modifiedNode)
{
OnContextFinishedAsync(context);
GetApplication()->InvokeInMainThread(ownerComposition->GetRelatedControlHost(), [=]()
{
PostList(newContext, byGlobalCorrection);
});
}
}
void GuiGrammarAutoComplete::PostList(const AutoCompleteContext& newContext, bool byGlobalCorrection)
{
bool openList = true; // true: make the list visible
bool keepListState = false; // true: don't change the list visibility
Ptr<AutoCompleteData> autoComplete = newContext.autoComplete;
// if failed to get the auto complete list, close
if (!autoComplete)
{
openList = false;
}
if (openList)
{
if (autoComplete->shownCandidates.Count() + autoComplete->candidateItems.Count() == 0)
{
openList = false;
}
}
TextPos startPosition, endPosition;
WString editingText;
if (openList)
{
SPIN_LOCK(editTraceLock)
{
// if the edit version is invalid, cancel
vint traceIndex = UnsafeGetEditTraceIndex(newContext.modifiedEditVersion);
if (traceIndex == -1)
{
return;
}
// an edit version has two trace at most, for text change and caret change, here we peak the text change
if (traceIndex > 0 && editTrace[traceIndex - 1].editVersion == context.modifiedEditVersion)
{
traceIndex--;
}
// if the edit version is not created by keyboard input, close
if (traceIndex >= 0)
{
TextEditNotifyStruct& trace = editTrace[traceIndex];
if (!trace.keyInput)
{
openList = false;
}
}
// scan all traces from the calculation's edit version until now
if (openList)
{
keepListState = true;
startPosition = autoComplete->startPosition;
endPosition = editTrace[editTrace.Count() - 1].inputEnd;
for (vint i = traceIndex; i < editTrace.Count(); i++)
{
TextEditNotifyStruct& trace = editTrace[i];
// if there are no text change trace until now, don't change the list
if (trace.originalText != L"" || trace.inputText != L"")
{
keepListState = false;
}
// if the edit position goes before the start position of the auto complete, refresh
if (trace.inputEnd <= startPosition)
{
openList = false;
break;
}
}
}
if (traceIndex > 0)
{
editTrace.RemoveRange(0, traceIndex);
}
}
}
// if there is a global correction send to the UI thread but the list is not opening, cancel
if (byGlobalCorrection && !IsListOpening())
{
return;
}
// if the input text from the start position to the current position crosses a token, close
if (openList && element)
{
editingText = element->GetLines().GetText(startPosition, endPosition);
if (grammarParser->GetTable()->GetLexer().Walk().IsClosedToken(editingText))
{
openList = false;
}
}
// calculate the content of the list
if (autoComplete && ((!keepListState && openList) || IsListOpening()))
{
SortedList<WString> itemKeys;
List<ParsingCandidateItem> itemValues;
// copy all candidate keywords
for (auto token : autoComplete->shownCandidates)
{
WString literal = parsingExecutor->GetTokenMetaData(token).unescapedRegexText;
if (literal != L"" && !itemKeys.Contains(literal))
{
ParsingCandidateItem item;
item.name = literal;
item.semanticId = -1;
itemValues.Insert(itemKeys.Add(literal), item);
}
}
// copy all candidate symbols
if (autoComplete->acceptableSemanticIds)
{
for (auto item : autoComplete->candidateItems)
{
if (autoComplete->acceptableSemanticIds->Contains(item.semanticId))
{
// add all acceptable display of a symbol
// because a symbol can has multiple representation in different places
if (item.name != L"" && !itemKeys.Contains(item.name))
{
itemValues.Insert(itemKeys.Add(item.name), item);
}
}
}
}
// fill the list
List<GuiTextBoxAutoCompleteBase::AutoCompleteItem> candidateItems;
for (vint i = 0; i < itemValues.Count(); i++)
{
auto& item = itemValues[i];
if (item.tag.IsNull())
{
if (auto analyzer = parsingExecutor->GetAnalyzer())
{
item.tag = analyzer->CreateTagForCandidateItem(item);
}
}
GuiTextBoxAutoCompleteBase::AutoCompleteItem candidateItem;
candidateItem.text = item.name;
candidateItem.tag = item.tag;
candidateItems.Add(candidateItem);
}
SetListContent(candidateItems);
}
// set the list state
if (!keepListState)
{
if (openList)
{
OpenList(startPosition);
}
else
{
CloseList();
}
}
if (IsListOpening())
{
HighlightList(editingText);
}
}
void GuiGrammarAutoComplete::Initialize()
{
grammarParser=CreateAutoRecoverParser(parsingExecutor->GetParser()->GetTable());
CollectLeftRecursiveRules();
parsingExecutor->AttachCallback(this);
}
void GuiGrammarAutoComplete::OnContextFinishedAsync(AutoCompleteContext& context)
{
if (auto analyzer = parsingExecutor->GetAnalyzer())
{
if (context.autoComplete && context.autoComplete->acceptableSemanticIds)
{
analyzer->GetCandidateItemsAsync(*context.autoComplete.Obj(), context, context.autoComplete->candidateItems);
}
}
}
void GuiGrammarAutoComplete::EnsureAutoCompleteFinished()
{
parsingExecutor->EnsureTaskFinished();
SPIN_LOCK(contextLock)
{
context = AutoCompleteContext();
}
}
GuiGrammarAutoComplete::GuiGrammarAutoComplete(Ptr<RepeatingParsingExecutor> _parsingExecutor)
:RepeatingParsingExecutor::CallbackBase(_parsingExecutor)
,editing(false)
{
Initialize();
}
GuiGrammarAutoComplete::GuiGrammarAutoComplete(Ptr<parsing::tabling::ParsingGeneralParser> _grammarParser, const WString& _grammarRule)
:RepeatingParsingExecutor::CallbackBase(Ptr(new RepeatingParsingExecutor(_grammarParser, _grammarRule)))
,editing(false)
{
Initialize();
}
GuiGrammarAutoComplete::~GuiGrammarAutoComplete()
{
EnsureAutoCompleteFinished();
parsingExecutor->DetachCallback(this);
}
Ptr<RepeatingParsingExecutor> GuiGrammarAutoComplete::GetParsingExecutor()
{
return parsingExecutor;
}
}
}
}
/***********************************************************************
.\CONTROLS\TEXTEDITORPACKAGE\LANGUAGESERVICE\GUILANGUAGECOLORIZER.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace elements;
using namespace parsing;
using namespace parsing::tabling;
using namespace collections;
using namespace theme;
/***********************************************************************
GuiGrammarColorizer
***********************************************************************/
void GuiGrammarColorizer::OnParsingFinishedAsync(const RepeatingParsingOutput& output)
{
SPIN_LOCK(contextLock)
{
context=output;
OnContextFinishedAsync(context);
}
RestartColorizer();
}
void GuiGrammarColorizer::OnContextFinishedAsync(const RepeatingParsingOutput& context)
{
}
void GuiGrammarColorizer::Attach(elements::GuiColorizedTextElement* _element, SpinLock& _elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)
{
GuiTextBoxRegexColorizer::Attach(_element, _elementModifyLock, _ownerComposition, editVersion);
RepeatingParsingExecutor::CallbackBase::Attach(_element, _elementModifyLock, _ownerComposition, editVersion);
}
void GuiGrammarColorizer::Detach()
{
GuiTextBoxRegexColorizer::Detach();
RepeatingParsingExecutor::CallbackBase::Detach();
if(element && elementModifyLock)
{
parsingExecutor->EnsureTaskFinished();
StopColorizer(false);
}
}
void GuiGrammarColorizer::TextEditPreview(TextEditPreviewStruct& arguments)
{
GuiTextBoxRegexColorizer::TextEditPreview(arguments);
RepeatingParsingExecutor::CallbackBase::TextEditPreview(arguments);
}
void GuiGrammarColorizer::TextEditNotify(const TextEditNotifyStruct& arguments)
{
GuiTextBoxRegexColorizer::TextEditNotify(arguments);
RepeatingParsingExecutor::CallbackBase::TextEditNotify(arguments);
}
void GuiGrammarColorizer::TextCaretChanged(const TextCaretChangedStruct& arguments)
{
GuiTextBoxRegexColorizer::TextCaretChanged(arguments);
RepeatingParsingExecutor::CallbackBase::TextCaretChanged(arguments);
}
void GuiGrammarColorizer::TextEditFinished(vuint editVersion)
{
GuiTextBoxRegexColorizer::TextEditFinished(editVersion);
RepeatingParsingExecutor::CallbackBase::TextEditFinished(editVersion);
}
void GuiGrammarColorizer::OnSemanticColorize(SemanticColorizeContext& context, const RepeatingParsingOutput& input)
{
if (auto analyzer = parsingExecutor->GetAnalyzer())
{
auto semanticId = analyzer->GetSemanticIdForTokenAsync(context, input);
if(semanticId!=-1)
{
context.semanticId=semanticId;
}
}
}
void GuiGrammarColorizer::EnsureColorizerFinished()
{
parsingExecutor->EnsureTaskFinished();
StopColorizerForever();
SPIN_LOCK(contextLock)
{
context=RepeatingParsingOutput();
}
}
GuiGrammarColorizer::GuiGrammarColorizer(Ptr<RepeatingParsingExecutor> _parsingExecutor)
:RepeatingParsingExecutor::CallbackBase(_parsingExecutor)
{
parsingExecutor->AttachCallback(this);
BeginSetColors();
}
GuiGrammarColorizer::GuiGrammarColorizer(Ptr<parsing::tabling::ParsingGeneralParser> _grammarParser, const WString& _grammarRule)
:RepeatingParsingExecutor::CallbackBase(Ptr(new RepeatingParsingExecutor(_grammarParser, _grammarRule)))
{
parsingExecutor->AttachCallback(this);
BeginSetColors();
}
GuiGrammarColorizer::~GuiGrammarColorizer()
{
EnsureColorizerFinished();
parsingExecutor->DetachCallback(this);
}
void GuiGrammarColorizer::BeginSetColors()
{
ClearTokens();
colorSettings.Clear();
text::ColorEntry entry;
{
entry.normal.text = Color(0, 0, 0);
entry.normal.background = Color(0, 0, 0, 0);
entry.selectedFocused.text = Color(255, 255, 255);
entry.selectedFocused.background = Color(51, 153, 255);
entry.selectedUnfocused.text = Color(255, 255, 255);
entry.selectedUnfocused.background = Color(51, 153, 255);
}
SetDefaultColor(entry);
colorSettings.Add(L"Default", entry);
}
const collections::SortedList<WString>& GuiGrammarColorizer::GetColorNames()
{
return colorSettings.Keys();
}
GuiGrammarColorizer::ColorEntry GuiGrammarColorizer::GetColor(const WString& name)
{
vint index=colorSettings.Keys().IndexOf(name);
return index==-1?GetDefaultColor():colorSettings.Values().Get(index);
}
void GuiGrammarColorizer::SetColor(const WString& name, const ColorEntry& entry)
{
colorSettings.Set(name, entry);
}
void GuiGrammarColorizer::SetColor(const WString& name, const Color& color)
{
text::ColorEntry entry=GetDefaultColor();
entry.normal.text=color;
SetColor(name, entry);
}
void GuiGrammarColorizer::EndSetColors()
{
SortedList<WString> tokenColors;
Ptr<ParsingTable> table=parsingExecutor->GetParser()->GetTable();
semanticColorMap.Clear();
vint tokenCount=table->GetTokenCount();
for(vint token=ParsingTable::UserTokenStart;token<tokenCount;token++)
{
const ParsingTable::TokenInfo& tokenInfo=table->GetTokenInfo(token);
const RepeatingParsingExecutor::TokenMetaData& md=parsingExecutor->GetTokenMetaData(token-ParsingTable::UserTokenStart);
if(md.defaultColorIndex==-1)
{
AddToken(tokenInfo.regex, GetDefaultColor());
}
else
{
WString name=parsingExecutor->GetSemanticName(md.defaultColorIndex);
vint color=AddToken(tokenInfo.regex, GetColor(name));
semanticColorMap.Set(md.defaultColorIndex, color);
tokenColors.Add(name);
}
}
for (auto [color, index] : indexed(colorSettings.Keys()))
{
if(!tokenColors.Contains(color))
{
vint semanticId=parsingExecutor->GetSemanticId(color);
if(semanticId!=-1)
{
vint tokenId=AddExtraToken(colorSettings.Values().Get(index));
vint color=tokenId+tokenCount-ParsingTable::UserTokenStart;
semanticColorMap.Set(semanticId, color);
}
}
}
Setup();
}
void GuiGrammarColorizer::ColorizeTokenContextSensitive(vint lineIndex, const wchar_t* text, vint start, vint length, vint& token, vint& contextState)
{
SPIN_LOCK(contextLock)
{
ParsingTreeObject* node=context.node.Obj();
if(node && token!=-1 && parsingExecutor->GetTokenMetaData(token).hasContextColor)
{
ParsingTextPos pos(lineIndex, start);
SemanticColorizeContext scContext;
if(SemanticColorizeContext::RetriveContext(scContext, pos, node, parsingExecutor.Obj()))
{
const RepeatingParsingExecutor::FieldMetaData& md=parsingExecutor->GetFieldMetaData(scContext.type, scContext.field);
vint semantic=md.colorIndex;
scContext.semanticId=-1;
if(scContext.acceptableSemanticIds)
{
OnSemanticColorize(scContext, context);
if(md.semantics->Contains(scContext.semanticId))
{
semantic=scContext.semanticId;
}
}
if(semantic!=-1)
{
vint index=semanticColorMap.Keys().IndexOf(semantic);
if(index!=-1)
{
token=semanticColorMap.Values()[index];
}
}
}
}
}
}
Ptr<RepeatingParsingExecutor> GuiGrammarColorizer::GetParsingExecutor()
{
return parsingExecutor;
}
}
}
}
/***********************************************************************
.\CONTROLS\TEXTEDITORPACKAGE\LANGUAGESERVICE\GUILANGUAGEOPERATIONS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace collections;
using namespace parsing;
using namespace parsing::tabling;
using namespace regex_internal;
/***********************************************************************
ParsingContext
***********************************************************************/
bool ParsingTokenContext::RetriveContext(ParsingTokenContext& output, parsing::ParsingTreeNode* foundNode, RepeatingParsingExecutor* executor)
{
ParsingTreeToken* foundToken=dynamic_cast<ParsingTreeToken*>(foundNode);
if(!foundToken) return false;
ParsingTreeObject* tokenParent=dynamic_cast<ParsingTreeObject*>(foundNode->GetParent());
if(!tokenParent) return false;
vint index=tokenParent->GetMembers().Values().IndexOf(foundNode);
if(index==-1) return false;
WString type=tokenParent->GetType();
WString field=tokenParent->GetMembers().Keys().Get(index);
const RepeatingParsingExecutor::FieldMetaData& md=executor->GetFieldMetaData(type, field);
output.foundToken=foundToken;
output.tokenParent=tokenParent;
output.type=type;
output.field=field;
output.acceptableSemanticIds=md.semantics;
return true;
}
bool ParsingTokenContext::RetriveContext(ParsingTokenContext& output, parsing::ParsingTextPos pos, parsing::ParsingTreeObject* rootNode, RepeatingParsingExecutor* executor)
{
ParsingTreeNode* foundNode=rootNode->FindDeepestNode(pos);
if(!foundNode) return false;
return RetriveContext(output, foundNode, executor);
}
bool ParsingTokenContext::RetriveContext(ParsingTokenContext& output, parsing::ParsingTextRange range, ParsingTreeObject* rootNode, RepeatingParsingExecutor* executor)
{
ParsingTreeNode* foundNode=rootNode->FindDeepestNode(range);
if(!foundNode) return false;
return RetriveContext(output, foundNode, executor);
}
/***********************************************************************
RepeatingParsingExecutor::IParsingAnalyzer
***********************************************************************/
parsing::ParsingTreeNode* RepeatingParsingExecutor::IParsingAnalyzer::ToParent(parsing::ParsingTreeNode* node, const RepeatingPartialParsingOutput* output)
{
if (!output || !output->modifiedNode) return node;
return node == output->modifiedNode.Obj()
? output->originalNode.Obj()
: node;
}
parsing::ParsingTreeObject* RepeatingParsingExecutor::IParsingAnalyzer::ToChild(parsing::ParsingTreeObject* node, const RepeatingPartialParsingOutput* output)
{
if (!output || !output->modifiedNode) return node;
return node == output->originalNode.Obj()
? output->modifiedNode.Obj()
: node;
}
Ptr<parsing::ParsingTreeNode> RepeatingParsingExecutor::IParsingAnalyzer::ToChild(Ptr<parsing::ParsingTreeNode> node, const RepeatingPartialParsingOutput* output)
{
if (!output) return node;
return node == output->originalNode
? output->modifiedNode.Cast<ParsingTreeNode>()
: node;
}
parsing::ParsingTreeNode* RepeatingParsingExecutor::IParsingAnalyzer::GetParent(parsing::ParsingTreeNode* node, const RepeatingPartialParsingOutput* output)
{
return ToParent(node, output)->GetParent();
}
Ptr<parsing::ParsingTreeNode> RepeatingParsingExecutor::IParsingAnalyzer::GetMember(parsing::ParsingTreeObject* node, const WString& name, const RepeatingPartialParsingOutput* output)
{
return ToChild(ToChild(node, output)->GetMember(name), output);
}
Ptr<parsing::ParsingTreeNode> RepeatingParsingExecutor::IParsingAnalyzer::GetItem(parsing::ParsingTreeArray* node, vint index, const RepeatingPartialParsingOutput* output)
{
return ToChild(node->GetItem(index), output);
}
/***********************************************************************
RepeatingParsingExecutor::CallbackBase
***********************************************************************/
RepeatingParsingExecutor::CallbackBase::CallbackBase(Ptr<RepeatingParsingExecutor> _parsingExecutor)
:parsingExecutor(_parsingExecutor)
,callbackAutoPushing(false)
,callbackElement(0)
,callbackElementModifyLock(0)
{
}
RepeatingParsingExecutor::CallbackBase::~CallbackBase()
{
}
void RepeatingParsingExecutor::CallbackBase::RequireAutoSubmitTask(bool enabled)
{
callbackAutoPushing=enabled;
}
void RepeatingParsingExecutor::CallbackBase::Attach(elements::GuiColorizedTextElement* _element, SpinLock& _elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)
{
if(_element)
{
SPIN_LOCK(_elementModifyLock)
{
callbackElement=_element;
callbackElementModifyLock=&_elementModifyLock;
}
}
parsingExecutor->ActivateCallback(this);
if(callbackElement && callbackElementModifyLock && callbackAutoPushing)
{
SPIN_LOCK(*callbackElementModifyLock)
{
RepeatingParsingInput input;
input.editVersion=editVersion;
input.code=callbackElement->GetLines().GetText();
parsingExecutor->SubmitTask(input);
}
}
}
void RepeatingParsingExecutor::CallbackBase::Detach()
{
if(callbackElement && callbackElementModifyLock)
{
SPIN_LOCK(*callbackElementModifyLock)
{
callbackElement=0;
callbackElementModifyLock=0;
}
}
parsingExecutor->DeactivateCallback(this);
}
void RepeatingParsingExecutor::CallbackBase::TextEditPreview(TextEditPreviewStruct& arguments)
{
}
void RepeatingParsingExecutor::CallbackBase::TextEditNotify(const TextEditNotifyStruct& arguments)
{
}
void RepeatingParsingExecutor::CallbackBase::TextCaretChanged(const TextCaretChangedStruct& arguments)
{
}
void RepeatingParsingExecutor::CallbackBase::TextEditFinished(vuint editVersion)
{
if(callbackElement && callbackElementModifyLock && callbackAutoPushing)
{
SPIN_LOCK(*callbackElementModifyLock)
{
RepeatingParsingInput input;
input.editVersion=editVersion;
input.code=callbackElement->GetLines().GetText();
parsingExecutor->SubmitTask(input);
}
}
}
/***********************************************************************
RepeatingParsingExecutor
***********************************************************************/
void RepeatingParsingExecutor::Execute(const RepeatingParsingInput& input)
{
List<Ptr<ParsingError>> errors;
Ptr<ParsingTreeObject> node=grammarParser->Parse(input.code, grammarRule, errors).Cast<ParsingTreeObject>();
if(node)
{
node->InitializeQueryCache();
}
RepeatingParsingOutput result;
result.node=node;
result.editVersion=input.editVersion;
result.code=input.code;
if(node)
{
OnContextFinishedAsync(result);
for (auto callback : callbacks)
{
callback->OnParsingFinishedAsync(result);
}
}
}
void RepeatingParsingExecutor::PrepareMetaData()
{
Ptr<ParsingTable> table=grammarParser->GetTable();
tokenIndexMap.Clear();
semanticIndexMap.Clear();
tokenMetaDatas.Clear();
fieldMetaDatas.Clear();
Dictionary<vint, Ptr<ParsingTable::AttributeInfo>> tokenColorAtts, tokenContextColorAtts, tokenCandidateAtts, tokenAutoCompleteAtts;
Dictionary<FieldDesc, Ptr<ParsingTable::AttributeInfo>> fieldColorAtts, fieldSemanticAtts;
{
vint tokenCount=table->GetTokenCount();
for(vint token=ParsingTable::UserTokenStart;token<tokenCount;token++)
{
const ParsingTable::TokenInfo& tokenInfo=table->GetTokenInfo(token);
vint tokenIndex=token-ParsingTable::UserTokenStart;
tokenIndexMap.Add(tokenInfo.name, tokenIndex);
if(Ptr<ParsingTable::AttributeInfo> att=GetColorAttribute(tokenInfo.attributeIndex))
{
tokenColorAtts.Add(tokenIndex, att);
}
if(Ptr<ParsingTable::AttributeInfo> att=GetContextColorAttribute(tokenInfo.attributeIndex))
{
tokenContextColorAtts.Add(tokenIndex, att);
}
if(Ptr<ParsingTable::AttributeInfo> att=GetCandidateAttribute(tokenInfo.attributeIndex))
{
tokenCandidateAtts.Add(tokenIndex, att);
}
if(Ptr<ParsingTable::AttributeInfo> att=GetAutoCompleteAttribute(tokenInfo.attributeIndex))
{
tokenAutoCompleteAtts.Add(tokenIndex, att);
}
}
}
{
vint fieldCount=table->GetTreeFieldInfoCount();
for(vint field=0;field<fieldCount;field++)
{
const ParsingTable::TreeFieldInfo& fieldInfo=table->GetTreeFieldInfo(field);
FieldDesc fieldDesc(fieldInfo.type, fieldInfo.field);
if(Ptr<ParsingTable::AttributeInfo> att=GetColorAttribute(fieldInfo.attributeIndex))
{
fieldColorAtts.Add(fieldDesc, att);
}
if(Ptr<ParsingTable::AttributeInfo> att=GetSemanticAttribute(fieldInfo.attributeIndex))
{
fieldSemanticAtts.Add(fieldDesc, att);
}
}
}
for (auto att :
From(tokenColorAtts.Values())
.Concat(tokenContextColorAtts.Values())
.Concat(fieldColorAtts.Values())
.Concat(fieldSemanticAtts.Values())
)
{
for (auto argument : att->arguments)
{
if(!semanticIndexMap.Contains(argument))
{
semanticIndexMap.Add(argument);
}
}
}
vint index=0;
for (auto tokenIndex : tokenIndexMap.Values())
{
TokenMetaData md;
md.tableTokenIndex=tokenIndex+ParsingTable::UserTokenStart;
md.lexerTokenIndex=tokenIndex;
md.defaultColorIndex=-1;
md.hasContextColor=false;
md.hasAutoComplete=false;
md.isCandidate=false;
if((index=tokenColorAtts.Keys().IndexOf(tokenIndex))!=-1)
{
md.defaultColorIndex=semanticIndexMap.IndexOf(tokenColorAtts.Values()[index]->arguments[0]);
}
md.hasContextColor=tokenContextColorAtts.Keys().Contains(tokenIndex);
md.hasAutoComplete=tokenAutoCompleteAtts.Keys().Contains(tokenIndex);
if ((md.isCandidate = tokenCandidateAtts.Keys().Contains(tokenIndex)))
{
const ParsingTable::TokenInfo& tokenInfo = table->GetTokenInfo(md.tableTokenIndex);
auto regex = wtou32(tokenInfo.regex);
if (IsRegexEscapedLiteralString(regex))
{
md.unescapedRegexText = u32tow(UnescapeTextForRegex(regex));
}
else
{
md.isCandidate = false;
}
}
tokenMetaDatas.Add(tokenIndex, md);
}
{
vint fieldCount=table->GetTreeFieldInfoCount();
for(vint field=0;field<fieldCount;field++)
{
const ParsingTable::TreeFieldInfo& fieldInfo=table->GetTreeFieldInfo(field);
FieldDesc fieldDesc(fieldInfo.type, fieldInfo.field);
FieldMetaData md;
md.colorIndex=-1;
if((index=fieldColorAtts.Keys().IndexOf(fieldDesc))!=-1)
{
md.colorIndex=semanticIndexMap.IndexOf(fieldColorAtts.Values()[index]->arguments[0]);
}
if((index=fieldSemanticAtts.Keys().IndexOf(fieldDesc))!=-1)
{
md.semantics=Ptr(new List<vint>);
for (auto argument : fieldSemanticAtts.Values()[index]->arguments)
{
md.semantics->Add(semanticIndexMap.IndexOf(argument));
}
}
fieldMetaDatas.Add(fieldDesc, md);
}
}
}
void RepeatingParsingExecutor::OnContextFinishedAsync(RepeatingParsingOutput& context)
{
if(analyzer)
{
context.cache = analyzer->CreateCacheAsync(context);
}
}
RepeatingParsingExecutor::RepeatingParsingExecutor(Ptr<parsing::tabling::ParsingGeneralParser> _grammarParser, const WString& _grammarRule, Ptr<IParsingAnalyzer> _analyzer)
:grammarParser(_grammarParser)
,grammarRule(_grammarRule)
,analyzer(_analyzer)
,autoPushingCallback(0)
{
PrepareMetaData();
if (analyzer)
{
analyzer->Attach(this);
}
}
RepeatingParsingExecutor::~RepeatingParsingExecutor()
{
EnsureTaskFinished();
if (analyzer)
{
analyzer->Detach(this);
}
}
Ptr<parsing::tabling::ParsingGeneralParser> RepeatingParsingExecutor::GetParser()
{
return grammarParser;
}
bool RepeatingParsingExecutor::AttachCallback(ICallback* value)
{
if(!value) return false;
if(callbacks.Contains(value)) return false;
callbacks.Add(value);
return true;
}
bool RepeatingParsingExecutor::DetachCallback(ICallback* value)
{
if(!value) return false;
if(!callbacks.Contains(value)) return false;
DeactivateCallback(value);
callbacks.Remove(value);
return true;
}
bool RepeatingParsingExecutor::ActivateCallback(ICallback* value)
{
if(!value) return false;
if(!callbacks.Contains(value)) return false;
if(activatedCallbacks.Contains(value)) return false;
activatedCallbacks.Add(value);
if(!autoPushingCallback)
{
autoPushingCallback=value;
autoPushingCallback->RequireAutoSubmitTask(true);
}
return true;
}
bool RepeatingParsingExecutor::DeactivateCallback(ICallback* value)
{
if(!value) return false;
if(!callbacks.Contains(value)) return false;
if(!activatedCallbacks.Contains(value)) return false;
if(autoPushingCallback==value)
{
autoPushingCallback->RequireAutoSubmitTask(false);
autoPushingCallback=0;
}
activatedCallbacks.Remove(value);
if(!autoPushingCallback && activatedCallbacks.Count()>0)
{
autoPushingCallback=activatedCallbacks[0];
autoPushingCallback->RequireAutoSubmitTask(true);
}
return true;
}
Ptr<RepeatingParsingExecutor::IParsingAnalyzer> RepeatingParsingExecutor::GetAnalyzer()
{
return analyzer;
}
vint RepeatingParsingExecutor::GetTokenIndex(const WString& tokenName)
{
vint index=tokenIndexMap.Keys().IndexOf(tokenName);
return index==-1?-1:tokenIndexMap.Values()[index];
}
vint RepeatingParsingExecutor::GetSemanticId(const WString& name)
{
return semanticIndexMap.IndexOf(name);
}
WString RepeatingParsingExecutor::GetSemanticName(vint id)
{
return 0<=id&&id<semanticIndexMap.Count()?semanticIndexMap[id]:L"";
}
const RepeatingParsingExecutor::TokenMetaData& RepeatingParsingExecutor::GetTokenMetaData(vint regexTokenIndex)
{
return tokenMetaDatas[regexTokenIndex];
}
const RepeatingParsingExecutor::FieldMetaData& RepeatingParsingExecutor::GetFieldMetaData(const WString& type, const WString& field)
{
return fieldMetaDatas[FieldDesc(type, field)];
}
Ptr<parsing::tabling::ParsingTable::AttributeInfo> RepeatingParsingExecutor::GetAttribute(vint index, const WString& name, vint argumentCount)
{
if(index!=-1)
{
Ptr<ParsingTable::AttributeInfo> att=grammarParser->GetTable()->GetAttributeInfo(index)->FindFirst(name);
if(att && (argumentCount==-1 || att->arguments.Count()==argumentCount))
{
return att;
}
}
return 0;
}
Ptr<parsing::tabling::ParsingTable::AttributeInfo> RepeatingParsingExecutor::GetColorAttribute(vint index)
{
return GetAttribute(index, L"Color", 1);
}
Ptr<parsing::tabling::ParsingTable::AttributeInfo> RepeatingParsingExecutor::GetContextColorAttribute(vint index)
{
return GetAttribute(index, L"ContextColor", 0);
}
Ptr<parsing::tabling::ParsingTable::AttributeInfo> RepeatingParsingExecutor::GetSemanticAttribute(vint index)
{
return GetAttribute(index, L"Semantic", -1);
}
Ptr<parsing::tabling::ParsingTable::AttributeInfo> RepeatingParsingExecutor::GetCandidateAttribute(vint index)
{
return GetAttribute(index, L"Candidate", 0);
}
Ptr<parsing::tabling::ParsingTable::AttributeInfo> RepeatingParsingExecutor::GetAutoCompleteAttribute(vint index)
{
return GetAttribute(index, L"AutoComplete", 0);
}
}
}
}
/***********************************************************************
.\CONTROLS\TOOLSTRIPPACKAGE\GUIMENUCONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace compositions;
/***********************************************************************
IGuiMenuService
***********************************************************************/
const wchar_t* const IGuiMenuService::Identifier = L"vl::presentation::controls::IGuiMenuService";
const wchar_t* const IGuiMenuDropdownProvider::Identifier = L"vl::presentation::controls::IGuiMenuDropdownProvider";
IGuiMenuService::IGuiMenuService()
:openingMenu(0)
{
}
void IGuiMenuService::MenuItemExecuted()
{
if(openingMenu)
{
openingMenu->Hide();
}
if(GetParentMenuService())
{
GetParentMenuService()->MenuItemExecuted();
}
}
GuiMenu* IGuiMenuService::GetOpeningMenu()
{
return openingMenu;
}
void IGuiMenuService::MenuOpened(GuiMenu* menu)
{
if(openingMenu!=menu && openingMenu)
{
openingMenu->Hide();
}
openingMenu=menu;
}
void IGuiMenuService::MenuClosed(GuiMenu* menu)
{
if(openingMenu==menu)
{
openingMenu=0;
}
}
/***********************************************************************
GuiMenu
***********************************************************************/
void GuiMenu::BeforeControlTemplateUninstalled_()
{
}
void GuiMenu::AfterControlTemplateInstalled_(bool initialize)
{
}
IGuiMenuService* GuiMenu::GetParentMenuService()
{
return parentMenuService;
}
IGuiMenuService::Direction GuiMenu::GetPreferredDirection()
{
return IGuiMenuService::Vertical;
}
theme::ThemeName GuiMenu::GetHostThemeName()
{
return GetControlThemeName();
}
bool GuiMenu::IsActiveState()
{
return true;
}
bool GuiMenu::IsSubMenuActivatedByMouseDown()
{
return false;
}
void GuiMenu::MenuItemExecuted()
{
IGuiMenuService::MenuItemExecuted();
Hide();
}
void GuiMenu::Moving(NativeRect& bounds, bool fixSizeOnly, bool draggingBorder)
{
GuiPopup::Moving(bounds, fixSizeOnly, draggingBorder);
if (draggingBorder)
{
if (auto nativeWindow = GetNativeWindow())
{
auto newSize = bounds.GetSize();
auto nativeOffset = (nativeWindow->GetBounds().GetSize() - nativeWindow->GetClientSize());
auto preferredNativeSize = nativeWindow->Convert(preferredMenuClientSizeBeforeUpdating) + nativeOffset;
if (newSize.x < preferredNativeSize.x) newSize.x = preferredNativeSize.x;
if (newSize.y < preferredNativeSize.y) newSize.y = preferredNativeSize.y;
preferredMenuClientSize = nativeWindow->Convert(newSize - nativeOffset);
}
}
}
void GuiMenu::UpdateClientSizeAfterRendering(Size preferredSize, Size clientSize)
{
auto size = preferredSize;
if (size.x < preferredMenuClientSize.x) size.x = preferredMenuClientSize.x;
if (size.y < preferredMenuClientSize.y) size.y = preferredMenuClientSize.y;
GuiPopup::UpdateClientSizeAfterRendering(preferredSize, size);
}
void GuiMenu::OnWindowOpened(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if(parentMenuService)
{
parentMenuService->MenuOpened(this);
}
}
void GuiMenu::OnDeactivatedAltHost()
{
if(hideOnDeactivateAltHost)
{
Hide();
}
GuiPopup::OnDeactivatedAltHost();
}
void GuiMenu::OnWindowClosed(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if(parentMenuService)
{
parentMenuService->MenuClosed(this);
GuiMenu* openingSubMenu=GetOpeningMenu();
if(openingSubMenu)
{
openingSubMenu->Hide();
}
}
}
GuiMenu::GuiMenu(theme::ThemeName themeName, GuiControl* _owner)
:GuiPopup(themeName, INativeWindow::Menu)
, owner(_owner)
{
UpdateMenuService();
WindowOpened.AttachMethod(this, &GuiMenu::OnWindowOpened);
WindowClosed.AttachMethod(this, &GuiMenu::OnWindowClosed);
}
GuiMenu::~GuiMenu()
{
}
void GuiMenu::UpdateMenuService()
{
if(owner)
{
parentMenuService=owner->QueryTypedService<IGuiMenuService>();
}
}
IDescriptable* GuiMenu::QueryService(const WString& identifier)
{
if(identifier==IGuiMenuService::Identifier)
{
return (IGuiMenuService*)this;
}
else
{
return GuiPopup::QueryService(identifier);
}
}
bool GuiMenu::GetHideOnDeactivateAltHost()
{
return hideOnDeactivateAltHost;
}
void GuiMenu::SetHideOnDeactivateAltHost(bool value)
{
hideOnDeactivateAltHost = value;
}
Size GuiMenu::GetPreferredMenuClientSize()
{
return preferredMenuClientSize;
}
void GuiMenu::SetPreferredMenuClientSize(Size value)
{
preferredMenuClientSize = value;
preferredMenuClientSizeBeforeUpdating = value;
}
/***********************************************************************
GuiMenuBar
***********************************************************************/
IGuiMenuService* GuiMenuBar::GetParentMenuService()
{
return GetParent() ? GetParent()->QueryTypedService<IGuiMenuService>() : nullptr;
}
IGuiMenuService::Direction GuiMenuBar::GetPreferredDirection()
{
return IGuiMenuService::Horizontal;
}
theme::ThemeName GuiMenuBar::GetHostThemeName()
{
return GetControlThemeName();
}
bool GuiMenuBar::IsActiveState()
{
return GetOpeningMenu()!=0;
}
bool GuiMenuBar::IsSubMenuActivatedByMouseDown()
{
return true;
}
GuiMenuBar::GuiMenuBar(theme::ThemeName themeName)
:GuiControl(themeName)
{
}
GuiMenuBar::~GuiMenuBar()
{
}
IDescriptable* GuiMenuBar::QueryService(const WString& identifier)
{
if(identifier==IGuiMenuService::Identifier)
{
return (IGuiMenuService*)this;
}
else
{
return GuiControl::QueryService(identifier);
}
}
/***********************************************************************
GuiMenuButton
***********************************************************************/
void GuiMenuButton::BeforeControlTemplateUninstalled_()
{
auto host = GetSubMenuHost();
host->Clicked.Detach(hostClickedHandler);
host->GetBoundsComposition()->GetEventReceiver()->mouseEnter.Detach(hostMouseEnterHandler);
hostClickedHandler = nullptr;
hostMouseEnterHandler = nullptr;
}
void GuiMenuButton::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
auto host = GetSubMenuHost();
ct->SetSubMenuOpening(GetSubMenuOpening());
ct->SetLargeImage(largeImage);
ct->SetImage(image);
ct->SetShortcutText(shortcutText);
ct->SetSubMenuExisting(subMenu != nullptr);
hostClickedHandler = host->Clicked.AttachMethod(this, &GuiMenuButton::OnClicked);
hostMouseEnterHandler = host->GetBoundsComposition()->GetEventReceiver()->mouseEnter.AttachMethod(this, &GuiMenuButton::OnMouseEnter);
}
bool GuiMenuButton::OpenSubMenuInternal()
{
if (!GetSubMenuOpening())
{
if (ownerMenuService)
{
GuiMenu* openingSiblingMenu = ownerMenuService->GetOpeningMenu();
if (openingSiblingMenu)
{
openingSiblingMenu->Hide();
}
}
BeforeSubMenuOpening.Execute(GetNotifyEventArguments());
if (subMenu)
{
subMenu->SetClientSize(preferredMenuClientSize);
IGuiMenuService::Direction direction = GetSubMenuDirection();
subMenu->ShowPopup(GetSubMenuHost(), direction == IGuiMenuService::Horizontal);
AfterSubMenuOpening.Execute(GetNotifyEventArguments());
return true;
}
}
return false;
}
void GuiMenuButton::OnParentLineChanged()
{
GuiButton::OnParentLineChanged();
ownerMenuService=QueryTypedService<IGuiMenuService>();
if(ownerMenuService)
{
SetClickOnMouseUp(!ownerMenuService->IsSubMenuActivatedByMouseDown());
}
if(subMenu)
{
subMenu->UpdateMenuService();
}
}
compositions::IGuiAltActionHost* GuiMenuButton::GetActivatingAltHost()
{
if (subMenu)
{
return subMenu->QueryTypedService<IGuiAltActionHost>();
}
else
{
return GuiSelectableButton::GetActivatingAltHost();
}
}
void GuiMenuButton::OnSubMenuWindowOpened(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
SubMenuOpeningChanged.Execute(GetNotifyEventArguments());
TypedControlTemplateObject(true)->SetSubMenuOpening(true);
}
void GuiMenuButton::OnSubMenuWindowClosed(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
SubMenuOpeningChanged.Execute(GetNotifyEventArguments());
TypedControlTemplateObject(true)->SetSubMenuOpening(false);
}
void GuiMenuButton::OnMouseEnter(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if(GetVisuallyEnabled())
{
if(cascadeAction && ownerMenuService && ownerMenuService->IsActiveState())
{
OpenSubMenuInternal();
}
}
}
void GuiMenuButton::OnClicked(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if(GetVisuallyEnabled())
{
if(!OpenSubMenuInternal() && ownerMenuService)
{
ownerMenuService->MenuItemExecuted();
}
}
}
IGuiMenuService::Direction GuiMenuButton::GetSubMenuDirection()
{
return ownerMenuService?ownerMenuService->GetPreferredDirection():IGuiMenuService::Horizontal;
}
void GuiMenuButton::DetachSubMenu()
{
if (subMenu)
{
subMenu->WindowOpened.Detach(subMenuWindowOpenedHandler);
subMenu->WindowClosed.Detach(subMenuWindowClosedHandler);
subMenuWindowOpenedHandler = nullptr;
subMenuWindowClosedHandler = nullptr;
if (ownedSubMenu)
{
delete subMenu;
}
}
}
GuiMenu* GuiMenuButton::ProvideDropdownMenu()
{
return GetSubMenu();
}
GuiMenuButton::GuiMenuButton(theme::ThemeName themeName)
:GuiSelectableButton(themeName)
,subMenu(0)
,ownedSubMenu(false)
,ownerMenuService(0)
,cascadeAction(true)
{
SetAutoSelection(false);
BeforeSubMenuOpening.SetAssociatedComposition(boundsComposition);
SubMenuOpeningChanged.SetAssociatedComposition(boundsComposition);
LargeImageChanged.SetAssociatedComposition(boundsComposition);
ImageChanged.SetAssociatedComposition(boundsComposition);
ShortcutTextChanged.SetAssociatedComposition(boundsComposition);
}
GuiMenuButton::~GuiMenuButton()
{
if (!subMenuDisposeFlag || !subMenuDisposeFlag->IsDisposed())
{
DetachSubMenu();
}
}
GuiButton* GuiMenuButton::GetSubMenuHost()
{
GuiButton* button = TypedControlTemplateObject(true)->GetSubMenuHost();
return button ? button : this;
}
Ptr<GuiImageData> GuiMenuButton::GetLargeImage()
{
return largeImage;
}
void GuiMenuButton::SetLargeImage(Ptr<GuiImageData> value)
{
if (largeImage != value)
{
largeImage = value;
TypedControlTemplateObject(true)->SetLargeImage(largeImage);
LargeImageChanged.Execute(GetNotifyEventArguments());
}
}
Ptr<GuiImageData> GuiMenuButton::GetImage()
{
return image;
}
void GuiMenuButton::SetImage(Ptr<GuiImageData> value)
{
if (image != value)
{
image = value;
TypedControlTemplateObject(true)->SetImage(image);
ImageChanged.Execute(GetNotifyEventArguments());
}
}
const WString& GuiMenuButton::GetShortcutText()
{
return shortcutText;
}
void GuiMenuButton::SetShortcutText(const WString& value)
{
if (shortcutText != value)
{
shortcutText = value;
TypedControlTemplateObject(true)->SetShortcutText(shortcutText);
ShortcutTextChanged.Execute(GetNotifyEventArguments());
}
}
bool GuiMenuButton::IsSubMenuExists()
{
return subMenu!=0;
}
GuiMenu* GuiMenuButton::GetSubMenu()
{
return subMenu;
}
GuiMenu* GuiMenuButton::CreateSubMenu(TemplateProperty<templates::GuiMenuTemplate> subMenuTemplate)
{
if (!subMenu)
{
GuiMenu* newSubMenu = new GuiMenu(theme::ThemeName::Menu, this);
newSubMenu->SetControlTemplate(subMenuTemplate ? subMenuTemplate : TypedControlTemplateObject(true)->GetSubMenuTemplate());
SetSubMenu(newSubMenu, true);
}
return subMenu;
}
void GuiMenuButton::SetSubMenu(GuiMenu* value, bool owned)
{
if (subMenu)
{
DetachSubMenu();
subMenuDisposeFlag = nullptr;
}
subMenu = value;
ownedSubMenu = owned;
if (subMenu)
{
subMenu->SetPreferredMenuClientSize(preferredMenuClientSize);
subMenuDisposeFlag = subMenu->GetDisposedFlag();
subMenuWindowOpenedHandler = subMenu->WindowOpened.AttachMethod(this, &GuiMenuButton::OnSubMenuWindowOpened);
subMenuWindowClosedHandler = subMenu->WindowClosed.AttachMethod(this, &GuiMenuButton::OnSubMenuWindowClosed);
}
TypedControlTemplateObject(true)->SetSubMenuExisting(subMenu != nullptr);
}
void GuiMenuButton::DestroySubMenu()
{
if(subMenu)
{
DetachSubMenu();
subMenu=0;
ownedSubMenu=false;
TypedControlTemplateObject(true)->SetSubMenuExisting(false);
}
}
bool GuiMenuButton::GetOwnedSubMenu()
{
return subMenu && ownedSubMenu;
}
bool GuiMenuButton::GetSubMenuOpening()
{
if(subMenu)
{
return subMenu->GetOpening();
}
else
{
return false;
}
}
void GuiMenuButton::SetSubMenuOpening(bool value)
{
if (subMenu && subMenu->GetOpening() != value)
{
if (value)
{
OpenSubMenuInternal();
}
else
{
subMenu->Close();
}
}
}
Size GuiMenuButton::GetPreferredMenuClientSize()
{
return preferredMenuClientSize;
}
void GuiMenuButton::SetPreferredMenuClientSize(Size value)
{
preferredMenuClientSize = value;
if (subMenu)
{
subMenu->SetPreferredMenuClientSize(preferredMenuClientSize);
}
}
bool GuiMenuButton::GetCascadeAction()
{
return cascadeAction;
}
void GuiMenuButton::SetCascadeAction(bool value)
{
cascadeAction=value;
}
IDescriptable* GuiMenuButton::QueryService(const WString& identifier)
{
if (identifier == IGuiMenuDropdownProvider::Identifier)
{
return (IGuiMenuDropdownProvider*)this;
}
else
{
return GuiSelectableButton::QueryService(identifier);
}
}
}
}
}
/***********************************************************************
.\CONTROLS\TOOLSTRIPPACKAGE\GUIRIBBONCONTROLS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace reflection::description;
using namespace collections;
using namespace compositions;
using namespace theme;
using namespace templates;
/***********************************************************************
GuiRibbonTab
***********************************************************************/
void GuiRibbonTab::BeforeControlTemplateUninstalled_()
{
auto ct = TypedControlTemplateObject(false);
if (!ct) return;
if (auto bhc = ct->GetBeforeHeadersContainer())
{
bhc->RemoveChild(beforeHeaders);
}
if (auto ahc = ct->GetAfterHeadersContainer())
{
ahc->RemoveChild(afterHeaders);
}
}
void GuiRibbonTab::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
if (auto bhc = ct->GetBeforeHeadersContainer())
{
bhc->AddChild(beforeHeaders);
}
if (auto ahc = ct->GetAfterHeadersContainer())
{
ahc->AddChild(afterHeaders);
}
}
GuiRibbonTab::GuiRibbonTab(theme::ThemeName themeName)
:GuiTab(themeName)
{
beforeHeaders = new GuiBoundsComposition();
beforeHeaders->SetAlignmentToParent(Margin(0, 0, 0, 0));
beforeHeaders->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
afterHeaders = new GuiBoundsComposition();
afterHeaders->SetAlignmentToParent(Margin(0, 0, 0, 0));
afterHeaders->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
}
GuiRibbonTab::~GuiRibbonTab()
{
if (!beforeHeaders->GetParent())
{
SafeDeleteComposition(beforeHeaders);
}
if (!afterHeaders->GetParent())
{
SafeDeleteComposition(afterHeaders);
}
}
compositions::GuiGraphicsComposition* GuiRibbonTab::GetBeforeHeaders()
{
return beforeHeaders;
}
compositions::GuiGraphicsComposition* GuiRibbonTab::GetAfterHeaders()
{
return afterHeaders;
}
/***********************************************************************
GuiRibbonGroupCollection
***********************************************************************/
bool GuiRibbonGroupCollection::QueryInsert(vint index, GuiRibbonGroup* const& value)
{
return !value->GetBoundsComposition()->GetParent();
}
void GuiRibbonGroupCollection::AfterInsert(vint index, GuiRibbonGroup* const& value)
{
value->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
auto item = new GuiStackItemComposition();
item->AddChild(value->GetBoundsComposition());
tabPage->stack->InsertStackItem(index, item);
}
void GuiRibbonGroupCollection::AfterRemove(vint index, vint count)
{
for (vint i = 0; i < count; i++)
{
auto item = tabPage->stack->GetStackItems()[index];
tabPage->stack->RemoveChild(item);
item->RemoveChild(item->Children()[0]);
delete item;
}
}
GuiRibbonGroupCollection::GuiRibbonGroupCollection(GuiRibbonTabPage* _tabPage)
:tabPage(_tabPage)
{
}
GuiRibbonGroupCollection::~GuiRibbonGroupCollection()
{
}
/***********************************************************************
GuiRibbonTabPage
***********************************************************************/
GuiRibbonTabPage::GuiRibbonTabPage(theme::ThemeName themeName)
:GuiTabPage(themeName)
, groups(this)
{
stack = new GuiStackComposition();
stack->SetDirection(GuiStackComposition::Horizontal);
stack->SetAlignmentToParent(Margin(2, 2, 2, 2));
stack->SetPadding(2);
stack->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
responsiveStack = new GuiResponsiveStackComposition();
responsiveStack->SetDirection(ResponsiveDirection::Horizontal);
responsiveStack->SetAlignmentToParent(Margin(0, 0, 0, 0));
responsiveStack->AddChild(stack);
responsiveContainer = new GuiResponsiveContainerComposition();
responsiveContainer->SetAlignmentToParent(Margin(0, 0, 0, 0));
responsiveContainer->SetResponsiveTarget(responsiveStack);
containerComposition->AddChild(responsiveContainer);
HighlightedChanged.SetAssociatedComposition(boundsComposition);
}
GuiRibbonTabPage::~GuiRibbonTabPage()
{
}
bool GuiRibbonTabPage::GetHighlighted()
{
return highlighted;
}
void GuiRibbonTabPage::SetHighlighted(bool value)
{
if (highlighted != value)
{
highlighted = value;
HighlightedChanged.Execute(GetNotifyEventArguments());
}
}
collections::ObservableListBase<GuiRibbonGroup*>& GuiRibbonTabPage::GetGroups()
{
return groups;
}
/***********************************************************************
GuiRibbonGroupItemCollection
***********************************************************************/
bool GuiRibbonGroupItemCollection::QueryInsert(vint index, GuiControl* const& value)
{
return !value->GetBoundsComposition()->GetParent();
}
void GuiRibbonGroupItemCollection::AfterInsert(vint index, GuiControl* const& value)
{
value->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
auto item = new GuiStackItemComposition();
item->AddChild(value->GetBoundsComposition());
group->stack->InsertStackItem(index, item);
}
void GuiRibbonGroupItemCollection::AfterRemove(vint index, vint count)
{
for (vint i = 0; i < count; i++)
{
auto item = group->stack->GetStackItems()[index];
group->stack->RemoveChild(item);
item->RemoveChild(item->Children()[0]);
delete item;
}
}
GuiRibbonGroupItemCollection::GuiRibbonGroupItemCollection(GuiRibbonGroup* _group)
:group(_group)
{
}
GuiRibbonGroupItemCollection::~GuiRibbonGroupItemCollection()
{
}
/***********************************************************************
GuiRibbonGroup::CommandExecutor
***********************************************************************/
GuiRibbonGroup::CommandExecutor::CommandExecutor(GuiRibbonGroup* _group)
:group(_group)
{
}
GuiRibbonGroup::CommandExecutor::~CommandExecutor()
{
}
void GuiRibbonGroup::CommandExecutor::NotifyExpandButtonClicked()
{
group->ExpandButtonClicked.Execute(group->GetNotifyEventArguments());
}
/***********************************************************************
GuiRibbonGroupMenu
***********************************************************************/
class GuiRibbonGroupMenu : public GuiMenu, public Description<GuiRibbonGroupMenu>
{
private:
IGuiMenuService::Direction GetPreferredDirection()override
{
return IGuiMenuService::Horizontal;
}
bool IsActiveState()override
{
return false;
}
public:
GuiRibbonGroupMenu(theme::ThemeName themeName, GuiControl* _owner)
:GuiMenu(themeName, _owner)
{
}
};
/***********************************************************************
GuiRibbonGroup
***********************************************************************/
void GuiRibbonGroup::BeforeControlTemplateUninstalled_()
{
auto ct = TypedControlTemplateObject(false);
if (!ct) return;
ct->SetCommands(nullptr);
}
void GuiRibbonGroup::AfterControlTemplateInstalled_(bool initialize)
{
{
auto ct = TypedControlTemplateObject(true);
ct->SetExpandable(expandable);
ct->SetCollapsed(responsiveView->GetCurrentView() == responsiveFixedButton);
ct->SetCommands(commandExecutor.Obj());
dropdownButton->SetControlTemplate(ct->GetLargeDropdownButtonTemplate());
dropdownMenu->SetControlTemplate(ct->GetSubMenuTemplate());
}
if (auto ct = dynamic_cast<GuiRibbonGroupMenuTemplate*>(dropdownMenu->TypedControlTemplateObject(true)))
{
ct->SetExpandable(expandable);
ct->SetCommands(commandExecutor.Obj());
}
}
bool GuiRibbonGroup::IsAltAvailable()
{
return alt != L"";
}
compositions::IGuiAltActionHost* GuiRibbonGroup::GetActivatingAltHost()
{
if (IsAltAvailable())
{
return this;
}
else
{
return GuiControl::GetActivatingAltHost();
}
}
void GuiRibbonGroup::OnCachedBoundsChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
dropdownMenu->GetBoundsComposition()->SetPreferredMinSize(Size(0, containerComposition->GetCachedBounds().Height()));
}
void GuiRibbonGroup::OnTextChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
dropdownButton->SetText(GetText());
}
void GuiRibbonGroup::OnBeforeSubMenuOpening(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (responsiveView->GetViews().Contains(responsiveFixedButton))
{
auto currentDropdown = dropdownMenu;
if (items.Count() == 1)
{
if (auto provider = items[0]->QueryTypedService<IGuiMenuDropdownProvider>())
{
if (auto menu = provider->ProvideDropdownMenu())
{
currentDropdown = menu;
}
}
}
dropdownButton->SetSubMenu(currentDropdown, false);
}
}
void GuiRibbonGroup::OnBeforeSwitchingView(compositions::GuiGraphicsComposition* sender, compositions::GuiItemEventArgs& arguments)
{
if (auto ct = TypedControlTemplateObject(false))
{
ct->SetCollapsed(arguments.itemIndex == 1);
}
if (arguments.itemIndex == 0)
{
while (responsiveStack->LevelDown());
dropdownMenu->GetContainerComposition()->RemoveChild(stack);
responsiveStack->AddChild(stack);
dropdownButton->SetSubMenu(nullptr, false);
}
else
{
while (responsiveStack->LevelUp());
responsiveStack->RemoveChild(stack);
dropdownMenu->GetContainerComposition()->AddChild(stack);
}
}
GuiRibbonGroup::GuiRibbonGroup(theme::ThemeName themeName)
:GuiControl(themeName)
, items(this)
{
SetAltComposition(boundsComposition);
SetAltControl(this, false);
commandExecutor = Ptr(new CommandExecutor(this));
{
stack = new GuiStackComposition();
stack->SetDirection(GuiStackComposition::Horizontal);
stack->SetAlignmentToParent(Margin(0, 0, 0, 0));
stack->SetPadding(2);
stack->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
responsiveStack = new GuiResponsiveStackComposition();
responsiveStack->SetDirection(ResponsiveDirection::Horizontal);
responsiveStack->SetAlignmentToParent(Margin(0, 0, 0, 0));
responsiveStack->AddChild(stack);
}
{
dropdownButton = new GuiToolstripButton(theme::ThemeName::RibbonLargeDropdownButton);
dropdownButton->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
responsiveFixedButton = new GuiResponsiveFixedComposition();
responsiveFixedButton->SetAlignmentToParent(Margin(0, 0, 0, 0));
responsiveFixedButton->AddChild(dropdownButton->GetBoundsComposition());
dropdownMenu = new GuiRibbonGroupMenu(theme::ThemeName::RibbonGroupMenu, dropdownButton);
}
responsiveView = new GuiResponsiveViewComposition();
responsiveView->SetAlignmentToParent(Margin(0, 0, 0, 0));
responsiveView->GetViews().Add(responsiveStack);
containerComposition->AddChild(responsiveView);
ExpandableChanged.SetAssociatedComposition(boundsComposition);
ExpandButtonClicked.SetAssociatedComposition(boundsComposition);
LargeImageChanged.SetAssociatedComposition(boundsComposition);
TextChanged.AttachMethod(this, &GuiRibbonGroup::OnTextChanged);
boundsComposition->CachedBoundsChanged.AttachMethod(this, &GuiRibbonGroup::OnCachedBoundsChanged);
responsiveView->BeforeSwitchingView.AttachMethod(this, &GuiRibbonGroup::OnBeforeSwitchingView);
dropdownButton->BeforeSubMenuOpening.AttachMethod(this, &GuiRibbonGroup::OnBeforeSubMenuOpening);
}
GuiRibbonGroup::~GuiRibbonGroup()
{
if (!responsiveView->GetViews().Contains(responsiveFixedButton))
{
SafeDeleteComposition(responsiveFixedButton);
}
delete dropdownMenu;
}
bool GuiRibbonGroup::GetExpandable()
{
return expandable;
}
void GuiRibbonGroup::SetExpandable(bool value)
{
if (expandable != value)
{
expandable = value;
TypedControlTemplateObject(true)->SetExpandable(expandable);
if (auto ct = dynamic_cast<GuiRibbonGroupMenuTemplate*>(dropdownMenu->TypedControlTemplateObject(true)))
{
ct->SetExpandable(expandable);
}
ExpandableChanged.Execute(GetNotifyEventArguments());
}
}
Ptr<GuiImageData> GuiRibbonGroup::GetLargeImage()
{
return largeImage;
}
void GuiRibbonGroup::SetLargeImage(Ptr<GuiImageData> value)
{
if (largeImage != value)
{
largeImage = value;
dropdownButton->SetLargeImage(value);
LargeImageChanged.Execute(GetNotifyEventArguments());
if (value)
{
if (!responsiveView->GetViews().Contains(responsiveFixedButton))
{
responsiveView->GetViews().Add(responsiveFixedButton);
}
}
else
{
if (responsiveView->GetViews().Contains(responsiveFixedButton))
{
responsiveView->GetViews().Remove(responsiveFixedButton);
}
}
}
}
collections::ObservableListBase<GuiControl*>& GuiRibbonGroup::GetItems()
{
return items;
}
/***********************************************************************
GuiRibbonIconLabel
***********************************************************************/
void GuiRibbonIconLabel::BeforeControlTemplateUninstalled_()
{
}
void GuiRibbonIconLabel::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
ct->SetImage(image);
}
GuiRibbonIconLabel::GuiRibbonIconLabel(theme::ThemeName themeName)
:GuiControl(themeName)
{
ImageChanged.SetAssociatedComposition(boundsComposition);
}
GuiRibbonIconLabel::~GuiRibbonIconLabel()
{
}
Ptr<GuiImageData> GuiRibbonIconLabel::GetImage()
{
return image;
}
void GuiRibbonIconLabel::SetImage(Ptr<GuiImageData> value)
{
if (image != value)
{
image = value;
TypedControlTemplateObject(true)->SetImage(image);
ImageChanged.Execute(GetNotifyEventArguments());
}
}
/***********************************************************************
GuiRibbonButtonsItemCollection
***********************************************************************/
bool GuiRibbonButtonsItemCollection::QueryInsert(vint index, GuiControl* const& value)
{
return !value->GetBoundsComposition()->GetParent();
}
void GuiRibbonButtonsItemCollection::AfterInsert(vint index, GuiControl* const& value)
{
buttons->responsiveView->GetSharedControls().Add(value);
buttons->SetButtonThemeName(buttons->responsiveView->GetCurrentView(), value);
for (vint i = 0; i < sizeof(buttons->views) / sizeof(*buttons->views); i++)
{
if (auto view = buttons->views[i])
{
auto stack = dynamic_cast<GuiStackComposition*>(view->Children()[0]);
auto shared = new GuiResponsiveSharedComposition();
shared->SetAlignmentToParent(Margin(0, 0, 0, 0));
shared->SetShared(value);
auto item = new GuiStackItemComposition();
item->AddChild(shared);
stack->InsertStackItem(index, item);
}
}
}
void GuiRibbonButtonsItemCollection::BeforeRemove(vint index, GuiControl* const& value)
{
CHECK_FAIL(L"GuiRibbonButtonsItemCollection::BeforeRemove(vint, GuiControl* const&)#Controls are not allowed to be removed from GuiRibbonButtons.");
}
GuiRibbonButtonsItemCollection::GuiRibbonButtonsItemCollection(GuiRibbonButtons* _buttons)
:buttons(_buttons)
{
}
GuiRibbonButtonsItemCollection::~GuiRibbonButtonsItemCollection()
{
}
/***********************************************************************
GuiRibbonButtons
***********************************************************************/
void GuiRibbonButtons::BeforeControlTemplateUninstalled_()
{
}
void GuiRibbonButtons::AfterControlTemplateInstalled_(bool initialize)
{
for (auto button : buttons)
{
SetButtonThemeName(responsiveView->GetCurrentView(), button);
}
}
void GuiRibbonButtons::OnBeforeSwitchingView(compositions::GuiGraphicsComposition* sender, compositions::GuiItemEventArgs& arguments)
{
for (auto button : buttons)
{
SetButtonThemeName(responsiveView->GetViews()[arguments.itemIndex], button);
}
}
void GuiRibbonButtons::SetButtonThemeName(compositions::GuiResponsiveCompositionBase* fixed, GuiControl* button)
{
if (fixed && button)
{
auto themeName = button->GetControlThemeName();
vint type = -1;
switch (themeName)
{
case ThemeName::RibbonLargeButton:
case ThemeName::RibbonSmallButton:
case ThemeName::ToolstripButton:
type = 0;
break;
case ThemeName::RibbonLargeDropdownButton:
case ThemeName::RibbonSmallDropdownButton:
case ThemeName::ToolstripDropdownButton:
type = 1;
break;
case ThemeName::RibbonLargeSplitButton:
case ThemeName::RibbonSmallSplitButton:
case ThemeName::ToolstripSplitButton:
type = 2;
break;
case ThemeName::RibbonSmallIconLabel:
case ThemeName::RibbonIconLabel:
type = 3;
break;
default:;
}
if (type != -1)
{
ThemeName themeName = ThemeName::Unknown;
TemplateProperty<GuiToolstripButtonTemplate> controlTemplate;
if (fixed == views[(vint)RibbonButtonSize::Large])
{
switch (type)
{
case 0: themeName = ThemeName::RibbonLargeButton; break;
case 1: themeName = ThemeName::RibbonLargeDropdownButton; break;
case 2: themeName = ThemeName::RibbonLargeSplitButton; break;
case 3: themeName = ThemeName::RibbonSmallIconLabel; break;
}
}
else if (fixed == views[(vint)RibbonButtonSize::Small])
{
switch (type)
{
case 0: themeName = ThemeName::RibbonSmallButton; break;
case 1: themeName = ThemeName::RibbonSmallDropdownButton; break;
case 2: themeName = ThemeName::RibbonSmallSplitButton; break;
case 3: themeName = ThemeName::RibbonSmallIconLabel; break;
}
}
else if (fixed == views[(vint)RibbonButtonSize::Icon])
{
switch (type)
{
case 0: themeName = ThemeName::ToolstripButton; break;
case 1: themeName = ThemeName::ToolstripDropdownButton; break;
case 2: themeName = ThemeName::ToolstripSplitButton; break;
case 3: themeName = ThemeName::RibbonIconLabel; break;
}
}
if (auto ct = TypedControlTemplateObject(false))
{
if (fixed == views[(vint)RibbonButtonSize::Large])
{
switch (type)
{
case 0: controlTemplate = ct->GetLargeButtonTemplate(); break;
case 1: controlTemplate = ct->GetLargeDropdownButtonTemplate(); break;
case 2: controlTemplate = ct->GetLargeSplitButtonTemplate(); break;
case 3: controlTemplate = ct->GetSmallIconLabelTemplate(); break;
}
}
else if (fixed == views[(vint)RibbonButtonSize::Small])
{
switch (type)
{
case 0: controlTemplate = ct->GetSmallButtonTemplate(); break;
case 1: controlTemplate = ct->GetSmallDropdownButtonTemplate(); break;
case 2: controlTemplate = ct->GetSmallSplitButtonTemplate(); break;
case 3: controlTemplate = ct->GetSmallIconLabelTemplate(); break;
}
}
else if (fixed == views[(vint)RibbonButtonSize::Icon])
{
switch (type)
{
case 0: controlTemplate = ct->GetIconButtonTemplate(); break;
case 1: controlTemplate = ct->GetIconDropdownButtonTemplate(); break;
case 2: controlTemplate = ct->GetIconSplitButtonTemplate(); break;
case 3: controlTemplate = ct->GetIconLabelTemplate(); break;
}
}
}
button->SetControlThemeNameAndTemplate(themeName, controlTemplate);
}
}
}
GuiRibbonButtons::GuiRibbonButtons(theme::ThemeName themeName, RibbonButtonSize _maxSize, RibbonButtonSize _minSize)
:GuiControl(themeName)
, maxSize(_maxSize)
, minSize(_minSize)
, buttons(this)
{
responsiveView = new GuiResponsiveViewComposition();
responsiveView->SetDirection(ResponsiveDirection::Horizontal);
responsiveView->SetAlignmentToParent(Margin(0, 0, 0, 0));
responsiveView->BeforeSwitchingView.AttachMethod(this, &GuiRibbonButtons::OnBeforeSwitchingView);
auto installButton = [&](GuiTableComposition* table, vint row, vint column, GuiControl* buttonContainer)
{
auto shared = new GuiResponsiveSharedComposition();
shared->SetAlignmentToParent(Margin(0, 0, 0, 0));
shared->SetShared(buttonContainer);
auto cell = new GuiCellComposition();
cell->SetSite(row, column, 1, 1);
cell->AddChild(shared);
table->AddChild(cell);
};
for (vint i = 0; i < sizeof(views) / sizeof(*views); i++)
{
if ((vint)maxSize <= i && i <= (vint)minSize)
{
auto stack = new GuiStackComposition();
stack->SetAlignmentToParent(Margin(0, 0, 0, 0));
stack->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
stack->SetDirection(i == 0 ? GuiStackComposition::Horizontal : GuiStackComposition::Vertical);
views[i] = new GuiResponsiveFixedComposition();
views[i]->AddChild(stack);
responsiveView->GetViews().Add(views[i]);
}
}
auto sharedSizeRootComposition = new GuiSharedSizeRootComposition();
sharedSizeRootComposition->SetAlignmentToParent(Margin(0, 0, 0, 0));
sharedSizeRootComposition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
sharedSizeRootComposition->AddChild(responsiveView);
containerComposition->AddChild(sharedSizeRootComposition);
}
GuiRibbonButtons::~GuiRibbonButtons()
{
}
collections::ObservableListBase<GuiControl*>& GuiRibbonButtons::GetButtons()
{
return buttons;
}
/***********************************************************************
GuiRibbonToolstripsGroupCollection
***********************************************************************/
bool GuiRibbonToolstripsGroupCollection::QueryInsert(vint index, GuiToolstripGroup* const& value)
{
return !value->GetBoundsComposition()->GetParent();
}
void GuiRibbonToolstripsGroupCollection::AfterInsert(vint index, GuiToolstripGroup* const& value)
{
toolstrips->RearrangeToolstripGroups();
}
void GuiRibbonToolstripsGroupCollection::AfterRemove(vint index, vint count)
{
toolstrips->RearrangeToolstripGroups();
}
GuiRibbonToolstripsGroupCollection::GuiRibbonToolstripsGroupCollection(GuiRibbonToolstrips* _toolstrips)
:toolstrips(_toolstrips)
{
}
GuiRibbonToolstripsGroupCollection::~GuiRibbonToolstripsGroupCollection()
{
}
/***********************************************************************
GuiRibbonToolstrips
***********************************************************************/
// TODO: (enumerable) foreach
#define ARRLEN(X) sizeof(X) / sizeof(*X)
void GuiRibbonToolstrips::BeforeControlTemplateUninstalled_()
{
}
void GuiRibbonToolstrips::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
for (vint i = 0; i < ARRLEN(toolbars); i++)
{
toolbars[i]->SetControlTemplate(ct->GetToolbarTemplate());
}
}
void GuiRibbonToolstrips::OnBeforeSwitchingView(compositions::GuiGraphicsComposition* sender, compositions::GuiItemEventArgs& arguments)
{
RearrangeToolstripGroups(arguments.itemIndex);
}
void GuiRibbonToolstrips::RearrangeToolstripGroups(vint viewIndex)
{
static_assert(ARRLEN(longContainers) == 2, "");
static_assert(ARRLEN(shortContainers) == 3, "");
if (viewIndex == -1)
{
viewIndex = responsiveView->GetViews().IndexOf(responsiveView->GetCurrentView());
}
for (vint i = 0; i < ARRLEN(longContainers); i++)
{
longContainers[i]->GetToolstripItems().Clear();
}
for (vint i = 0; i < ARRLEN(shortContainers); i++)
{
shortContainers[i]->GetToolstripItems().Clear();
}
vint count = viewIndex == 0 ? 2 : 3;
if (groups.Count() <= count)
{
auto containers = viewIndex == 0 ? longContainers : shortContainers;
// TODO: (enumerable) foreach:indexed
for (vint i = 0; i < groups.Count(); i++)
{
containers[i]->GetToolstripItems().Add(groups[i]);
}
}
else if (count == 3)
{
#define DELTA(POSTFIX) (abs(count1##POSTFIX - count2##POSTFIX) + abs(count2##POSTFIX - count3##POSTFIX) + abs(count3##POSTFIX - count1##POSTFIX))
#define DEFINE_COUNT(POSTFIX, OFFSET_FIRST, OFFSET_LAST) \
vint count1##POSTFIX = count1_o + (OFFSET_FIRST); \
vint count2##POSTFIX = count2_o - (OFFSET_FIRST) - (OFFSET_LAST); \
vint count3##POSTFIX = count3_o + (OFFSET_LAST)
#define MIN(a, b) (a)<(b)?(a):(b)
vint firstGroupCount = 0;
vint lastGroupCount = 0;
vint count1_o = 0;
vint count2_o = From(groups)
.Select([](GuiToolstripGroup* group) {return group->GetToolstripItems().Count(); })
.Aggregate([](vint a, vint b) {return a + b; });
vint count3_o = 0;
vint delta_o = DELTA(_o);
while (firstGroupCount + lastGroupCount < groups.Count())
{
auto newFirstGroup = groups[firstGroupCount];
auto newLastGroup = groups[groups.Count() - lastGroupCount - 1];
DEFINE_COUNT(_f, newFirstGroup->GetToolstripItems().Count(), 0);
vint delta_f = DELTA(_f);
DEFINE_COUNT(_l, 0, newLastGroup->GetToolstripItems().Count());
vint delta_l = DELTA(_l);
vint delta = MIN(delta_o, MIN(delta_f, delta_l));
if (delta == delta_f)
{
firstGroupCount++;
count1_o = count1_f;
count2_o = count2_f;
count3_o = count3_f;
delta_o = delta_f;
}
else if (delta == delta_l)
{
lastGroupCount++;
count1_o = count1_l;
count2_o = count2_l;
count3_o = count3_l;
delta_o = delta_l;
}
else
{
break;
}
}
vint minMiddle = firstGroupCount;
vint maxMiddle = groups.Count() - lastGroupCount - 1;
// TODO: (enumerable) foreach:indexed
for (vint j = 0; j < groups.Count(); j++)
{
shortContainers[
j < minMiddle ? 0 :
j>maxMiddle ? 2 :
1
]->GetToolstripItems().Add(groups[j]);
}
#undef MIN
#undef DEFINE_COUNT
#undef DELTA
}
else if (count == 2)
{
vint firstGroupCount = groups.Count();
{
vint count1 = 0;
vint count2 = From(groups)
.Select([](GuiToolstripGroup* group) {return group->GetToolstripItems().Count(); })
.Aggregate([](vint a, vint b) {return a + b; });
vint delta = abs(count2 - count1);
// TODO: (enumerable) foreach
for (vint i = 0; i < groups.Count(); i++)
{
auto groupCount = groups[i]->GetToolstripItems().Count();
vint count1_2 = count1 + groupCount;
vint count2_2 = count2 - groupCount;
vint delta_2 = abs(count2_2 - count1_2);
if (delta < delta_2)
{
firstGroupCount = i;
break;
}
count1 = count1_2;
count2 = count2_2;
delta = delta_2;
}
}
// TODO: (enumerable) foreach:indexed
for (vint j = 0; j < groups.Count(); j++)
{
longContainers[j < firstGroupCount ? 0 : 1]->GetToolstripItems().Add(groups[j]);
}
}
}
GuiRibbonToolstrips::GuiRibbonToolstrips(theme::ThemeName themeName)
:GuiControl(themeName)
, groups(this)
{
responsiveView = new GuiResponsiveViewComposition();
responsiveView->SetDirection(ResponsiveDirection::Horizontal);
responsiveView->SetAlignmentToParent(Margin(0, 0, 0, 0));
responsiveView->BeforeSwitchingView.AttachMethod(this, &GuiRibbonToolstrips::OnBeforeSwitchingView);
vint toolbarIndex = 0;
// TODO: (enumerable) foreach:indexed
for (vint i = 0; i < sizeof(views) / sizeof(*views); i++)
{
auto containers = i == 0 ? longContainers : shortContainers;
vint count = i == 0 ? 2 : 3;
auto table = new GuiTableComposition();
table->SetAlignmentToParent(Margin(0, 0, 0, 0));
table->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
table->SetRowsAndColumns(count * 2 + 1, 1);
table->SetColumnOption(0, GuiCellOption::MinSizeOption());
table->SetRowOption(0, GuiCellOption::PercentageOption(1.0));
for (vint j = 0; j < count; j++)
{
table->SetRowOption(j * 2 + 1, GuiCellOption::MinSizeOption());
table->SetRowOption(j * 2 + 2, GuiCellOption::PercentageOption(1.0));
}
for (vint j = 0; j < count; j++)
{
auto toolbar = new GuiToolstripToolBar(theme::ThemeName::ToolstripToolBar);
toolbar->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
toolbars[toolbarIndex++] = toolbar;
auto cell = new GuiCellComposition();
cell->SetSite(j * 2 + 1, 0, 1, 1);
cell->AddChild(toolbar->GetBoundsComposition());
table->AddChild(cell);
auto container = new GuiToolstripGroupContainer(theme::ThemeName::CustomControl);
toolbar->GetToolstripItems().Add(container);
containers[j] = container;
}
views[i] = new GuiResponsiveFixedComposition();
views[i]->AddChild(table);
responsiveView->GetViews().Add(views[i]);
}
containerComposition->AddChild(responsiveView);
}
GuiRibbonToolstrips::~GuiRibbonToolstrips()
{
}
collections::ObservableListBase<GuiToolstripGroup*>& GuiRibbonToolstrips::GetGroups()
{
return groups;
}
#undef ARRLEN
/***********************************************************************
GuiRibbonGallery::CommandExecutor
***********************************************************************/
GuiRibbonGallery::CommandExecutor::CommandExecutor(GuiRibbonGallery* _gallery)
:gallery(_gallery)
{
}
GuiRibbonGallery::CommandExecutor::~CommandExecutor()
{
}
void GuiRibbonGallery::CommandExecutor::NotifyScrollUp()
{
gallery->RequestedScrollUp.Execute(gallery->GetNotifyEventArguments());
}
void GuiRibbonGallery::CommandExecutor::NotifyScrollDown()
{
gallery->RequestedScrollDown.Execute(gallery->GetNotifyEventArguments());
}
void GuiRibbonGallery::CommandExecutor::NotifyDropdown()
{
gallery->RequestedDropdown.Execute(gallery->GetNotifyEventArguments());
}
/***********************************************************************
GuiRibbonGallery
***********************************************************************/
void GuiRibbonGallery::BeforeControlTemplateUninstalled_()
{
auto ct = TypedControlTemplateObject(false);
if (!ct) return;
ct->SetCommands(nullptr);
}
void GuiRibbonGallery::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
ct->SetCommands(commandExecutor.Obj());
ct->SetScrollUpEnabled(scrollUpEnabled);
ct->SetScrollDownEnabled(scrollDownEnabled);
}
GuiRibbonGallery::GuiRibbonGallery(theme::ThemeName themeName)
:GuiControl(themeName)
{
commandExecutor = Ptr(new CommandExecutor(this));
ScrollUpEnabledChanged.SetAssociatedComposition(boundsComposition);
ScrollDownEnabledChanged.SetAssociatedComposition(boundsComposition);
RequestedScrollUp.SetAssociatedComposition(boundsComposition);
RequestedScrollDown.SetAssociatedComposition(boundsComposition);
RequestedDropdown.SetAssociatedComposition(boundsComposition);
}
GuiRibbonGallery::~GuiRibbonGallery()
{
}
bool GuiRibbonGallery::GetScrollUpEnabled()
{
return scrollUpEnabled;
}
void GuiRibbonGallery::SetScrollUpEnabled(bool value)
{
if (scrollUpEnabled != value)
{
scrollUpEnabled = value;
TypedControlTemplateObject(true)->SetScrollUpEnabled(value);
}
}
bool GuiRibbonGallery::GetScrollDownEnabled()
{
return scrollDownEnabled;
}
void GuiRibbonGallery::SetScrollDownEnabled(bool value)
{
if (scrollDownEnabled != value)
{
scrollDownEnabled = value;
TypedControlTemplateObject(true)->SetScrollDownEnabled(value);
}
}
/***********************************************************************
GuiRibbonToolstripMenu
***********************************************************************/
void GuiRibbonToolstripMenu::BeforeControlTemplateUninstalled_()
{
auto ct = TypedControlTemplateObject(false);
if (!ct) return;
if (auto cc = ct->GetContentComposition())
{
cc->RemoveChild(contentComposition);
}
}
void GuiRibbonToolstripMenu::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
if (auto cc = ct->GetContentComposition())
{
cc->AddChild(contentComposition);
}
}
GuiRibbonToolstripMenu::GuiRibbonToolstripMenu(theme::ThemeName themeName, GuiControl* owner)
:GuiToolstripMenu(themeName, owner)
{
contentComposition = new GuiBoundsComposition();
contentComposition->SetAlignmentToParent(Margin(0, 0, 0, 0));
contentComposition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
}
GuiRibbonToolstripMenu::~GuiRibbonToolstripMenu()
{
if (!contentComposition->GetParent())
{
SafeDeleteComposition(contentComposition);
}
}
compositions::GuiGraphicsComposition* GuiRibbonToolstripMenu::GetContentComposition()
{
return contentComposition;
}
}
}
}
/***********************************************************************
.\CONTROLS\TOOLSTRIPPACKAGE\GUIRIBBONGALLERYLIST.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace reflection::description;
using namespace collections;
using namespace compositions;
using namespace templates;
namespace list
{
/***********************************************************************
list::GalleryGroup
***********************************************************************/
GalleryGroup::GalleryGroup()
{
}
GalleryGroup::~GalleryGroup()
{
if (eventHandler)
{
itemValues.Cast<IValueObservableList>()->ItemChanged.Remove(eventHandler);
}
}
WString GalleryGroup::GetName()
{
return name;
}
Ptr<IValueList> GalleryGroup::GetItemValues()
{
return itemValues;
}
/***********************************************************************
list::GroupedDataSource
***********************************************************************/
void GroupedDataSource::RebuildItemSource()
{
ignoreGroupChanged = true;
joinedItemSource.Clear();
groupedItemSource.Clear();
cachedGroupItemCounts.Clear();
ignoreGroupChanged = false;
if (itemSource)
{
if (GetGroupEnabled())
{
for (auto [groupValue, index] : indexed(GetLazyList<Value>(itemSource)))
{
auto group = Ptr(new GalleryGroup);
group->name = titleProperty(groupValue);
group->itemValues = GetChildren(childrenProperty(groupValue));
AttachGroupChanged(group, index);
groupedItemSource.Add(group);
}
}
else
{
auto group = Ptr(new GalleryGroup);
group->itemValues = GetChildren(itemSource);
AttachGroupChanged(group, 0);
groupedItemSource.Add(group);
}
}
}
Ptr<IValueList> GroupedDataSource::GetChildren(Ptr<IValueEnumerable> children)
{
if (!children)
{
return nullptr;
}
else if (auto list = children.Cast<IValueList>())
{
return list;
}
else
{
return IValueList::Create(GetLazyList<Value>(children));
}
}
void GroupedDataSource::AttachGroupChanged(Ptr<GalleryGroup> group, vint index)
{
if (auto observable = group->itemValues.Cast<IValueObservableList>())
{
group->eventHandler = observable->ItemChanged.Add([this, index](vint start, vint oldCount, vint newCount)
{
OnGroupItemChanged(index, start, oldCount, newCount);
});
}
}
void GroupedDataSource::OnGroupChanged(vint start, vint oldCount, vint newCount)
{
if (!ignoreGroupChanged)
{
for (vint i = 0; i < oldCount; i++)
{
RemoveGroupFromJoined(start);
}
for (vint i = 0; i < newCount; i++)
{
InsertGroupToJoined(start + i);
}
}
}
void GroupedDataSource::OnGroupItemChanged(vint index, vint start, vint oldCount, vint newCount)
{
if (!ignoreGroupChanged)
{
vint countBeforeGroup = GetCountBeforeGroup(index);
vint joinedIndex = countBeforeGroup + start;
vint minCount = oldCount < newCount ? oldCount : newCount;
auto itemValues = groupedItemSource[index]->itemValues;
for (vint i = 0; i < minCount; i++)
{
joinedItemSource.Set(joinedIndex + i, itemValues->Get(start + i));
}
if (oldCount < newCount)
{
for (vint i = minCount; i < newCount; i++)
{
joinedItemSource.Insert(joinedIndex + i, itemValues->Get(start + i));
}
}
else if (oldCount > newCount)
{
for (vint i = minCount; i < oldCount; i++)
{
joinedItemSource.RemoveAt(joinedIndex + i);
}
}
cachedGroupItemCounts[index] += newCount - oldCount;
}
}
vint GroupedDataSource::GetCountBeforeGroup(vint index)
{
vint count = 0;
for (vint i = 0; i < index; i++)
{
count += cachedGroupItemCounts[i];
}
return count;
}
void GroupedDataSource::InsertGroupToJoined(vint index)
{
vint countBeforeGroup = GetCountBeforeGroup(index);
auto group = groupedItemSource[index];
vint itemCount = group->itemValues ? group->itemValues->GetCount() : 0;
cachedGroupItemCounts.Insert(index, itemCount);
if (itemCount > 0)
{
for (vint i = 0; i < itemCount; i++)
{
joinedItemSource.Insert(countBeforeGroup + i, group->itemValues->Get(i));
}
}
}
void GroupedDataSource::RemoveGroupFromJoined(vint index)
{
vint countBeforeGroup = GetCountBeforeGroup(index);
joinedItemSource.RemoveRange(countBeforeGroup, cachedGroupItemCounts[index]);
cachedGroupItemCounts.RemoveAt(index);
}
GroupedDataSource::GroupedDataSource(compositions::GuiGraphicsComposition* _associatedComposition)
:associatedComposition(_associatedComposition)
{
GroupEnabledChanged.SetAssociatedComposition(associatedComposition);
GroupTitlePropertyChanged.SetAssociatedComposition(associatedComposition);
GroupChildrenPropertyChanged.SetAssociatedComposition(associatedComposition);
auto vol = UnboxValue<Ptr<IValueObservableList>>(BoxParameter(groupedItemSource));
groupChangedHandler = vol->ItemChanged.Add(this, &GroupedDataSource::OnGroupChanged);
}
GroupedDataSource::~GroupedDataSource()
{
auto vol = UnboxValue<Ptr<IValueObservableList>>(BoxParameter(joinedItemSource));
vol->ItemChanged.Remove(groupChangedHandler);
}
Ptr<IValueEnumerable> GroupedDataSource::GetItemSource()
{
return itemSource;
}
void GroupedDataSource::SetItemSource(Ptr<IValueEnumerable> value)
{
if (itemSource != value)
{
itemSource = value;
RebuildItemSource();
}
}
bool GroupedDataSource::GetGroupEnabled()
{
return titleProperty && childrenProperty;
}
ItemProperty<WString> GroupedDataSource::GetGroupTitleProperty()
{
return titleProperty;
}
void GroupedDataSource::SetGroupTitleProperty(const ItemProperty<WString>& value)
{
if (titleProperty != value)
{
titleProperty = value;
GroupTitlePropertyChanged.Execute(GuiEventArgs(associatedComposition));
GroupEnabledChanged.Execute(GuiEventArgs(associatedComposition));
RebuildItemSource();
}
}
ItemProperty<Ptr<IValueEnumerable>> GroupedDataSource::GetGroupChildrenProperty()
{
return childrenProperty;
}
void GroupedDataSource::SetGroupChildrenProperty(const ItemProperty<Ptr<IValueEnumerable>>& value)
{
if (childrenProperty != value)
{
childrenProperty = value;
GroupChildrenPropertyChanged.Execute(GuiEventArgs(associatedComposition));
GroupEnabledChanged.Execute(GuiEventArgs(associatedComposition));
RebuildItemSource();
}
}
const GroupedDataSource::GalleryGroupList& GroupedDataSource::GetGroups()
{
return groupedItemSource;
}
}
/***********************************************************************
GuiBindableRibbonGalleryList
***********************************************************************/
void GuiBindableRibbonGalleryList::BeforeControlTemplateUninstalled_()
{
}
void GuiBindableRibbonGalleryList::AfterControlTemplateInstalled_(bool initialize)
{
auto ct = TypedControlTemplateObject(true);
itemList->SetControlTemplate(ct->GetItemListTemplate());
subMenu->SetControlTemplate(ct->GetMenuTemplate());
groupContainer->SetControlTemplate(ct->GetGroupContainerTemplate());
MenuResetGroupTemplate();
UpdateLayoutSizeOffset();
}
void GuiBindableRibbonGalleryList::UpdateLayoutSizeOffset()
{
auto cSize = itemList->GetContainerComposition()->GetCachedBounds();
auto bSize = itemList->GetBoundsComposition()->GetCachedBounds();
layout->SetSizeOffset(Size(bSize.Width() - cSize.Width(), bSize.Height() - cSize.Height()));
if (layout->GetItemWidth() > 0)
{
vint columns = layout->GetVisibleItemCount();
if (columns == 0) columns = 1;
vint rows = (visibleItemCount + columns - 1) / columns;
vint height = (vint)(layout->GetCachedBounds().Height()*(rows + 0.5));
groupContainer->GetBoundsComposition()->SetPreferredMinSize(Size(0, height));
}
else
{
groupContainer->GetBoundsComposition()->SetPreferredMinSize(Size(0, 0));
}
}
void GuiBindableRibbonGalleryList::OnItemListSelectionChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
auto pos = IndexToGalleryPos(itemList->GetSelectedItemIndex());
// TODO: (enumerable) foreach
for (vint i = 0; i < groupedItemSource.Count(); i++)
{
auto group = groupedItemSource[i];
if (group->GetItemValues())
{
vint count = group->GetItemValues()->GetCount();
for (vint j = 0; j < count; j++)
{
auto background = MenuGetGroupItemBackground(i, j);
background->SetSelected(pos.group == i && pos.item == j);
}
}
}
if (!skipItemAppliedEvent && itemList->GetSelectedItemIndex() != -1)
{
GuiItemEventArgs itemAppliedArgs(boundsComposition);
itemAppliedArgs.itemIndex = itemList->GetSelectedItemIndex();
ItemApplied.Execute(itemAppliedArgs);
}
SelectionChanged.Execute(GetNotifyEventArguments());
}
void GuiBindableRibbonGalleryList::OnItemListItemMouseEnter(compositions::GuiGraphicsComposition* sender, compositions::GuiItemEventArgs& arguments)
{
StartPreview(arguments.itemIndex);
}
void GuiBindableRibbonGalleryList::OnItemListItemMouseLeave(compositions::GuiGraphicsComposition* sender, compositions::GuiItemEventArgs& arguments)
{
StopPreview(arguments.itemIndex);
}
void GuiBindableRibbonGalleryList::OnCachedBoundsChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
UpdateLayoutSizeOffset();
auto bounds = boundsComposition->GetCachedBounds();
subMenu->GetBoundsComposition()->SetPreferredMinSize(Size(bounds.Width() + 20, 1));
// TODO: (enumerable) foreach
for (vint i = 0; i < groupedItemSource.Count(); i++)
{
auto group = groupedItemSource[i];
if (group->GetItemValues())
{
vint count = group->GetItemValues()->GetCount();
for (vint j = 0; j < count; j++)
{
auto background = MenuGetGroupItemBackground(i, j);
background->GetBoundsComposition()->SetPreferredMinSize(Size(0, bounds.Height()));
}
}
}
}
void GuiBindableRibbonGalleryList::OnRequestedDropdown(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
subMenu->ShowPopup(this, Point(0, 0));
}
void GuiBindableRibbonGalleryList::OnRequestedScrollUp(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
itemListArranger->ScrollUp();
}
void GuiBindableRibbonGalleryList::OnRequestedScrollDown(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
itemListArranger->ScrollDown();
}
void GuiBindableRibbonGalleryList::MenuResetGroupTemplate()
{
groupStack->SetItemTemplate([this](const Value& groupValue)->GuiTemplate*
{
auto group = UnboxValue<Ptr<list::GalleryGroup>>(groupValue);
auto groupTemplate = new GuiTemplate;
groupTemplate->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
auto groupContentStack = new GuiStackComposition;
groupContentStack->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
groupContentStack->SetAlignmentToParent(Margin(0, 0, 0, 0));
groupContentStack->SetDirection(GuiStackComposition::Vertical);
{
auto item = new GuiStackItemComposition;
groupContentStack->AddChild(item);
auto header = new GuiControl(theme::ThemeName::RibbonToolstripHeader);
header->SetControlTemplate(TypedControlTemplateObject(true)->GetHeaderTemplate());
header->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
header->SetText(group->GetName());
item->AddChild(header->GetBoundsComposition());
}
if (itemStyle)
{
auto item = new GuiStackItemComposition;
item->SetPreferredMinSize(Size(1, 1));
groupContentStack->AddChild(item);
auto groupItemFlow = new GuiRepeatFlowComposition();
groupItemFlow->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
groupItemFlow->SetAlignmentToParent(Margin(0, 0, 0, 0));
groupItemFlow->SetItemSource(group->GetItemValues());
groupItemFlow->SetItemTemplate([=](const Value& groupItemValue)->GuiTemplate*
{
auto groupItemTemplate = new GuiTemplate;
groupItemTemplate->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
auto backgroundButton = new GuiSelectableButton(theme::ThemeName::ListItemBackground);
if (auto style = TypedControlTemplateObject(true)->GetBackgroundTemplate())
{
backgroundButton->SetControlTemplate(style);
}
backgroundButton->SetAutoFocus(false);
backgroundButton->SetAutoSelection(false);
backgroundButton->Clicked.AttachLambda([=](GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
auto groupIndex = groupStack->GetStackItems().IndexOf(dynamic_cast<GuiStackItemComposition*>(groupTemplate->GetParent()));
auto itemIndex = groupItemFlow->GetFlowItems().IndexOf(dynamic_cast<GuiFlowItemComposition*>(groupItemTemplate->GetParent()));
auto index = GalleryPosToIndex({ groupIndex,itemIndex });
itemList->SetSelected(index, true);
itemList->EnsureItemVisible(index);
subMenu->Close();
});
backgroundButton->GetBoundsComposition()->GetEventReceiver()->mouseEnter.AttachLambda([=](GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
auto groupIndex = groupStack->GetStackItems().IndexOf(dynamic_cast<GuiStackItemComposition*>(groupTemplate->GetParent()));
auto itemIndex = groupItemFlow->GetFlowItems().IndexOf(dynamic_cast<GuiFlowItemComposition*>(groupItemTemplate->GetParent()));
auto index = GalleryPosToIndex({ groupIndex,itemIndex });
StartPreview(index);
});
backgroundButton->GetBoundsComposition()->GetEventReceiver()->mouseLeave.AttachLambda([=](GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
auto groupIndex = groupStack->GetStackItems().IndexOf(dynamic_cast<GuiStackItemComposition*>(groupTemplate->GetParent()));
auto itemIndex = groupItemFlow->GetFlowItems().IndexOf(dynamic_cast<GuiFlowItemComposition*>(groupItemTemplate->GetParent()));
auto index = GalleryPosToIndex({ groupIndex,itemIndex });
StopPreview(index);
});
groupItemTemplate->AddChild(backgroundButton->GetBoundsComposition());
auto itemTemplate = itemStyle(groupItemValue);
itemTemplate->SetAlignmentToParent(Margin(0, 0, 0, 0));
backgroundButton->GetContainerComposition()->AddChild(itemTemplate);
return groupItemTemplate;
});
item->AddChild(groupItemFlow);
}
groupTemplate->AddChild(groupContentStack);
return groupTemplate;
});
}
GuiControl* GuiBindableRibbonGalleryList::MenuGetGroupHeader(vint groupIndex)
{
CHECK_ERROR(0 <= groupIndex && groupIndex < groupedItemSource.Count(), L"GuiBindableRibbonGalleryList::MenuGetGroupHeader(vint)#Group index out of range");
auto stackItem = groupStack->GetStackItems()[groupIndex];
auto groupTemplate = stackItem->Children()[0];
auto groupContentStack = dynamic_cast<GuiStackComposition*>(groupTemplate->Children()[0]);
auto groupHeaderItem = groupContentStack->GetStackItems()[0];
auto groupHeader = groupHeaderItem->Children()[0]->GetAssociatedControl();
CHECK_ERROR(groupHeader, L"GuiBindableRibbonGalleryList::MenuGetGroupHeader(vint)#Internal error.");
return groupHeader;
}
compositions::GuiRepeatFlowComposition* GuiBindableRibbonGalleryList::MenuGetGroupFlow(vint groupIndex)
{
CHECK_ERROR(0 <= groupIndex && groupIndex < groupedItemSource.Count(), L"GuiBindableRibbonGalleryList::MenuGetGroupFlow(vint)#Group index out of range");
if (!itemStyle) return nullptr;
auto stackItem = groupStack->GetStackItems()[groupIndex];
auto groupTemplate = stackItem->Children()[0];
auto groupContentStack = dynamic_cast<GuiStackComposition*>(groupTemplate->Children()[0]);
auto groupContentItem = groupContentStack->GetStackItems()[1];
auto groupFlow = dynamic_cast<GuiRepeatFlowComposition*>(groupContentItem->Children()[0]);
CHECK_ERROR(groupFlow, L"GuiBindableRibbonGalleryList::MenuGetGroupHeader(vint)#Internal error.");
return groupFlow;
}
GuiSelectableButton* GuiBindableRibbonGalleryList::MenuGetGroupItemBackground(vint groupIndex, vint itemIndex)
{
CHECK_ERROR(0 <= groupIndex && groupIndex < groupedItemSource.Count(), L"GuiBindableRibbonGalleryList::MenuGetGroupItemBackground(vint, vint)#Group index out of range");
auto group = groupedItemSource[groupIndex];
CHECK_ERROR(group->GetItemValues() && 0 <= itemIndex && itemIndex < group->GetItemValues()->GetCount(), L"GuiBindableRibbonGalleryList::MenuGetGroupHeader(vint, vint)#Item index out of range");
auto groupFlow = MenuGetGroupFlow(groupIndex);
auto groupFlowItem = groupFlow->GetFlowItems()[itemIndex];
auto groupItemTemplate = groupFlowItem->Children()[0];
auto groupItemBackground = dynamic_cast<GuiSelectableButton*>(groupItemTemplate->Children()[0]->GetAssociatedControl());
CHECK_ERROR(groupItemBackground, L"GuiBindableRibbonGalleryList::MenuGetGroupHeader(vint, vint)#Internal error.");
return groupItemBackground;
}
void GuiBindableRibbonGalleryList::StartPreview(vint index)
{
if (index != itemList->GetSelectedItemIndex())
{
GuiItemEventArgs previewArgs(boundsComposition);
previewArgs.itemIndex = index;
PreviewStarted.Execute(previewArgs);
}
}
void GuiBindableRibbonGalleryList::StopPreview(vint index)
{
if (index != itemList->GetSelectedItemIndex())
{
GuiItemEventArgs previewArgs(boundsComposition);
previewArgs.itemIndex = index;
PreviewStopped.Execute(previewArgs);
}
}
GuiMenu* GuiBindableRibbonGalleryList::ProvideDropdownMenu()
{
return GetSubMenu();
}
GuiBindableRibbonGalleryList::GuiBindableRibbonGalleryList(theme::ThemeName themeName)
:GuiRibbonGallery(themeName)
, GroupedDataSource(boundsComposition)
{
ItemTemplateChanged.SetAssociatedComposition(boundsComposition);
SelectionChanged.SetAssociatedComposition(boundsComposition);
PreviewStarted.SetAssociatedComposition(boundsComposition);
PreviewStopped.SetAssociatedComposition(boundsComposition);
ItemApplied.SetAssociatedComposition(boundsComposition);
subMenu = new GuiRibbonToolstripMenu(theme::ThemeName::RibbonToolstripMenu, this);
{
layout = new ribbon_impl::GalleryResponsiveLayout;
layout->SetAlignmentToParent(Margin(0, 0, 0, 0));
containerComposition->AddChild(layout);
itemListArranger = new ribbon_impl::GalleryItemArranger(this);
itemList = new GuiBindableTextList(theme::ThemeName::RibbonGalleryItemList);
itemList->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
itemList->SetArranger(Ptr(itemListArranger));
itemList->SetItemSource(UnboxValue<Ptr<IValueObservableList>>(BoxParameter(joinedItemSource)));
itemList->SelectionChanged.AttachMethod(this, &GuiBindableRibbonGalleryList::OnItemListSelectionChanged);
itemList->ItemMouseEnter.AttachMethod(this, &GuiBindableRibbonGalleryList::OnItemListItemMouseEnter);
itemList->ItemMouseLeave.AttachMethod(this, &GuiBindableRibbonGalleryList::OnItemListItemMouseLeave);
layout->AddChild(itemList->GetBoundsComposition());
}
{
groupContainer = new GuiScrollContainer(theme::ThemeName::ScrollView);
groupContainer->SetHorizontalAlwaysVisible(false);
groupContainer->SetVerticalAlwaysVisible(false);
groupContainer->SetExtendToFullWidth(true);
groupContainer->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
subMenu->GetContentComposition()->AddChild(groupContainer->GetBoundsComposition());
groupStack = new GuiRepeatStackComposition();
groupStack->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
groupStack->SetAlignmentToParent(Margin(0, 0, 0, 0));
groupStack->SetDirection(GuiStackComposition::Vertical);
groupStack->SetItemSource(UnboxValue<Ptr<IValueObservableList>>(BoxParameter(groupedItemSource)));
groupContainer->GetContainerComposition()->AddChild(groupStack);
MenuResetGroupTemplate();
}
RequestedScrollUp.AttachMethod(this, &GuiBindableRibbonGalleryList::OnRequestedScrollUp);
RequestedScrollDown.AttachMethod(this, &GuiBindableRibbonGalleryList::OnRequestedScrollDown);
RequestedDropdown.AttachMethod(this, &GuiBindableRibbonGalleryList::OnRequestedDropdown);
boundsComposition->CachedBoundsChanged.AttachMethod(this, &GuiBindableRibbonGalleryList::OnCachedBoundsChanged);
itemListArranger->UnblockScrollUpdate();
}
GuiBindableRibbonGalleryList::~GuiBindableRibbonGalleryList()
{
delete subMenu;
}
GuiBindableRibbonGalleryList::ItemStyleProperty GuiBindableRibbonGalleryList::GetItemTemplate()
{
return itemStyle;
}
void GuiBindableRibbonGalleryList::SetItemTemplate(ItemStyleProperty value)
{
if (itemStyle != value)
{
itemStyle = value;
itemList->SetItemTemplate(value);
ItemTemplateChanged.Execute(GetNotifyEventArguments());
}
}
GalleryPos GuiBindableRibbonGalleryList::IndexToGalleryPos(vint index)
{
if (0 <= index && index < joinedItemSource.Count())
{
for (auto [group, groupIndex] : indexed(groupedItemSource))
{
auto itemValues = group->GetItemValues();
vint itemCount = itemValues ? itemValues->GetCount() : 0;
if (index >= itemCount)
{
index -= itemCount;
}
else
{
return GalleryPos(groupIndex, index);
}
}
}
return {};
}
vint GuiBindableRibbonGalleryList::GalleryPosToIndex(GalleryPos pos)
{
if (0 <= pos.group && pos.group < groupedItemSource.Count())
{
auto countBeforeGroup = GetCountBeforeGroup(pos.group);
auto itemValues = groupedItemSource[pos.group]->GetItemValues();
vint itemCount = itemValues ? itemValues->GetCount() : 0;
if (0 <= pos.item && pos.item < itemCount)
{
return countBeforeGroup + pos.item;
}
}
return -1;
}
vint GuiBindableRibbonGalleryList::GetMinCount()
{
return layout->GetMinCount();
}
void GuiBindableRibbonGalleryList::SetMinCount(vint value)
{
layout->SetMinCount(value);
}
vint GuiBindableRibbonGalleryList::GetMaxCount()
{
return layout->GetMaxCount();
}
void GuiBindableRibbonGalleryList::SetMaxCount(vint value)
{
layout->SetMaxCount(value);
}
vint GuiBindableRibbonGalleryList::GetSelectedIndex()
{
return itemList->GetSelectedItemIndex();
}
description::Value GuiBindableRibbonGalleryList::GetSelectedItem()
{
vint index = itemList->GetSelectedItemIndex();
if (index == -1) return Value();
auto pos = IndexToGalleryPos(index);
return groupedItemSource[pos.group]->GetItemValues()->Get(pos.item);
}
void GuiBindableRibbonGalleryList::ApplyItem(vint index)
{
if (index == -1)
{
itemList->ClearSelection();
}
else
{
itemList->SetSelected(index, true);
itemList->EnsureItemVisible(index);
}
}
void GuiBindableRibbonGalleryList::SelectItem(vint index)
{
skipItemAppliedEvent = true;
ApplyItem(index);
skipItemAppliedEvent = false;
}
vint GuiBindableRibbonGalleryList::GetVisibleItemCount()
{
return visibleItemCount;
}
void GuiBindableRibbonGalleryList::SetVisibleItemCount(vint value)
{
if (visibleItemCount != value)
{
visibleItemCount = value;
UpdateLayoutSizeOffset();
}
}
GuiToolstripMenu* GuiBindableRibbonGalleryList::GetSubMenu()
{
return subMenu;
}
IDescriptable* GuiBindableRibbonGalleryList::QueryService(const WString& identifier)
{
if (identifier == IGuiMenuDropdownProvider::Identifier)
{
return (IGuiMenuDropdownProvider*)this;
}
else
{
return GuiRibbonGallery::QueryService(identifier);
}
}
}
}
}
/***********************************************************************
.\CONTROLS\TOOLSTRIPPACKAGE\GUIRIBBONIMPL.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace compositions;
/***********************************************************************
GalleryItemArrangerRepeatComposition
***********************************************************************/
namespace ribbon_impl
{
void GalleryItemArrangerRepeatComposition::Layout_BeginPlaceItem(bool firstPhase, Rect newBounds, vint& newStartIndex)
{
if (firstPhase)
{
pim_itemWidth = itemWidth;
newStartIndex = firstIndex;
}
}
compositions::VirtualRepeatPlaceItemResult GalleryItemArrangerRepeatComposition::Layout_PlaceItem(bool firstPhase, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent)
{
alignmentToParent = Margin(-1, 0, -1, 0);
bounds = Rect(Point((index - firstIndex) * itemWidth, 0), Size(itemWidth, 0));
if (firstPhase)
{
vint styleWidth = Layout_GetStylePreferredSize(style).x;
if (pim_itemWidth < styleWidth)
{
pim_itemWidth = styleWidth;
}
}
if (bounds.Right() + pim_itemWidth > viewBounds.Right())
{
return VirtualRepeatPlaceItemResult::HitLastItem;
}
else
{
return VirtualRepeatPlaceItemResult::None;
}
}
compositions::VirtualRepeatEndPlaceItemResult GalleryItemArrangerRepeatComposition::Layout_EndPlaceItem(bool firstPhase, Rect newBounds, vint newStartIndex)
{
bool result = false;
if (firstPhase)
{
if (pim_itemWidth != itemWidth)
{
itemWidth = pim_itemWidth;
result = true;
}
}
if (!blockScrollUpdate)
{
UnblockScrollUpdate();
}
return result ?
VirtualRepeatEndPlaceItemResult::TotalSizeUpdated :
VirtualRepeatEndPlaceItemResult::None;
}
void GalleryItemArrangerRepeatComposition::Layout_EndLayout(bool totalSizeUpdated)
{
}
void GalleryItemArrangerRepeatComposition::Layout_InvalidateItemSizeCache()
{
itemWidth = 1;
}
void GalleryItemArrangerRepeatComposition::Layout_CalculateTotalSize(Size& full, Size& minimum)
{
full = Size(1, 1);
minimum = Size(1, 1);
}
Size GalleryItemArrangerRepeatComposition::Layout_GetAdoptedSize(Size expectedSize)
{
return Size(1, 1);
}
GalleryItemArrangerRepeatComposition::GalleryItemArrangerRepeatComposition(GuiBindableRibbonGalleryList* _owner)
:owner(_owner)
{
}
GalleryItemArrangerRepeatComposition::~GalleryItemArrangerRepeatComposition()
{
}
vint GalleryItemArrangerRepeatComposition::FindItemByVirtualKeyDirection(vint itemIndex, compositions::KeyDirection key)
{
vint count = itemSource->GetCount();
if (itemIndex < 0 || itemIndex >= count) return -1;
vint groupCount = viewBounds.Width() / itemWidth;
if (groupCount == 0) groupCount = 1;
switch (key)
{
case KeyDirection::Left:
itemIndex--;
break;
case KeyDirection::Right:
itemIndex++;
break;
case KeyDirection::Home:
itemIndex = 0;
break;
case KeyDirection::End:
itemIndex = count;
break;
case KeyDirection::PageUp:
itemIndex -= groupCount;
break;
case KeyDirection::PageDown:
itemIndex += groupCount;
break;
default:
return -1;
}
if (itemIndex < 0) return 0;
else if (itemIndex >= count) return count - 1;
else return itemIndex;
}
compositions::VirtualRepeatEnsureItemVisibleResult GalleryItemArrangerRepeatComposition::EnsureItemVisible(vint itemIndex)
{
if (!itemSource) return VirtualRepeatEnsureItemVisibleResult::NotMoved;
if (itemIndex < 0 || itemIndex >= itemSource->GetCount())
{
return VirtualRepeatEnsureItemVisibleResult::ItemNotExists;
}
vint groupCount = viewBounds.Width() / itemWidth;
if (groupCount == 0) groupCount = 1;
if (itemIndex < firstIndex)
{
firstIndex = itemIndex;
InvalidateLayout();
}
else if (itemIndex >= firstIndex + groupCount)
{
firstIndex = itemIndex - groupCount + 1;
InvalidateLayout();
}
return VirtualRepeatEnsureItemVisibleResult::NotMoved;
}
void GalleryItemArrangerRepeatComposition::ScrollUp()
{
vint count = itemSource->GetCount();
vint groupCount = viewBounds.Width() / itemWidth;
if (groupCount == 0) groupCount = 1;
if (count > groupCount)
{
firstIndex -= groupCount;
if (firstIndex < 0)
{
firstIndex = 0;
}
InvalidateLayout();
}
}
void GalleryItemArrangerRepeatComposition::ScrollDown()
{
vint count = itemSource->GetCount();
vint groupCount = viewBounds.Width() / itemWidth;
if (groupCount == 0) groupCount = 1;
if (count > groupCount)
{
firstIndex += groupCount;
if (firstIndex > count - groupCount)
{
firstIndex = count - groupCount;
}
InvalidateLayout();
}
}
void GalleryItemArrangerRepeatComposition::UnblockScrollUpdate()
{
blockScrollUpdate = false;
vint count = itemSource->GetCount();
vint groupCount = viewBounds.Width() / pim_itemWidth;
if (groupCount == 0) groupCount = 1;
owner->SetScrollUpEnabled(firstIndex > 0);
owner->SetScrollDownEnabled(firstIndex + groupCount < count);
if (owner->layout->GetItemWidth() != pim_itemWidth)
{
owner->layout->SetItemWidth(pim_itemWidth);
owner->UpdateLayoutSizeOffset();
}
}
/***********************************************************************
GalleryItemArranger
***********************************************************************/
GalleryItemArranger::GalleryItemArranger(GuiBindableRibbonGalleryList* _owner)
: TBase(new TBase::ArrangerRepeatComposition(this, _owner))
{
}
GalleryItemArranger::~GalleryItemArranger()
{
}
void GalleryItemArranger::ScrollUp()
{
GetRepeatComposition()->ScrollUp();
}
void GalleryItemArranger::ScrollDown()
{
GetRepeatComposition()->ScrollDown();
}
void GalleryItemArranger::UnblockScrollUpdate()
{
GetRepeatComposition()->UnblockScrollUpdate();
}
/***********************************************************************
GalleryResponsiveLayout
***********************************************************************/
void GalleryResponsiveLayout::UpdateMinSize()
{
SetPreferredMinSize(Size(itemCount * itemWidth + sizeOffset.x, sizeOffset.y));
}
GalleryResponsiveLayout::GalleryResponsiveLayout()
{
SetDirection(ResponsiveDirection::Horizontal);
}
GalleryResponsiveLayout::~GalleryResponsiveLayout()
{
}
vint GalleryResponsiveLayout::GetMinCount()
{
return minCount;
}
vint GalleryResponsiveLayout::GetMaxCount()
{
return maxCount;
}
vint GalleryResponsiveLayout::GetItemWidth()
{
return itemWidth;
}
Size GalleryResponsiveLayout::GetSizeOffset()
{
return sizeOffset;
}
vint GalleryResponsiveLayout::GetVisibleItemCount()
{
return itemCount;
}
void GalleryResponsiveLayout::SetMinCount(vint value)
{
vint oldCount = GetLevelCount();
vint oldLevel = GetCurrentLevel();
if (minCount != value)
{
if (value < 0) value = 0;
minCount = value;
if (maxCount < minCount) maxCount = minCount;
if (itemCount < minCount) itemCount = minCount;
UpdateMinSize();
}
bool countChanged = oldCount != GetLevelCount();
bool levelChanged = oldLevel != GetCurrentLevel();
if (countChanged) LevelCountChanged.Execute(GuiEventArgs(this));
if (levelChanged) CurrentLevelChanged.Execute(GuiEventArgs(this));
if (countChanged || levelChanged) OnResponsiveChildLevelUpdated();
}
void GalleryResponsiveLayout::SetMaxCount(vint value)
{
vint oldCount = GetLevelCount();
vint oldLevel = GetCurrentLevel();
if (maxCount != value)
{
if (value < 0) value = 0;
maxCount = value;
if (minCount > maxCount) minCount = maxCount;
if (itemCount > maxCount) itemCount = maxCount;
UpdateMinSize();
}
if (oldCount != GetLevelCount()) LevelCountChanged.Execute(GuiEventArgs(this));
if (oldLevel != GetCurrentLevel()) CurrentLevelChanged.Execute(GuiEventArgs(this));
}
void GalleryResponsiveLayout::SetItemWidth(vint value)
{
if (itemWidth != value)
{
itemWidth = value;
UpdateMinSize();
}
}
void GalleryResponsiveLayout::SetSizeOffset(Size value)
{
if (sizeOffset != value)
{
sizeOffset = value;
UpdateMinSize();
}
}
vint GalleryResponsiveLayout::GetLevelCount()
{
return maxCount - minCount + 1;
}
vint GalleryResponsiveLayout::GetCurrentLevel()
{
return itemCount - minCount;
}
bool GalleryResponsiveLayout::LevelDown()
{
if (itemCount > minCount)
{
itemCount--;
UpdateMinSize();
CurrentLevelChanged.Execute(GuiEventArgs(this));
return true;
}
return false;
}
bool GalleryResponsiveLayout::LevelUp()
{
if (itemCount < maxCount)
{
itemCount++;
UpdateMinSize();
CurrentLevelChanged.Execute(GuiEventArgs(this));
return true;
}
return false;
}
}
}
}
}
/***********************************************************************
.\CONTROLS\TOOLSTRIPPACKAGE\GUITOOLSTRIPCOMMAND.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace collections;
using namespace compositions;
using namespace regex;
/***********************************************************************
GuiToolstripCommand
***********************************************************************/
void GuiToolstripCommand::OnShortcutKeyItemExecuted(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (enabled)
{
Executed.ExecuteWithNewSender(arguments, sender);
}
}
void GuiToolstripCommand::OnRenderTargetChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
UpdateShortcutOwner();
}
void GuiToolstripCommand::InvokeDescriptionChanged()
{
GuiEventArgs arguments;
DescriptionChanged.Execute(arguments);
}
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::RemoveShortcut()
{
if (shortcutKeyItem)
{
shortcutKeyItem->Executed.Detach(shortcutKeyItemExecutedHandler);
shortcutKeyItem->GetManager()->DestroyShortcut(shortcutKeyItem);
}
shortcutKeyItem = nullptr;
shortcutKeyItemExecutedHandler = nullptr;
}
void GuiToolstripCommand::ReplaceShortcut(compositions::IGuiShortcutKeyItem* value)
{
if (shortcutKeyItem != value)
{
RemoveShortcut();
if (value)
{
shortcutKeyItem = value;
shortcutKeyItemExecutedHandler = shortcutKeyItem->Executed.AttachMethod(this, &GuiToolstripCommand::OnShortcutKeyItemExecuted);
}
InvokeDescriptionChanged();
}
}
void GuiToolstripCommand::BuildShortcut(const WString& builderText)
{
List<glr::ParsingError> errors;
if (auto parser = GetParserManager()->GetParser<ShortcutBuilder>(L"SHORTCUT"))
{
if (auto builder = parser->ParseInternal(builderText, errors))
{
shortcutBuilder = builder;
if (auto shortcutKeyManager = GetShortcutManagerFromBuilder(builder))
{
if (auto item = shortcutKeyManager->CreateShortcutIfNotExist(builder->ctrl, builder->shift, builder->alt, builder->key))
{
ReplaceShortcut(item);
}
}
}
}
}
void GuiToolstripCommand::UpdateShortcutOwner()
{
GuiControlHost* host = nullptr;
if (auto control = dynamic_cast<GuiControl*>(attachedRootObject))
{
host = control->GetRelatedControlHost();
}
else if (auto composition = dynamic_cast<GuiGraphicsComposition*>(attachedRootObject))
{
host = composition->GetRelatedControlHost();
}
if (attachedControlHost != host)
{
attachedControlHost = host;
if (shortcutBuilder && !shortcutBuilder->global)
{
if (shortcutKeyItem)
{
ReplaceShortcut(nullptr);
}
BuildShortcut(shortcutBuilder->text);
}
}
}
GuiToolstripCommand::GuiToolstripCommand()
{
}
GuiToolstripCommand::~GuiToolstripCommand()
{
RemoveShortcut();
shortcutBuilder = nullptr;
}
void GuiToolstripCommand::Attach(GuiInstanceRootObject* rootObject)
{
GuiGraphicsComposition* rootComposition = nullptr;
if (attachedRootObject != rootObject)
{
if (attachedRootObject)
{
if (auto control = dynamic_cast<GuiControl*>(attachedRootObject))
{
control->ControlSignalTrigerred.Detach(renderTargetChangedHandler);
}
else if (auto composition = dynamic_cast<GuiGraphicsComposition*>(attachedRootObject))
{
composition->GetEventReceiver()->renderTargetChanged.Detach(renderTargetChangedHandler);
}
renderTargetChangedHandler = nullptr;
}
attachedRootObject = rootObject;
if (attachedRootObject)
{
if (auto control = dynamic_cast<GuiControl*>(attachedRootObject))
{
renderTargetChangedHandler = control->ControlSignalTrigerred.AttachLambda(
[=](GuiGraphicsComposition* sender, GuiControlSignalEventArgs& arguments)
{
OnRenderTargetChanged(sender, arguments);
});
}
else if (auto composition = dynamic_cast<GuiGraphicsComposition*>(attachedRootObject))
{
renderTargetChangedHandler = composition->GetEventReceiver()->renderTargetChanged.AttachMethod(this, &GuiToolstripCommand::OnRenderTargetChanged);
}
}
UpdateShortcutOwner();
}
}
void GuiToolstripCommand::Detach(GuiInstanceRootObject* rootObject)
{
Attach(nullptr);
}
Ptr<GuiImageData> GuiToolstripCommand::GetLargeImage()
{
return largeImage;
}
void GuiToolstripCommand::SetLargeImage(Ptr<GuiImageData> value)
{
if (largeImage != value)
{
largeImage = value;
InvokeDescriptionChanged();
}
}
Ptr<GuiImageData> GuiToolstripCommand::GetImage()
{
return image;
}
void GuiToolstripCommand::SetImage(Ptr<GuiImageData> value)
{
if(image!=value)
{
image=value;
InvokeDescriptionChanged();
}
}
const WString& GuiToolstripCommand::GetText()
{
return text;
}
void GuiToolstripCommand::SetText(const WString& value)
{
if(text!=value)
{
text=value;
InvokeDescriptionChanged();
}
}
compositions::IGuiShortcutKeyItem* GuiToolstripCommand::GetShortcut()
{
return shortcutKeyItem;
}
WString GuiToolstripCommand::GetShortcutBuilder()
{
return shortcutBuilder ? shortcutBuilder->text : L"";
}
void GuiToolstripCommand::SetShortcutBuilder(const WString& value)
{
BuildShortcut(value);
}
bool GuiToolstripCommand::GetEnabled()
{
return enabled;
}
void GuiToolstripCommand::SetEnabled(bool value)
{
if(enabled!=value)
{
enabled=value;
InvokeDescriptionChanged();
}
}
bool GuiToolstripCommand::GetSelected()
{
return selected;
}
void GuiToolstripCommand::SetSelected(bool value)
{
if(selected!=value)
{
selected=value;
InvokeDescriptionChanged();
}
}
/***********************************************************************
GuiToolstripCommand::ShortcutBuilder Parser
***********************************************************************/
class GuiToolstripCommandShortcutParser : public Object, public IGuiParser<GuiToolstripCommand::ShortcutBuilder>
{
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"((<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"))
, _key(regexShortcut.CaptureNames().IndexOf(L"key"))
{
}
Ptr<ShortcutBuilder> ParseInternal(const WString& text, collections::List<glr::ParsingError>& errors)override
{
Ptr<RegexMatch> match=regexShortcut.MatchHead(text);
if (match && match->Result().Length() != text.Length())
{
glr::ParsingError error;
error.message = L"Failed to parse a shortcut \"" + text + L"\".";
errors.Add(error);
return nullptr;
}
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);
WString name = match->Groups()[_key][0].Value();
builder->key = GetCurrentController()->InputService()->GetKey(name);
return builder->key == VKEY::KEY_UNKNOWN ? nullptr : builder;
}
};
/***********************************************************************
GuiToolstripCommandPlugin
***********************************************************************/
class GuiToolstripCommandPlugin : public Object, public IGuiPlugin
{
public:
GUI_PLUGIN_NAME(GacUI_Compiler_ShortcutParser)
{
GUI_PLUGIN_DEPEND(GacUI_Parser);
}
void Load(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override
{
if (controllerUnrelatedPlugins)
{
IGuiParserManager* manager = GetParserManager();
manager->SetParser(L"SHORTCUT", Ptr(new GuiToolstripCommandShortcutParser));
}
}
void Unload(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override
{
}
};
GUI_REGISTER_PLUGIN(GuiToolstripCommandPlugin)
}
}
}
/***********************************************************************
.\CONTROLS\TOOLSTRIPPACKAGE\GUITOOLSTRIPMENU.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace controls
{
using namespace collections;
using namespace compositions;
/***********************************************************************
GuiToolstripCollectionBase
***********************************************************************/
const wchar_t* const IToolstripUpdateLayoutInvoker::Identifier = L"vl::presentation::controls::IToolstripUpdateLayoutInvoker";
void GuiToolstripCollectionBase::InvokeUpdateLayout()
{
if(contentCallback)
{
contentCallback->UpdateLayout();
}
}
bool GuiToolstripCollectionBase::QueryInsert(vint index, GuiControl* const& child)
{
return !items.Contains(child) && !child->GetBoundsComposition()->GetParent();
}
void GuiToolstripCollectionBase::BeforeRemove(vint index, GuiControl* const& child)
{
if (auto invoker = child->QueryTypedService<IToolstripUpdateLayoutInvoker>())
{
invoker->SetCallback(nullptr);
}
InvokeUpdateLayout();
}
void GuiToolstripCollectionBase::AfterInsert(vint index, GuiControl* const& child)
{
if (auto invoker = child->QueryTypedService<IToolstripUpdateLayoutInvoker>())
{
invoker->SetCallback(contentCallback);
}
InvokeUpdateLayout();
}
void GuiToolstripCollectionBase::AfterRemove(vint index, vint count)
{
InvokeUpdateLayout();
}
GuiToolstripCollectionBase::GuiToolstripCollectionBase(IToolstripUpdateLayout* _contentCallback)
:contentCallback(_contentCallback)
{
}
GuiToolstripCollectionBase::~GuiToolstripCollectionBase()
{
}
/***********************************************************************
GuiToolstripCollection
***********************************************************************/
void GuiToolstripCollection::UpdateItemVisibility(vint index, GuiControl* child)
{
auto stackItem = stackComposition->GetStackItems()[index];
if (child->GetVisible())
{
stackItem->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
child->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
}
else
{
stackItem->SetMinSizeLimitation(GuiGraphicsComposition::NoLimit);
child->GetBoundsComposition()->SetAlignmentToParent(Margin(-1, -1, -1, -1));
}
}
void GuiToolstripCollection::OnItemVisibleChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
auto child = sender->GetRelatedControl();
vint index = IndexOf(child);
UpdateItemVisibility(index, child);
InvokeUpdateLayout();
}
void GuiToolstripCollection::BeforeRemove(vint index, GuiControl* const& child)
{
GuiStackItemComposition* stackItem = stackComposition->GetStackItems().Get(index);
auto eventHandler = eventHandlers[index];
child->VisibleChanged.Detach(eventHandler);
eventHandlers.RemoveAt(index);
GuiToolstripCollectionBase::BeforeRemove(index, child);
}
void GuiToolstripCollection::AfterInsert(vint index, GuiControl* const& child)
{
{
GuiStackItemComposition* stackItem = new GuiStackItemComposition;
stackItem->AddChild(child->GetBoundsComposition());
stackComposition->InsertStackItem(index, stackItem);
}
{
auto eventHandler = child->VisibleChanged.AttachMethod(this, &GuiToolstripCollection::OnItemVisibleChanged);
eventHandlers.Insert(index, eventHandler);
}
UpdateItemVisibility(index, child);
GuiToolstripCollectionBase::AfterInsert(index, child);
}
void GuiToolstripCollection::AfterRemove(vint index, vint count)
{
for (vint i = 0; i < count; i++)
{
auto stackItem = stackComposition->GetStackItems().Get(index);
stackComposition->RemoveChild(stackItem);
SafeDeleteComposition(stackItem);
}
GuiToolstripCollectionBase::AfterRemove(index, count);
}
GuiToolstripCollection::GuiToolstripCollection(IToolstripUpdateLayout* _contentCallback, compositions::GuiStackComposition* _stackComposition)
:GuiToolstripCollectionBase(_contentCallback)
,stackComposition(_stackComposition)
{
stackComposition->SetPreferredMinSize(Size(1, 1));
}
GuiToolstripCollection::~GuiToolstripCollection()
{
}
/***********************************************************************
GuiToolstripMenu
***********************************************************************/
void GuiToolstripMenu::UpdateLayout()
{
sharedSizeRootComposition->ForceCalculateSizeImmediately();
}
GuiToolstripMenu::GuiToolstripMenu(theme::ThemeName themeName, GuiControl* _owner)
:GuiMenu(themeName, _owner)
{
sharedSizeRootComposition = new GuiSharedSizeRootComposition();
sharedSizeRootComposition->SetAlignmentToParent(Margin(0, 0, 0, 0));
sharedSizeRootComposition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
containerComposition->AddChild(sharedSizeRootComposition);
stackComposition=new GuiStackComposition;
stackComposition->SetDirection(GuiStackComposition::Vertical);
stackComposition->SetAlignmentToParent(Margin(0, 0, 0, 0));
stackComposition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
sharedSizeRootComposition->AddChild(stackComposition);
toolstripItems = Ptr(new GuiToolstripCollection(this, stackComposition));
}
GuiToolstripMenu::~GuiToolstripMenu()
{
}
collections::ObservableListBase<GuiControl*>& GuiToolstripMenu::GetToolstripItems()
{
return *toolstripItems.Obj();
}
/***********************************************************************
GuiToolstripMenuBar
***********************************************************************/
GuiToolstripMenuBar::GuiToolstripMenuBar(theme::ThemeName themeName)
:GuiMenuBar(themeName)
{
stackComposition=new GuiStackComposition;
stackComposition->SetDirection(GuiStackComposition::Horizontal);
stackComposition->SetAlignmentToParent(Margin(0, 0, 0, 0));
stackComposition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
containerComposition->AddChild(stackComposition);
toolstripItems=Ptr(new GuiToolstripCollection(nullptr, stackComposition));
}
GuiToolstripMenuBar::~GuiToolstripMenuBar()
{
}
collections::ObservableListBase<GuiControl*>& GuiToolstripMenuBar::GetToolstripItems()
{
return *toolstripItems.Obj();
}
/***********************************************************************
GuiToolstripToolBar
***********************************************************************/
IGuiMenuService* GuiToolstripToolBar::GetParentMenuService()
{
return GetParent() ? GetParent()->QueryTypedService<IGuiMenuService>() : nullptr;
}
IGuiMenuService::Direction GuiToolstripToolBar::GetPreferredDirection()
{
return IGuiMenuService::Horizontal;
}
theme::ThemeName GuiToolstripToolBar::GetHostThemeName()
{
return GetControlThemeName();
}
bool GuiToolstripToolBar::IsActiveState()
{
return GetOpeningMenu() != nullptr;
}
bool GuiToolstripToolBar::IsSubMenuActivatedByMouseDown()
{
return false;
}
GuiToolstripToolBar::GuiToolstripToolBar(theme::ThemeName themeName)
:GuiControl(themeName)
{
stackComposition=new GuiStackComposition;
stackComposition->SetDirection(GuiStackComposition::Horizontal);
stackComposition->SetAlignmentToParent(Margin(0, 0, 0, 0));
stackComposition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
containerComposition->AddChild(stackComposition);
toolstripItems=Ptr(new GuiToolstripCollection(nullptr, stackComposition));
}
GuiToolstripToolBar::~GuiToolstripToolBar()
{
}
collections::ObservableListBase<GuiControl*>& GuiToolstripToolBar::GetToolstripItems()
{
return *toolstripItems.Obj();
}
IDescriptable* GuiToolstripToolBar::QueryService(const WString& identifier)
{
if (identifier == IGuiMenuService::Identifier)
{
return (IGuiMenuService*)this;
}
else
{
return GuiControl::QueryService(identifier);
}
}
/***********************************************************************
GuiToolstripButton
***********************************************************************/
void GuiToolstripButton::SetCallback(IToolstripUpdateLayout* _callback)
{
callback = _callback;
}
void GuiToolstripButton::OnActiveAlt()
{
auto host = GetSubMenuHost();
if (host == this)
{
GuiMenuButton::OnActiveAlt();
}
else
{
host->QueryTypedService<IGuiAltAction>()->OnActiveAlt();
}
}
void GuiToolstripButton::UpdateCommandContent()
{
if(command)
{
SetLargeImage(command->GetLargeImage());
SetImage(command->GetImage());
SetText(command->GetText());
SetEnabled(command->GetEnabled());
SetSelected(command->GetSelected());
if(command->GetShortcut())
{
SetShortcutText(command->GetShortcut()->GetName());
}
else
{
SetShortcutText(L"");
}
}
else
{
SetLargeImage(nullptr);
SetImage(nullptr);
SetText(L"");
SetEnabled(true);
SetSelected(false);
SetShortcutText(L"");
}
}
void GuiToolstripButton::OnLayoutAwaredPropertyChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if (callback)
{
callback->UpdateLayout();
}
}
void GuiToolstripButton::OnClicked(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
if(command)
{
command->Executed.ExecuteWithNewSender(arguments, sender);
}
}
void GuiToolstripButton::OnCommandDescriptionChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments)
{
UpdateCommandContent();
}
GuiToolstripButton::GuiToolstripButton(theme::ThemeName themeName)
:GuiMenuButton(themeName)
,command(0)
{
SetAutoFocus(false);
Clicked.AttachMethod(this, &GuiToolstripButton::OnClicked);
TextChanged.AttachMethod(this, &GuiToolstripButton::OnLayoutAwaredPropertyChanged);
ShortcutTextChanged.AttachMethod(this, &GuiToolstripButton::OnLayoutAwaredPropertyChanged);
}
GuiToolstripButton::~GuiToolstripButton()
{
}
GuiToolstripCommand* GuiToolstripButton::GetCommand()
{
return command;
}
void GuiToolstripButton::SetCommand(GuiToolstripCommand* value)
{
if(command!=value)
{
if(command)
{
command->DescriptionChanged.Detach(descriptionChangedHandler);
}
command=0;
descriptionChangedHandler=0;
if(value)
{
command=value;
descriptionChangedHandler=command->DescriptionChanged.AttachMethod(this, &GuiToolstripButton::OnCommandDescriptionChanged);
}
UpdateCommandContent();
}
}
GuiToolstripMenu* GuiToolstripButton::GetToolstripSubMenu()
{
return dynamic_cast<GuiToolstripMenu*>(GetSubMenu());
}
GuiToolstripMenu* GuiToolstripButton::EnsureToolstripSubMenu()
{
if (!GetSubMenu())
{
CreateToolstripSubMenu({});
}
return dynamic_cast<GuiToolstripMenu*>(GetSubMenu());
}
void GuiToolstripButton::CreateToolstripSubMenu(TemplateProperty<templates::GuiMenuTemplate> subMenuTemplate)
{
if (!subMenu)
{
auto newSubMenu = new GuiToolstripMenu(theme::ThemeName::Menu, this);
if (subMenuTemplate)
{
newSubMenu->SetControlTemplate(subMenuTemplate);
}
else
{
newSubMenu->SetControlTemplate(TypedControlTemplateObject(true)->GetSubMenuTemplate());
}
SetSubMenu(newSubMenu, true);
}
}
IDescriptable* GuiToolstripButton::QueryService(const WString& identifier)
{
if (identifier == IToolstripUpdateLayoutInvoker::Identifier)
{
return (IToolstripUpdateLayoutInvoker*)this;
}
else
{
return GuiMenuButton::QueryService(identifier);
}
}
/***********************************************************************
GuiToolstripNestedContainer
***********************************************************************/
void GuiToolstripNestedContainer::UpdateLayout()
{
// It could happen if a GuiToolstripGroupContainer contains something other that GuiToolstripGroup
if (callback && callback != this)
{
callback->UpdateLayout();
}
}
void GuiToolstripNestedContainer::SetCallback(IToolstripUpdateLayout* _callback)
{
callback = _callback;
}
GuiToolstripNestedContainer::GuiToolstripNestedContainer(theme::ThemeName themeName)
:GuiControl(themeName)
{
}
GuiToolstripNestedContainer::~GuiToolstripNestedContainer()
{
}
IDescriptable* GuiToolstripNestedContainer::QueryService(const WString& identifier)
{
if (identifier == IToolstripUpdateLayoutInvoker::Identifier)
{
return (IToolstripUpdateLayoutInvoker*)this;
}
else
{
return GuiControl::QueryService(identifier);
}
}
/***********************************************************************
GuiToolstripGroupContainer::GroupCollection
***********************************************************************/
void GuiToolstripGroupContainer::GroupCollection::BeforeRemove(vint index, GuiControl* const& child)
{
auto controlStackItem = container->stackComposition->GetStackItems()[index * 2];
CHECK_ERROR(controlStackItem->RemoveChild(child->GetBoundsComposition()), L"GuiToolstripGroupContainer::GroupCollection::BeforeRemove(vint, GuiControl* const&)#Internal error");
}
void GuiToolstripGroupContainer::GroupCollection::AfterInsert(vint index, GuiControl* const& child)
{
auto controlStackItem = new GuiStackItemComposition;
child->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
CHECK_ERROR(controlStackItem->AddChild(child->GetBoundsComposition()), L"GuiToolstripGroupContainer::GroupCollection::AfterInsert(vint, GuiControl* const&)#Internal error");
if (container->stackComposition->GetStackItems().Count() > 0)
{
auto splitterStackItem = new GuiStackItemComposition;
auto splitter = new GuiControl(container->splitterThemeName);
if (splitterTemplate)
{
splitter->SetControlTemplate(splitterTemplate);
}
splitter->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
splitterStackItem->AddChild(splitter->GetBoundsComposition());
container->stackComposition->InsertStackItem(index == 0 ? 0 : index * 2 - 1, splitterStackItem);
}
container->stackComposition->InsertStackItem(index * 2, controlStackItem);
GuiToolstripCollectionBase::AfterInsert(index, child);
}
void GuiToolstripGroupContainer::GroupCollection::AfterRemove(vint index, vint count)
{
vint min = index * 2;
vint max = (index + count - 1) * 2;
for (vint i = min; i <= max; i++)
{
auto stackItem = container->stackComposition->GetStackItems()[min];
container->stackComposition->RemoveChild(stackItem);
SafeDeleteComposition(stackItem);
}
GuiToolstripCollectionBase::AfterRemove(index, count);
}
GuiToolstripGroupContainer::GroupCollection::GroupCollection(GuiToolstripGroupContainer* _container)
:GuiToolstripCollectionBase(_container)
, container(_container)
{
}
GuiToolstripGroupContainer::GroupCollection::~GroupCollection()
{
}
GuiToolstripGroupContainer::ControlTemplatePropertyType GuiToolstripGroupContainer::GroupCollection::GetSplitterTemplate()
{
return splitterTemplate;
}
void GuiToolstripGroupContainer::GroupCollection::SetSplitterTemplate(const ControlTemplatePropertyType& value)
{
splitterTemplate = value;
RebuildSplitters();
}
void GuiToolstripGroupContainer::GroupCollection::RebuildSplitters()
{
auto stack = container->stackComposition;
vint count = stack->GetStackItems().Count();
for (vint i = 1; i < count; i += 2)
{
auto stackItem = stack->GetStackItems()[i];
{
auto control = stackItem->Children()[0]->GetAssociatedControl();
CHECK_ERROR(control != nullptr, L"GuiToolstripGroupContainer::GroupCollection::RebuildSplitters()#Internal error");
stackItem->RemoveChild(control->GetBoundsComposition());
delete control;
}
{
auto control = new GuiControl(container->splitterThemeName);
if (splitterTemplate)
{
control->SetControlTemplate(splitterTemplate);
}
control->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
stackItem->AddChild(control->GetBoundsComposition());
}
}
}
/***********************************************************************
GuiToolstripGroupContainer
***********************************************************************/
void GuiToolstripGroupContainer::OnParentLineChanged()
{
auto newDirection = GuiStackComposition::Horizontal;
auto newTheme = theme::ThemeName::ToolstripSplitter;
if (auto service = QueryTypedService<IGuiMenuService>())
{
if (service->GetPreferredDirection() == IGuiMenuService::Vertical)
{
newTheme = theme::ThemeName::MenuSplitter;
newDirection = GuiStackComposition::Vertical;
}
switch (service->GetHostThemeName())
{
case theme::ThemeName::MenuBar:
newTheme = theme::ThemeName::MenuSplitter;
break;
case theme::ThemeName::ToolstripToolBar:
newTheme = theme::ThemeName::ToolstripSplitter;
break;
case theme::ThemeName::ToolstripToolBarInMenu:
newTheme = theme::ThemeName::ToolstripSplitterInMenu;
break;
default:;
}
}
if (newDirection != stackComposition->GetDirection() || newTheme != splitterThemeName)
{
splitterThemeName = newTheme;
stackComposition->SetDirection(newDirection);
groupCollection->RebuildSplitters();
UpdateLayout();
}
GuiControl::OnParentLineChanged();
}
GuiToolstripGroupContainer::GuiToolstripGroupContainer(theme::ThemeName themeName)
:GuiToolstripNestedContainer(themeName)
, splitterThemeName(theme::ThemeName::ToolstripSplitter)
{
stackComposition = new GuiStackComposition;
stackComposition->SetDirection(GuiStackComposition::Horizontal);
stackComposition->SetAlignmentToParent(Margin(0, 0, 0, 0));
stackComposition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
containerComposition->AddChild(stackComposition);
groupCollection = Ptr(new GroupCollection(this));
}
GuiToolstripGroupContainer::~GuiToolstripGroupContainer()
{
}
GuiToolstripGroupContainer::ControlTemplatePropertyType GuiToolstripGroupContainer::GetSplitterTemplate()
{
return groupCollection->GetSplitterTemplate();
}
void GuiToolstripGroupContainer::SetSplitterTemplate(const ControlTemplatePropertyType& value)
{
groupCollection->SetSplitterTemplate(value);
}
collections::ObservableListBase<GuiControl*>& GuiToolstripGroupContainer::GetToolstripItems()
{
return *groupCollection.Obj();
}
/***********************************************************************
GuiToolstripGroup
***********************************************************************/
void GuiToolstripGroup::OnParentLineChanged()
{
auto direction = GuiStackComposition::Horizontal;
if (auto service = QueryTypedService<IGuiMenuService>())
{
if (service->GetPreferredDirection() == IGuiMenuService::Vertical)
{
direction = GuiStackComposition::Vertical;
}
}
if (direction != stackComposition->GetDirection())
{
stackComposition->SetDirection(direction);
UpdateLayout();
}
GuiControl::OnParentLineChanged();
}
GuiToolstripGroup::GuiToolstripGroup(theme::ThemeName themeName)
:GuiToolstripNestedContainer(themeName)
{
stackComposition = new GuiStackComposition;
stackComposition->SetDirection(GuiStackComposition::Horizontal);
stackComposition->SetAlignmentToParent(Margin(0, 0, 0, 0));
stackComposition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
containerComposition->AddChild(stackComposition);
toolstripItems = Ptr(new GuiToolstripCollection(nullptr, stackComposition));
}
GuiToolstripGroup::~GuiToolstripGroup()
{
}
collections::ObservableListBase<GuiControl*>& GuiToolstripGroup::GetToolstripItems()
{
return *toolstripItems.Obj();
}
}
}
}
/***********************************************************************
.\GRAPHICSCOMPOSITION\GUIGRAPHICSAXIS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
/***********************************************************************
GuiDefaultAxis
***********************************************************************/
GuiDefaultAxis::GuiDefaultAxis()
{
}
GuiDefaultAxis::~GuiDefaultAxis()
{
}
Size GuiDefaultAxis::RealSizeToVirtualSize(Size size)
{
return size;
}
Size GuiDefaultAxis::VirtualSizeToRealSize(Size size)
{
return size;
}
Point GuiDefaultAxis::RealPointToVirtualPoint(Size realFullSize, Point point)
{
return point;
}
Point GuiDefaultAxis::VirtualPointToRealPoint(Size realFullSize, Point point)
{
return point;
}
Rect GuiDefaultAxis::RealRectToVirtualRect(Size realFullSize, Rect rect)
{
return rect;
}
Rect GuiDefaultAxis::VirtualRectToRealRect(Size realFullSize, Rect rect)
{
return rect;
}
Margin GuiDefaultAxis::RealMarginToVirtualMargin(Margin margin)
{
return margin;
}
Margin GuiDefaultAxis::VirtualMarginToRealMargin(Margin margin)
{
return margin;
}
KeyDirection GuiDefaultAxis::RealKeyDirectionToVirtualKeyDirection(KeyDirection key)
{
return key;
}
/***********************************************************************
GuiAxis
***********************************************************************/
GuiAxis::GuiAxis(AxisDirection _axisDirection)
:axisDirection(_axisDirection)
{
}
GuiAxis::~GuiAxis()
{
}
AxisDirection GuiAxis::GetDirection()
{
return axisDirection;
}
Size GuiAxis::RealSizeToVirtualSize(Size size)
{
switch(axisDirection)
{
case AxisDirection::LeftDown:
case AxisDirection::RightDown:
case AxisDirection::LeftUp:
case AxisDirection::RightUp:
return Size(size.x, size.y);
case AxisDirection::DownLeft:
case AxisDirection::DownRight:
case AxisDirection::UpLeft:
case AxisDirection::UpRight:
return Size(size.y, size.x);
}
return size;
}
Size GuiAxis::VirtualSizeToRealSize(Size size)
{
return RealSizeToVirtualSize(size);
}
Point GuiAxis::RealPointToVirtualPoint(Size realFullSize, Point point)
{
Rect rect(point, Size(0, 0));
return RealRectToVirtualRect(realFullSize, rect).LeftTop();
}
Point GuiAxis::VirtualPointToRealPoint(Size realFullSize, Point point)
{
Rect rect(point, Size(0, 0));
return VirtualRectToRealRect(realFullSize, rect).LeftTop();
}
Rect GuiAxis::RealRectToVirtualRect(Size realFullSize, Rect rect)
{
vint x1=rect.x1;
vint x2=realFullSize.x-rect.x2;
vint y1=rect.y1;
vint y2=realFullSize.y-rect.y2;
vint w=rect.Width();
vint h=rect.Height();
switch(axisDirection)
{
case AxisDirection::LeftDown:
return Rect(Point(x2, y1), Size(w, h));
case AxisDirection::RightDown:
return Rect(Point(x1, y1), Size(w, h));
case AxisDirection::LeftUp:
return Rect(Point(x2, y2), Size(w, h));
case AxisDirection::RightUp:
return Rect(Point(x1, y2), Size(w, h));
case AxisDirection::DownLeft:
return Rect(Point(y1, x2), Size(h, w));
case AxisDirection::DownRight:
return Rect(Point(y1, x1), Size(h, w));
case AxisDirection::UpLeft:
return Rect(Point(y2, x2), Size(h, w));
case AxisDirection::UpRight:
return Rect(Point(y2, x1), Size(h, w));
}
return rect;
}
Rect GuiAxis::VirtualRectToRealRect(Size realFullSize, Rect rect)
{
realFullSize=RealSizeToVirtualSize(realFullSize);
vint x1=rect.x1;
vint x2=realFullSize.x-rect.x2;
vint y1=rect.y1;
vint y2=realFullSize.y-rect.y2;
vint w=rect.Width();
vint h=rect.Height();
switch(axisDirection)
{
case AxisDirection::LeftDown:
return Rect(Point(x2, y1), Size(w, h));
case AxisDirection::RightDown:
return Rect(Point(x1, y1), Size(w, h));
case AxisDirection::LeftUp:
return Rect(Point(x2, y2), Size(w, h));
case AxisDirection::RightUp:
return Rect(Point(x1, y2), Size(w, h));
case AxisDirection::DownLeft:
return Rect(Point(y2, x1), Size(h, w));
case AxisDirection::DownRight:
return Rect(Point(y1, x1), Size(h, w));
case AxisDirection::UpLeft:
return Rect(Point(y2, x2), Size(h, w));
case AxisDirection::UpRight:
return Rect(Point(y1, x2), Size(h, w));
}
return rect;
}
Margin GuiAxis::RealMarginToVirtualMargin(Margin margin)
{
vint x1=margin.left;
vint x2=margin.right;
vint y1=margin.top;
vint y2=margin.bottom;
switch(axisDirection)
{
case AxisDirection::LeftDown:
return Margin(x2, y1, x1, y2);
case AxisDirection::RightDown:
return Margin(x1, y1, x2, y2);
case AxisDirection::LeftUp:
return Margin(x2, y2, x1, y1);
case AxisDirection::RightUp:
return Margin(x1, y2, x2, y1);
case AxisDirection::DownLeft:
return Margin(y1, x2, y2, x1);
case AxisDirection::DownRight:
return Margin(y1, x1, y2, x2);
case AxisDirection::UpLeft:
return Margin(y2, x2, y1, x1);
case AxisDirection::UpRight:
return Margin(y2, x1, y1, x2);
}
return margin;
}
Margin GuiAxis::VirtualMarginToRealMargin(Margin margin)
{
vint x1=margin.left;
vint x2=margin.right;
vint y1=margin.top;
vint y2=margin.bottom;
switch(axisDirection)
{
case AxisDirection::LeftDown:
return Margin(x2, y1, x1, y2);
case AxisDirection::RightDown:
return Margin(x1, y1, x2, y2);
case AxisDirection::LeftUp:
return Margin(x2, y2, x1, y1);
case AxisDirection::RightUp:
return Margin(x1, y2, x2, y1);
case AxisDirection::DownLeft:
return Margin(y2, x1, y1, x2);
case AxisDirection::DownRight:
return Margin(y1, x1, y2, x2);
case AxisDirection::UpLeft:
return Margin(y2, x2, y1, x1);
case AxisDirection::UpRight:
return Margin(y1, x2, y2, x1);
default:;
}
return margin;
}
KeyDirection GuiAxis::RealKeyDirectionToVirtualKeyDirection(KeyDirection key)
{
bool pageKey=false;
switch(key)
{
case KeyDirection::PageUp:
pageKey=true;
key=KeyDirection::Up;
break;
case KeyDirection::PageDown:
pageKey=true;
key=KeyDirection::Down;
break;
case KeyDirection::PageLeft:
pageKey=true;
key=KeyDirection::Left;
break;
case KeyDirection::PageRight:
pageKey=true;
key=KeyDirection::Right;
break;
default:;
}
switch(key)
{
case KeyDirection::Up:
switch(axisDirection)
{
case AxisDirection::LeftDown: key=KeyDirection::Up; break;
case AxisDirection::RightDown: key=KeyDirection::Up; break;
case AxisDirection::LeftUp: key=KeyDirection::Down; break;
case AxisDirection::RightUp: key=KeyDirection::Down; break;
case AxisDirection::DownLeft: key=KeyDirection::Left; break;
case AxisDirection::DownRight: key=KeyDirection::Left; break;
case AxisDirection::UpLeft: key=KeyDirection::Right; break;
case AxisDirection::UpRight: key=KeyDirection::Right; break;
}
break;
case KeyDirection::Down:
switch(axisDirection)
{
case AxisDirection::LeftDown: key=KeyDirection::Down; break;
case AxisDirection::RightDown: key=KeyDirection::Down; break;
case AxisDirection::LeftUp: key=KeyDirection::Up; break;
case AxisDirection::RightUp: key=KeyDirection::Up; break;
case AxisDirection::DownLeft: key=KeyDirection::Right; break;
case AxisDirection::DownRight: key=KeyDirection::Right; break;
case AxisDirection::UpLeft: key=KeyDirection::Left; break;
case AxisDirection::UpRight: key=KeyDirection::Left; break;
}
break;
case KeyDirection::Left:
switch(axisDirection)
{
case AxisDirection::LeftDown: key=KeyDirection::Right; break;
case AxisDirection::RightDown: key=KeyDirection::Left; break;
case AxisDirection::LeftUp: key=KeyDirection::Right; break;
case AxisDirection::RightUp: key=KeyDirection::Left; break;
case AxisDirection::DownLeft: key=KeyDirection::Down; break;
case AxisDirection::DownRight: key=KeyDirection::Up; break;
case AxisDirection::UpLeft: key=KeyDirection::Down; break;
case AxisDirection::UpRight: key=KeyDirection::Up; break;
}
break;
case KeyDirection::Right:
switch(axisDirection)
{
case AxisDirection::LeftDown: key=KeyDirection::Left; break;
case AxisDirection::RightDown: key=KeyDirection::Right; break;
case AxisDirection::LeftUp: key=KeyDirection::Left; break;
case AxisDirection::RightUp: key=KeyDirection::Right; break;
case AxisDirection::DownLeft: key=KeyDirection::Up; break;
case AxisDirection::DownRight: key=KeyDirection::Down; break;
case AxisDirection::UpLeft: key=KeyDirection::Up; break;
case AxisDirection::UpRight: key=KeyDirection::Down; break;
}
break;
case KeyDirection::Home:
switch(axisDirection)
{
case AxisDirection::LeftDown: key=KeyDirection::Home; break;
case AxisDirection::RightDown: key=KeyDirection::Home; break;
case AxisDirection::LeftUp: key=KeyDirection::End; break;
case AxisDirection::RightUp: key=KeyDirection::End; break;
case AxisDirection::DownLeft: key=KeyDirection::Home; break;
case AxisDirection::DownRight: key=KeyDirection::Home; break;
case AxisDirection::UpLeft: key=KeyDirection::End; break;
case AxisDirection::UpRight: key=KeyDirection::End; break;
}
break;
case KeyDirection::End:
switch(axisDirection)
{
case AxisDirection::LeftDown: key=KeyDirection::End; break;
case AxisDirection::RightDown: key=KeyDirection::End; break;
case AxisDirection::LeftUp: key=KeyDirection::Home; break;
case AxisDirection::RightUp: key=KeyDirection::Home; break;
case AxisDirection::DownLeft: key=KeyDirection::End; break;
case AxisDirection::DownRight: key=KeyDirection::End; break;
case AxisDirection::UpLeft: key=KeyDirection::Home; break;
case AxisDirection::UpRight: key=KeyDirection::Home; break;
}
break;
default:;
}
if(pageKey)
{
switch(key)
{
case KeyDirection::Up:
key=KeyDirection::PageUp;
break;
case KeyDirection::Down:
key=KeyDirection::PageDown;
break;
case KeyDirection::Left:
key=KeyDirection::PageLeft;
break;
case KeyDirection::Right:
key=KeyDirection::PageRight;
break;
default:;
}
}
return key;
}
}
}
}
/***********************************************************************
.\GRAPHICSCOMPOSITION\GUIGRAPHICSFLOWCOMPOSITION.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
using namespace collections;
/***********************************************************************
GuiFlowComposition
***********************************************************************/
void GuiFlowComposition::Layout_UpdateFlowItemLayout(vint maxVirtualWidth)
{
for (auto item : layout_flowItems)
{
item->Layout_SetCachedMinSize(item->Layout_CalculateMinSizeHelper());
}
if (layout_lastVirtualWidth != maxVirtualWidth)
{
layout_invalid = true;
layout_lastVirtualWidth = maxVirtualWidth;
}
if (!layout_invalid) return;
layout_invalid = false;
vint currentIndex = 0;
vint rowTop = 0;
while (currentIndex < layout_flowItems.Count())
{
auto currentItemVirtualMinSize = axis->RealSizeToVirtualSize(layout_flowItems[currentIndex]->GetCachedMinSize());
vint rowWidth = currentItemVirtualMinSize.x;
vint rowHeight = currentItemVirtualMinSize.y;
vint rowItemCount = 1;
for (vint i = currentIndex + 1; i < layout_flowItems.Count(); i++)
{
auto itemSize = axis->RealSizeToVirtualSize(layout_flowItems[i]->GetCachedMinSize());
vint itemWidth = itemSize.x + columnPadding;
if (rowWidth + itemWidth > maxVirtualWidth)
{
break;
}
rowWidth += itemWidth;
if (rowHeight < itemSize.y)
{
rowHeight = itemSize.y;
}
rowItemCount++;
}
vint baseLine = 0;
Array<vint> itemBaseLines(rowItemCount);
for (vint i = 0; i < rowItemCount; i++)
{
vint index = currentIndex + i;
vint itemBaseLine = 0;
auto itemSize = axis->RealSizeToVirtualSize(layout_flowItems[index]->GetCachedMinSize());
auto option = layout_flowItems[index]->GetFlowOption();
switch (option.baseline)
{
case GuiFlowOption::FromTop:
itemBaseLine = option.distance;
break;
case GuiFlowOption::FromBottom:
itemBaseLine = itemSize.y - option.distance;
break;
case GuiFlowOption::Percentage:
itemBaseLine = (vint)(itemSize.y*option.percentage);
break;
}
itemBaseLines[i] = itemBaseLine;
if (baseLine < itemBaseLine)
{
baseLine = itemBaseLine;
}
}
vint rowUsedWidth = 0;
for (vint i = 0; i < rowItemCount; i++)
{
vint index = currentIndex + i;
auto itemSize = axis->RealSizeToVirtualSize(layout_flowItems[index]->GetCachedMinSize());
vint itemLeft = 0;
vint itemTop = rowTop + baseLine - itemBaseLines[i];
switch (alignment)
{
case FlowAlignment::Left:
itemLeft = rowUsedWidth + i * columnPadding;
break;
case FlowAlignment::Center:
itemLeft = rowUsedWidth + i * columnPadding + (maxVirtualWidth - rowWidth) / 2;
break;
case FlowAlignment::Right:
itemLeft = rowUsedWidth + i * columnPadding + (maxVirtualWidth - rowWidth);
break;
case FlowAlignment::Extend:
if (i == 0)
{
itemLeft = rowUsedWidth;
}
else
{
itemLeft = rowUsedWidth + (vint)((double)(maxVirtualWidth - rowWidth) * i / (rowItemCount - 1)) + i * columnPadding;
}
break;
}
layout_flowItems[index]->layout_virtualBounds = Rect({ itemLeft,itemTop }, itemSize);
rowUsedWidth += itemSize.x;
}
rowTop += rowHeight + rowPadding;
currentIndex += rowItemCount;
}
layout_minVirtualHeight = rowTop == 0 ? 0 : rowTop - rowPadding;
}
Size GuiFlowComposition::Layout_UpdateFlowItemLayoutByConstraint(Size constraintSize)
{
Size extraSize(
extraMargin.left + extraMargin.right,
extraMargin.top + extraMargin.bottom
);
constraintSize.x -= extraSize.x;
constraintSize.y -= extraSize.y;
if (constraintSize.x < 0) constraintSize.x = 0;
if (constraintSize.y < 0) constraintSize.y = 0;
vint maxVirtualWidth = axis->RealSizeToVirtualSize(constraintSize).x;
Layout_UpdateFlowItemLayout(maxVirtualWidth);
return extraSize;
}
void GuiFlowComposition::OnChildInserted(GuiGraphicsComposition* child)
{
GuiBoundsComposition::OnChildInserted(child);
auto item = dynamic_cast<GuiFlowItemComposition*>(child);
if (item && !layout_flowItems.Contains(item))
{
layout_flowItems.Add(item);
}
}
void GuiFlowComposition::OnChildRemoved(GuiGraphicsComposition* child)
{
GuiBoundsComposition::OnChildRemoved(child);
auto item = dynamic_cast<GuiFlowItemComposition*>(child);
if (item)
{
layout_flowItems.Remove(item);
}
}
void GuiFlowComposition::OnCompositionStateChanged()
{
GuiBoundsComposition::OnCompositionStateChanged();
layout_invalid = true;
}
Size GuiFlowComposition::Layout_CalculateMinSize()
{
Size minSize = GuiBoundsComposition::Layout_CalculateMinSize();
if (GetMinSizeLimitation() == GuiGraphicsComposition::LimitToElementAndChildren && layout_flowItems.Count() > 0)
{
Size cachedSize = cachedBounds.GetSize();
Size constraintSize(
minSize.x > cachedSize.x ? minSize.x : cachedSize.x,
minSize.y > cachedSize.y ? minSize.y : cachedSize.y
);
Size extraSize = Layout_UpdateFlowItemLayoutByConstraint(constraintSize);
Size minFlowSize = axis->VirtualSizeToRealSize(Size(0, layout_minVirtualHeight));
minFlowSize.x += extraSize.x;
minFlowSize.y += extraSize.y;
if (minSize.x < minFlowSize.x) minSize.x = minFlowSize.x;
if (minSize.y < minFlowSize.y) minSize.y = minFlowSize.y;
}
return minSize;
}
Rect GuiFlowComposition::Layout_CalculateBounds(Size parentSize)
{
Rect bounds = GuiBoundsComposition::Layout_CalculateBounds(parentSize);
Size extraSize = Layout_UpdateFlowItemLayoutByConstraint(bounds.GetSize());
Size contentSize(
bounds.Width() - extraSize.x,
bounds.Height() - extraSize.y
);
for (auto item : layout_flowItems)
{
item->Layout_SetFlowItemBounds(contentSize, item->layout_virtualBounds);
}
return bounds;
}
const GuiFlowComposition::ItemCompositionList& GuiFlowComposition::GetFlowItems()
{
return layout_flowItems;
}
bool GuiFlowComposition::InsertFlowItem(vint index, GuiFlowItemComposition* item)
{
index = layout_flowItems.Insert(index, item);
if (AddChild(item))
{
return true;
}
layout_flowItems.RemoveAt(index);
return false;
}
Margin GuiFlowComposition::GetExtraMargin()
{
return extraMargin;
}
void GuiFlowComposition::SetExtraMargin(Margin value)
{
if (extraMargin != value)
{
extraMargin = value;
InvokeOnCompositionStateChanged();
}
}
vint GuiFlowComposition::GetRowPadding()
{
return rowPadding;
}
void GuiFlowComposition::SetRowPadding(vint value)
{
if (rowPadding != value)
{
rowPadding = value;
InvokeOnCompositionStateChanged();
}
}
vint GuiFlowComposition::GetColumnPadding()
{
return columnPadding;
}
void GuiFlowComposition::SetColumnPadding(vint value)
{
if (columnPadding != value)
{
columnPadding = value;
InvokeOnCompositionStateChanged();
}
}
Ptr<IGuiAxis> GuiFlowComposition::GetAxis()
{
return axis;
}
void GuiFlowComposition::SetAxis(Ptr<IGuiAxis> value)
{
if (value)
{
axis = value;
InvokeOnCompositionStateChanged();
}
}
FlowAlignment GuiFlowComposition::GetAlignment()
{
return alignment;
}
void GuiFlowComposition::SetAlignment(FlowAlignment value)
{
if (alignment != value)
{
alignment = value;
InvokeOnCompositionStateChanged();
}
}
/***********************************************************************
GuiFlowItemComposition
***********************************************************************/
void GuiFlowItemComposition::Layout_SetFlowItemBounds(Size contentSize, Rect virtualBounds)
{
Rect result = layout_flowParent->axis->VirtualRectToRealRect(contentSize, virtualBounds);
result.x1 += layout_flowParent->extraMargin.left;
result.x2 += layout_flowParent->extraMargin.left;
result.y1 += layout_flowParent->extraMargin.top;
result.y2 += layout_flowParent->extraMargin.top;
result.x1 -= extraMargin.left;
result.y1 -= extraMargin.top;
result.x2 += extraMargin.right;
result.y2 += extraMargin.bottom;
Layout_SetCachedBounds(result);
}
void GuiFlowItemComposition::OnParentLineChanged()
{
layout_flowParent = dynamic_cast<GuiFlowComposition*>(GetParent());
GuiGraphicsComposition::OnParentLineChanged();
}
GuiFlowItemComposition::GuiFlowItemComposition()
{
SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
CachedMinSizeChanged.AttachLambda([this](GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
if (layout_flowParent) layout_flowParent->layout_invalid = true;
});
}
Margin GuiFlowItemComposition::GetExtraMargin()
{
return extraMargin;
}
void GuiFlowItemComposition::SetExtraMargin(Margin value)
{
if (extraMargin != value)
{
extraMargin = value;
InvokeOnCompositionStateChanged();
}
}
GuiFlowOption GuiFlowItemComposition::GetFlowOption()
{
return option;
}
void GuiFlowItemComposition::SetFlowOption(GuiFlowOption value)
{
if (option != value)
{
option = value;
if (layout_flowParent) layout_flowParent->layout_invalid = true;
InvokeOnCompositionStateChanged();
}
}
}
}
}
/***********************************************************************
.\GRAPHICSCOMPOSITION\GUIGRAPHICSREPEATCOMPOSITION.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
using namespace reflection::description;
/***********************************************************************
GuiRepeatCompositionBase
***********************************************************************/
GuiRepeatCompositionBase::GuiRepeatCompositionBase()
{
}
GuiRepeatCompositionBase::~GuiRepeatCompositionBase()
{
if (itemChangedHandler)
{
itemSource.Cast<IValueObservableList>()->ItemChanged.Remove(itemChangedHandler);
}
}
GuiRepeatCompositionBase::ItemStyleProperty GuiRepeatCompositionBase::GetItemTemplate()
{
return itemTemplate;
}
void GuiRepeatCompositionBase::SetItemTemplate(ItemStyleProperty value)
{
OnClearItems();
itemTemplate = value;
if (itemTemplate && itemSource)
{
OnInstallItems();
}
}
Ptr<IValueEnumerable> GuiRepeatCompositionBase::GetItemSource()
{
return itemSource;
}
void GuiRepeatCompositionBase::SetItemSource(Ptr<IValueEnumerable> value)
{
if (value != itemSource)
{
if (itemChangedHandler)
{
itemSource.Cast<IValueObservableList>()->ItemChanged.Remove(itemChangedHandler);
itemChangedHandler = {};
}
OnClearItems();
itemSource = value.Cast<IValueList>();
if (!itemSource && value)
{
itemSource = IValueList::Create(GetLazyList<Value>(value));
}
if (itemTemplate && itemSource)
{
OnInstallItems();
}
if (auto observable = itemSource.Cast<IValueObservableList>())
{
itemChangedHandler = observable->ItemChanged.Add(this, &GuiRepeatCompositionBase::OnItemChanged);
}
}
}
description::Value GuiRepeatCompositionBase::GetContext()
{
return itemContext;
}
void GuiRepeatCompositionBase::SetContext(const description::Value& value)
{
if (itemContext != value)
{
itemContext = value;
OnUpdateContext();
GuiEventArgs arguments(dynamic_cast<GuiGraphicsComposition*>(this));
ContextChanged.Execute(arguments);
}
}
}
}
}
/***********************************************************************
.\GRAPHICSCOMPOSITION\GUIGRAPHICSREPEATCOMPOSITION_NONVIRTIAL.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
/***********************************************************************
GuiNonVirtialRepeatCompositionBase
***********************************************************************/
void GuiNonVirtialRepeatCompositionBase::OnItemChanged(vint index, vint oldCount, vint newCount)
{
if (itemTemplate && itemSource)
{
for (vint i = oldCount - 1; i >= 0; i--)
{
RemoveItem(index + i);
}
for (vint i = 0; i < newCount; i++)
{
InstallItem(index + i);
}
}
}
void GuiNonVirtialRepeatCompositionBase::OnClearItems()
{
vint count = GetRepeatCompositionCount();
for (vint i = count - 1; i >= 0; i--)
{
RemoveItem(i);
}
}
void GuiNonVirtialRepeatCompositionBase::OnInstallItems()
{
if (itemTemplate && itemSource)
{
vint count = itemSource->GetCount();
for (vint i = 0; i < count; i++)
{
InstallItem(i);
}
}
}
void GuiNonVirtialRepeatCompositionBase::OnUpdateContext()
{
vint count = GetRepeatCompositionCount();
for (vint i = 0; i < count; i++)
{
auto rc = GetRepeatComposition(i);
auto it = dynamic_cast<templates::GuiTemplate*>(rc->Children()[0]);
it->SetContext(itemContext);
}
}
void GuiNonVirtialRepeatCompositionBase::RemoveItem(vint index)
{
GuiItemEventArgs arguments(dynamic_cast<GuiGraphicsComposition*>(this));
arguments.itemIndex = index;
ItemRemoved.Execute(arguments);
auto item = RemoveRepeatComposition(index);
SafeDeleteComposition(item);
}
void GuiNonVirtialRepeatCompositionBase::InstallItem(vint index)
{
auto source = itemSource->Get(index);
auto templateItem = itemTemplate(source);
auto item = InsertRepeatComposition(index);
templateItem->SetAlignmentToParent(Margin(0, 0, 0, 0));
templateItem->SetContext(itemContext);
item->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
item->AddChild(templateItem);
GuiItemEventArgs arguments(dynamic_cast<GuiGraphicsComposition*>(this));
arguments.itemIndex = index;
ItemInserted.Execute(arguments);
}
GuiNonVirtialRepeatCompositionBase::GuiNonVirtialRepeatCompositionBase()
{
}
GuiNonVirtialRepeatCompositionBase::~GuiNonVirtialRepeatCompositionBase()
{
}
/***********************************************************************
GuiRepeatStackComposition
***********************************************************************/
vint GuiRepeatStackComposition::GetRepeatCompositionCount()
{
return GetStackItems().Count();
}
GuiGraphicsComposition* GuiRepeatStackComposition::GetRepeatComposition(vint index)
{
return GetStackItems()[index];
}
GuiGraphicsComposition* GuiRepeatStackComposition::InsertRepeatComposition(vint index)
{
CHECK_ERROR(0 <= index && index <= GetStackItems().Count(), L"GuiRepeatStackComposition::InsertRepeatComposition(vint)#Index out of range.");
auto item = new GuiStackItemComposition;
InsertStackItem(index, item);
return item;
}
GuiGraphicsComposition* GuiRepeatStackComposition::RemoveRepeatComposition(vint index)
{
auto item = GetStackItems()[index];
RemoveChild(item);
return item;
}
GuiRepeatStackComposition::GuiRepeatStackComposition()
{
ItemInserted.SetAssociatedComposition(this);
ItemRemoved.SetAssociatedComposition(this);
ContextChanged.SetAssociatedComposition(this);
}
GuiRepeatStackComposition::~GuiRepeatStackComposition()
{
}
/***********************************************************************
GuiRepeatFlowComposition
***********************************************************************/
vint GuiRepeatFlowComposition::GetRepeatCompositionCount()
{
return GetFlowItems().Count();
}
GuiGraphicsComposition* GuiRepeatFlowComposition::GetRepeatComposition(vint index)
{
return GetFlowItems()[index];
}
GuiGraphicsComposition* GuiRepeatFlowComposition::InsertRepeatComposition(vint index)
{
CHECK_ERROR(0 <= index && index <= GetFlowItems().Count(), L"GuiRepeatStackComposition::InsertRepeatComposition(vint)#Index out of range.");
auto item = new GuiFlowItemComposition;
InsertFlowItem(index, item);
return item;
}
GuiGraphicsComposition* GuiRepeatFlowComposition::RemoveRepeatComposition(vint index)
{
auto item = GetFlowItems()[index];
RemoveChild(item);
return item;
}
GuiRepeatFlowComposition::GuiRepeatFlowComposition()
{
ItemInserted.SetAssociatedComposition(this);
ItemRemoved.SetAssociatedComposition(this);
ContextChanged.SetAssociatedComposition(this);
}
GuiRepeatFlowComposition::~GuiRepeatFlowComposition()
{
}
}
}
}
/***********************************************************************
.\GRAPHICSCOMPOSITION\GUIGRAPHICSREPEATCOMPOSITION_VIRTUAL.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
using namespace collections;
/***********************************************************************
GuiVirtualRepeatCompositionBase
***********************************************************************/
void GuiVirtualRepeatCompositionBase::Layout_UpdateIndex(ItemStyleRecord style, vint index)
{
}
void GuiVirtualRepeatCompositionBase::Layout_UpdateViewBounds(Rect value, bool forceUpdateTotalSize)
{
auto old = GetViewLocation();
Rect oldBounds = viewBounds;
viewBounds = value;
OnViewChangedInternal(oldBounds, value, forceUpdateTotalSize);
if (old != GetViewLocation())
{
ViewLocationChanged.Execute(GuiEventArgs(this));
}
}
void GuiVirtualRepeatCompositionBase::Layout_UpdateViewLocation(Point value)
{
Layout_UpdateViewBounds(Rect(value, viewBounds.GetSize()), false);
}
Rect GuiVirtualRepeatCompositionBase::Layout_CalculateBounds(Size parentSize)
{
auto bounds = GuiBoundsComposition::Layout_CalculateBounds(parentSize);
auto size = axis->RealSizeToVirtualSize(bounds.GetSize());
if (size != viewBounds.GetSize() || itemSourceUpdated)
{
itemSourceUpdated = false;
Layout_UpdateViewBounds(Rect(viewBounds.LeftTop(), size), true);
}
return bounds;
}
void GuiVirtualRepeatCompositionBase::Layout_ResetLayout()
{
viewBounds = Rect({ 0,0 }, { 0,0 });
ViewLocationChanged.Execute(GuiEventArgs(this));
OnResetViewLocation();
itemSourceUpdated = true;
Layout_InvalidateItemSizeCache();
AdoptedSizeInvalidated.Execute(GuiEventArgs(this));
}
void GuiVirtualRepeatCompositionBase::Layout_SetStyleAlignmentToParent(ItemStyleRecord style, Margin value)
{
style->SetAlignmentToParent(axis->VirtualMarginToRealMargin(value));
}
Size GuiVirtualRepeatCompositionBase::Layout_GetStylePreferredSize(ItemStyleRecord style)
{
return axis->RealSizeToVirtualSize(style->GetCachedMinSize());
}
Rect GuiVirtualRepeatCompositionBase::Layout_GetStyleBounds(ItemStyleRecord style)
{
return axis->RealRectToVirtualRect(axis->VirtualSizeToRealSize(viewBounds.GetSize()), style->GetCachedBounds());
}
void GuiVirtualRepeatCompositionBase::Layout_SetStyleBounds(ItemStyleRecord style, Rect value)
{
return style->SetExpectedBounds(axis->VirtualRectToRealRect(axis->VirtualSizeToRealSize(viewBounds.GetSize()), value));
}
void GuiVirtualRepeatCompositionBase::OnStyleCachedMinSizeChanged(GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
InvalidateLayout();
}
void GuiVirtualRepeatCompositionBase::AttachEventHandler(GuiGraphicsComposition* itemStyle)
{
eventHandlers.Add(itemStyle, itemStyle->CachedMinSizeChanged.AttachMethod(this, &GuiVirtualRepeatCompositionBase::OnStyleCachedMinSizeChanged));
}
void GuiVirtualRepeatCompositionBase::DetachEventHandler(GuiGraphicsComposition* itemStyle)
{
vint index = eventHandlers.Keys().IndexOf(itemStyle);
if (index != -1)
{
auto eventHandler = eventHandlers.Values()[index];
itemStyle->CachedBoundsChanged.Detach(eventHandler);
eventHandlers.Remove(itemStyle);
}
}
void GuiVirtualRepeatCompositionBase::OnChildRemoved(GuiGraphicsComposition* child)
{
DetachEventHandler(child);
GuiBoundsComposition::OnChildRemoved(child);
}
void GuiVirtualRepeatCompositionBase::OnItemChanged(vint start, vint oldCount, vint newCount)
{
itemSourceUpdated = true;
InvokeOnCompositionStateChanged();
vint visibleCount = visibleStyles.Count();
vint itemCount = itemSource->GetCount();
SortedList<ItemStyleRecord> reusedStyles;
for (vint i = 0; i < visibleCount; i++)
{
vint index = startIndex + i;
if (index >= itemCount)
{
break;
}
vint oldIndex = -1;
if (index < start)
{
oldIndex = index;
}
else if (index >= start + newCount)
{
oldIndex = index - newCount + oldCount;
}
if (oldIndex != -1)
{
if (oldIndex >= startIndex && oldIndex < startIndex + visibleCount)
{
auto style = visibleStyles[oldIndex - startIndex];
reusedStyles.Add(style);
visibleStyles.Add(style);
}
else
{
oldIndex = -1;
}
}
if (oldIndex == -1)
{
visibleStyles.Add(CreateStyle(index));
}
}
for (vint i = 0; i < visibleCount; i++)
{
auto style = visibleStyles[i];
if (!reusedStyles.Contains(style))
{
DeleteStyle(style);
}
}
visibleStyles.RemoveRange(0, visibleCount);
for (auto [style, i] : indexed(visibleStyles))
{
Layout_UpdateIndex(style, startIndex + i);
}
}
void GuiVirtualRepeatCompositionBase::OnClearItems()
{
startIndex = 0;
for (auto style : visibleStyles)
{
DeleteStyle(style);
}
visibleStyles.Clear();
Layout_ResetLayout();
}
void GuiVirtualRepeatCompositionBase::OnInstallItems()
{
// nothing needs to be done here
// visibleStyles will be recreated in the next round of layout
}
void GuiVirtualRepeatCompositionBase::OnUpdateContext()
{
for (auto style : visibleStyles)
{
style->SetContext(itemContext);
}
}
void GuiVirtualRepeatCompositionBase::OnResetViewLocation()
{
}
GuiVirtualRepeatCompositionBase::ItemStyleRecord GuiVirtualRepeatCompositionBase::CreateStyleInternal(vint index)
{
auto source = itemSource->Get(index);
auto itemStyle = itemTemplate(source);
itemStyle->SetContext(itemContext);
return itemStyle;
}
void GuiVirtualRepeatCompositionBase::DeleteStyleInternal(ItemStyleRecord style)
{
SafeDeleteComposition(style);
}
vint GuiVirtualRepeatCompositionBase::CalculateAdoptedSize(vint expectedSize, vint count, vint itemSize)
{
vint visibleCount = expectedSize / itemSize;
if (count < visibleCount)
{
visibleCount = count;
}
else if (count > visibleCount)
{
vint deltaA = expectedSize - visibleCount * itemSize;
vint deltaB = itemSize - deltaA;
if (deltaB < deltaA)
{
visibleCount++;
}
}
return visibleCount * itemSize;
}
GuiVirtualRepeatCompositionBase::ItemStyleRecord GuiVirtualRepeatCompositionBase::CreateStyle(vint index)
{
auto itemStyle = CreateStyleInternal(index);
AddChild(itemStyle);
itemStyle->ForceCalculateSizeImmediately();
AttachEventHandler(itemStyle);
return itemStyle;
}
void GuiVirtualRepeatCompositionBase::DeleteStyle(ItemStyleRecord style)
{
DetachEventHandler(style);
DeleteStyleInternal(style);
}
void GuiVirtualRepeatCompositionBase::UpdateFullSize()
{
Size fullSize, minimumSize;
Layout_CalculateTotalSize(fullSize, minimumSize);
realFullSize = axis->VirtualSizeToRealSize(fullSize);
realMinimumFullSize = axis->VirtualSizeToRealSize(minimumSize);
}
void GuiVirtualRepeatCompositionBase::OnViewChangedInternal(Rect oldBounds, Rect newBounds, bool forceUpdateTotalSize)
{
bool needToUpdateTotalSize = forceUpdateTotalSize;
if (itemTemplate && itemSource)
{
while (true)
{
bool needRestart = false;
vint endIndex = startIndex + visibleStyles.Count() - 1;
vint newStartIndex = 0;
vint itemCount = itemSource->GetCount();
Layout_BeginPlaceItem(true, newBounds, newStartIndex);
if (newStartIndex < 0) newStartIndex = 0;
StyleList newVisibleStyles;
for (vint i = newStartIndex; i < itemCount; i++)
{
bool reuseOldStyle = startIndex <= i && i <= endIndex;
auto style = reuseOldStyle ? visibleStyles[i - startIndex] : CreateStyle(i);
newVisibleStyles.Add(style);
Rect bounds;
Margin alignmentToParent;
auto placeItemResult = Layout_PlaceItem(true, !reuseOldStyle, i, style, newBounds, bounds, alignmentToParent);
if (placeItemResult != VirtualRepeatPlaceItemResult::None)
{
needRestart = placeItemResult == VirtualRepeatPlaceItemResult::Restart;
break;
}
}
vint newEndIndex = newStartIndex + newVisibleStyles.Count() - 1;
for (auto [style, i] : indexed(visibleStyles))
{
vint index = startIndex + i;
if (index < newStartIndex || index > newEndIndex)
{
DeleteStyle(visibleStyles[i]);
}
}
CopyFrom(visibleStyles, newVisibleStyles);
needToUpdateTotalSize = (Layout_EndPlaceItem(true, newBounds, newStartIndex) == VirtualRepeatEndPlaceItemResult::TotalSizeUpdated) || needToUpdateTotalSize;
startIndex = newStartIndex;
if (!needRestart) break;
}
{
vint newStartIndex = startIndex;
Layout_BeginPlaceItem(false, viewBounds, newStartIndex);
for (auto [style, i] : indexed(visibleStyles))
{
Rect bounds;
Margin alignmentToParent(-1, -1, -1, -1);
Layout_PlaceItem(false, false, startIndex + i, style, viewBounds, bounds, alignmentToParent);
bounds.x1 -= viewBounds.x1;
bounds.x2 -= viewBounds.x1;
bounds.y1 -= viewBounds.y1;
bounds.y2 -= viewBounds.y1;
Layout_SetStyleAlignmentToParent(style, alignmentToParent);
Layout_SetStyleBounds(style, bounds);
}
needToUpdateTotalSize = (Layout_EndPlaceItem(false, viewBounds, startIndex) == VirtualRepeatEndPlaceItemResult::TotalSizeUpdated) || needToUpdateTotalSize;
}
}
else if (realFullSize != Size(0, 0))
{
needToUpdateTotalSize = true;
}
if (needToUpdateTotalSize)
{
UpdateFullSize();
TotalSizeChanged.Execute(GuiEventArgs(this));
AdoptedSizeInvalidated.Execute(GuiEventArgs(this));
}
Layout_EndLayout(needToUpdateTotalSize);
}
GuiVirtualRepeatCompositionBase::GuiVirtualRepeatCompositionBase()
{
AxisChanged.SetAssociatedComposition(this);
TotalSizeChanged.SetAssociatedComposition(this);
ViewLocationChanged.SetAssociatedComposition(this);
AdoptedSizeInvalidated.SetAssociatedComposition(this);
}
GuiVirtualRepeatCompositionBase::~GuiVirtualRepeatCompositionBase()
{
for (auto [style, eventHandler] : eventHandlers)
{
style->CachedMinSizeChanged.Detach(eventHandler);
}
eventHandlers.Clear();
}
Ptr<IGuiAxis> GuiVirtualRepeatCompositionBase::GetAxis()
{
return axis;
}
void GuiVirtualRepeatCompositionBase::SetAxis(Ptr<IGuiAxis> value)
{
if (axis != value)
{
OnClearItems();
if (!value) value = Ptr(new GuiDefaultAxis);
axis = value;
if (itemTemplate && itemSource)
{
OnInstallItems();
}
AxisChanged.Execute(GuiEventArgs(this));
}
}
Size GuiVirtualRepeatCompositionBase::GetTotalSize()
{
return useMinimumFullSize ? realMinimumFullSize : realFullSize;
}
bool GuiVirtualRepeatCompositionBase::GetUseMinimumTotalSize()
{
return useMinimumFullSize;
}
void GuiVirtualRepeatCompositionBase::SetUseMinimumTotalSize(bool value)
{
if (useMinimumFullSize != value)
{
useMinimumFullSize = value;
UpdateFullSize();
TotalSizeChanged.Execute(GuiEventArgs(this));
}
}
Point GuiVirtualRepeatCompositionBase::GetViewLocation()
{
return axis->VirtualRectToRealRect(realFullSize, viewBounds).LeftTop();
}
void GuiVirtualRepeatCompositionBase::SetViewLocation(Point value)
{
Size realSize = axis->VirtualSizeToRealSize(viewBounds.GetSize());
Rect realBounds = Rect(value, realSize);
Layout_UpdateViewBounds(axis->RealRectToVirtualRect(realFullSize, realBounds), false);
OnResetViewLocation();
}
GuiVirtualRepeatCompositionBase::ItemStyleRecord GuiVirtualRepeatCompositionBase::GetVisibleStyle(vint itemIndex)
{
if (startIndex <= itemIndex && itemIndex < startIndex + visibleStyles.Count())
{
return visibleStyles[itemIndex - startIndex];
}
else
{
return nullptr;
}
}
vint GuiVirtualRepeatCompositionBase::GetVisibleIndex(ItemStyleRecord style)
{
for (auto [s, i] : indexed(visibleStyles))
{
if (s == style)
{
return i + startIndex;
}
}
return -1;
}
void GuiVirtualRepeatCompositionBase::ResetLayout(bool recreateVisibleStyles)
{
if (recreateVisibleStyles)
{
OnClearItems();
}
else
{
Layout_ResetLayout();
}
}
void GuiVirtualRepeatCompositionBase::InvalidateLayout()
{
itemSourceUpdated = true;
}
Size GuiVirtualRepeatCompositionBase::GetAdoptedSize(Size expectedSize)
{
Size expectedViewSize = axis->RealSizeToVirtualSize(expectedSize);
Size adoptedViewSize = Layout_GetAdoptedSize(expectedViewSize);
Size adoptedSize = axis->VirtualSizeToRealSize(adoptedViewSize);
return adoptedSize;
}
vint GuiVirtualRepeatCompositionBase::FindItemByRealKeyDirection(vint itemIndex, compositions::KeyDirection key)
{
return FindItemByVirtualKeyDirection(itemIndex, axis->RealKeyDirectionToVirtualKeyDirection(key));
}
/***********************************************************************
GuiRepeatFreeHeightItemComposition
***********************************************************************/
void GuiRepeatFreeHeightItemComposition::EnsureOffsetForItem(vint itemIndex)
{
if (heights.Count() == 0) return;
if (availableOffsetCount == 0)
{
availableOffsetCount = 1;
offsets[0] = 0;
}
for (vint i = availableOffsetCount; i < itemIndex && i < heights.Count(); i++)
{
offsets[i] = offsets[i - 1] + heights[i - 1];
}
}
void GuiRepeatFreeHeightItemComposition::Layout_BeginPlaceItem(bool firstPhase, Rect newBounds, vint& newStartIndex)
{
pi_heightUpdated = false;
EnsureOffsetForItem(heights.Count() - 1);
if (firstPhase)
{
// TODO: (enumerable) foreach:indexed
for (vint i = 0; i < heights.Count(); i++)
{
if (heights[i] == 1 && startIndex <= i && i < startIndex + visibleStyles.Count() && visibleStyles[i - startIndex])
{
vint h = visibleStyles[i - startIndex]->GetCachedMinSize().y;
if (h > 1)
{
heights[i] = h;
}
}
if (offsets[i] + heights[i] > newBounds.Top())
{
newStartIndex = i;
break;
}
}
}
}
VirtualRepeatPlaceItemResult GuiRepeatFreeHeightItemComposition::Layout_PlaceItem(bool firstPhase, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent)
{
vint styleHeight = heights[index];
{
vint newStyleHeight = Layout_GetStylePreferredSize(style).y;
if (!newCreatedStyle || styleHeight < newStyleHeight)
{
styleHeight = newStyleHeight;
}
}
if (heights[index] != styleHeight)
{
heights[index] = styleHeight;
pi_heightUpdated = true;
}
vint styleOffset = index == 0 ? 0 : offsets[index - 1] + heights[index - 1];
if (availableOffsetCount <= index || offsets[index] != styleOffset)
{
offsets[index] = styleOffset;
availableOffsetCount = index;
}
bounds = Rect(Point(0, offsets[index]), Size(viewBounds.Width(), heights[index]));
if (bounds.Bottom() >= viewBounds.Bottom())
{
return VirtualRepeatPlaceItemResult::HitLastItem;
}
else
{
return VirtualRepeatPlaceItemResult::None;
}
}
VirtualRepeatEndPlaceItemResult GuiRepeatFreeHeightItemComposition::Layout_EndPlaceItem(bool firstPhase, Rect newBounds, vint newStartIndex)
{
return pi_heightUpdated ? VirtualRepeatEndPlaceItemResult::TotalSizeUpdated : VirtualRepeatEndPlaceItemResult::None;
}
void GuiRepeatFreeHeightItemComposition::Layout_EndLayout(bool totalSizeUpdated)
{
}
void GuiRepeatFreeHeightItemComposition::Layout_InvalidateItemSizeCache()
{
availableOffsetCount = 0;
for (vint i = 0; i < heights.Count(); i++)
{
heights[i] = 1;
}
}
void GuiRepeatFreeHeightItemComposition::Layout_CalculateTotalSize(Size& full, Size& minimum)
{
if (heights.Count() == 0)
{
full = minimum = Size(0, 0);
return;
}
EnsureOffsetForItem(heights.Count());
vint w = viewBounds.Width();
vint h = offsets[heights.Count() - 1] + heights[heights.Count() - 1];
full = Size(w, h);
minimum = Size(0, h);
}
Size GuiRepeatFreeHeightItemComposition::Layout_GetAdoptedSize(Size expectedSize)
{
vint h = expectedSize.x * 2;
if (expectedSize.y < h) expectedSize.y = h;
return expectedSize;
}
void GuiRepeatFreeHeightItemComposition::OnItemChanged(vint start, vint oldCount, vint newCount)
{
availableOffsetCount = start;
vint itemCount = heights.Count() + newCount - oldCount;
if (oldCount < newCount)
{
heights.Resize(itemCount);
if (start + newCount < itemCount)
{
memmove(&heights[start + newCount], &heights[start + oldCount], sizeof(vint) * (itemCount - start - newCount));
}
}
else if (oldCount > newCount)
{
if (start + newCount < itemCount)
{
memmove(&heights[start + newCount], &heights[start + oldCount], sizeof(vint) * (itemCount - start - newCount));
}
heights.Resize(itemCount);
}
for (vint i = 0; i < newCount; i++)
{
heights[start + i] = 1;
}
offsets.Resize(itemCount);
GuiVirtualRepeatCompositionBase::OnItemChanged(start, oldCount, newCount);
}
void GuiRepeatFreeHeightItemComposition::OnInstallItems()
{
heights.Resize(itemSource->GetCount());
Layout_InvalidateItemSizeCache();
offsets.Resize(itemSource->GetCount());
EnsureOffsetForItem(heights.Count() - 1);
GuiVirtualRepeatCompositionBase::OnInstallItems();
}
vint GuiRepeatFreeHeightItemComposition::FindItemByVirtualKeyDirection(vint itemIndex, compositions::KeyDirection key)
{
if (!itemSource) return -1;
vint count = itemSource->GetCount();
if (itemIndex < 0 || itemIndex >= count) return -1;
switch (key)
{
case KeyDirection::Up:
itemIndex--;
break;
case KeyDirection::Down:
itemIndex++;
break;
case KeyDirection::Home:
itemIndex = 0;
break;
case KeyDirection::End:
itemIndex = count - 1;
break;
case KeyDirection::PageUp:
itemIndex -= visibleStyles.Count();
break;
case KeyDirection::PageDown:
itemIndex += visibleStyles.Count();
break;
default:
return -1;
}
if (itemIndex < 0) return 0;
else if (itemIndex >= count) return count - 1;
else return itemIndex;
}
VirtualRepeatEnsureItemVisibleResult GuiRepeatFreeHeightItemComposition::EnsureItemVisible(vint itemIndex)
{
if (!itemSource) return VirtualRepeatEnsureItemVisibleResult::NotMoved;
bool moved = false;
while (true)
{
if (itemIndex < 0 || itemIndex >= itemSource->GetCount())
{
return VirtualRepeatEnsureItemVisibleResult::ItemNotExists;
}
EnsureOffsetForItem(itemIndex);
vint offset = viewBounds.y1;
vint top = offsets[itemIndex];
vint bottom = top + heights[itemIndex];
vint height = viewBounds.Height();
Point location = viewBounds.LeftTop();
if (offset >= top && offset + height <= bottom)
{
break;
}
else if (offset > top)
{
location.y = top;
}
else if (offset < bottom - height)
{
location.y = bottom - height;
}
else
{
break;
}
auto oldLeftTop = viewBounds.LeftTop();
Layout_UpdateViewLocation(location);
moved |= viewBounds.LeftTop() != oldLeftTop;
if (viewBounds.LeftTop() != location) break;
}
return moved ? VirtualRepeatEnsureItemVisibleResult::Moved : VirtualRepeatEnsureItemVisibleResult::NotMoved;
}
/***********************************************************************
GuiRepeatFixedHeightItemComposition
***********************************************************************/
void GuiRepeatFixedHeightItemComposition::Layout_BeginPlaceItem(bool firstPhase, Rect newBounds, vint& newStartIndex)
{
pi_width = itemWidth;
pi_yoffset = itemYOffset;
if (firstPhase)
{
pi_rowHeight = rowHeight;
newStartIndex = newBounds.Top() / pi_rowHeight;
}
}
VirtualRepeatPlaceItemResult GuiRepeatFixedHeightItemComposition::Layout_PlaceItem(bool firstPhase, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent)
{
if (firstPhase)
{
vint styleHeight = Layout_GetStylePreferredSize(style).y;
if (pi_rowHeight < styleHeight)
{
pi_rowHeight = styleHeight;
}
}
vint top = pi_yoffset + index * pi_rowHeight;
if (pi_width == -1)
{
alignmentToParent = Margin(0, -1, 0, -1);
bounds = Rect(Point(0, top), Size(0, pi_rowHeight));
}
else
{
alignmentToParent = Margin(-1, -1, -1, -1);
bounds = Rect(Point(0, top), Size(pi_width, pi_rowHeight));
}
if (bounds.Bottom() >= viewBounds.Bottom())
{
return VirtualRepeatPlaceItemResult::HitLastItem;
}
else
{
return VirtualRepeatPlaceItemResult::None;
}
}
VirtualRepeatEndPlaceItemResult GuiRepeatFixedHeightItemComposition::Layout_EndPlaceItem(bool firstPhase, Rect newBounds, vint newStartIndex)
{
if (firstPhase)
{
if (pi_rowHeight != rowHeight)
{
rowHeight = pi_rowHeight;
return VirtualRepeatEndPlaceItemResult::TotalSizeUpdated;
}
}
return VirtualRepeatEndPlaceItemResult::None;
}
void GuiRepeatFixedHeightItemComposition::Layout_EndLayout(bool totalSizeUpdated)
{
}
void GuiRepeatFixedHeightItemComposition::Layout_InvalidateItemSizeCache()
{
rowHeight = 1;
}
void GuiRepeatFixedHeightItemComposition::Layout_CalculateTotalSize(Size& full, Size& minimum)
{
if (!itemSource || itemSource->GetCount() == 0)
{
full = minimum = Size(0, 0);
return;
}
vint w = itemWidth;
vint w1 = w == -1 ? viewBounds.Width() : w;
vint w2 = w == -1 ? 0 : w;
vint h = rowHeight * itemSource->GetCount() + itemYOffset;
full = Size(w1, h);
minimum = Size(w2, h);
}
Size GuiRepeatFixedHeightItemComposition::Layout_GetAdoptedSize(Size expectedSize)
{
if (!itemSource) return expectedSize;
vint y = expectedSize.y - itemYOffset;
vint itemCount = itemSource->GetCount();
return Size(expectedSize.x, itemYOffset + CalculateAdoptedSize(y, itemCount, rowHeight));
}
vint GuiRepeatFixedHeightItemComposition::FindItemByVirtualKeyDirection(vint itemIndex, compositions::KeyDirection key)
{
vint count = itemSource->GetCount();
if (itemIndex < 0 || itemIndex >= count) return -1;
vint groupCount = viewBounds.Height() / rowHeight;
if (groupCount == 0) groupCount = 1;
switch (key)
{
case KeyDirection::Up:
itemIndex--;
break;
case KeyDirection::Down:
itemIndex++;
break;
case KeyDirection::Home:
itemIndex = 0;
break;
case KeyDirection::End:
itemIndex = count;
break;
case KeyDirection::PageUp:
itemIndex -= groupCount;
break;
case KeyDirection::PageDown:
itemIndex += groupCount;
break;
default:
return -1;
}
if (itemIndex < 0) return 0;
else if (itemIndex >= count) return count - 1;
else return itemIndex;
}
VirtualRepeatEnsureItemVisibleResult GuiRepeatFixedHeightItemComposition::EnsureItemVisible(vint itemIndex)
{
if (!itemSource) return VirtualRepeatEnsureItemVisibleResult::NotMoved;
if (itemIndex < 0 || itemIndex >= itemSource->GetCount())
{
return VirtualRepeatEnsureItemVisibleResult::ItemNotExists;
}
vint viewY1 = viewBounds.y1 + itemYOffset;
vint viewY2 = viewBounds.y2;
vint itemY1 = itemIndex * rowHeight + itemYOffset;
vint itemY2 = itemY1 + rowHeight;
if (viewY2 - viewY1 < rowHeight)
{
if (itemY1 < viewY2 && itemY2 > viewY1)
{
return VirtualRepeatEnsureItemVisibleResult::NotMoved;
}
}
else
{
if (itemY1 >= viewY1 && itemY2 <= viewY2)
{
return VirtualRepeatEnsureItemVisibleResult::NotMoved;
}
if (itemY1 < viewY1 && itemY2 > viewY1)
{
Layout_UpdateViewLocation({ viewBounds.x1,viewBounds.y1 + itemY1 - viewY1 });
return VirtualRepeatEnsureItemVisibleResult::Moved;
}
if (itemY1 < viewY2 && itemY2 > viewY2)
{
Layout_UpdateViewLocation({ viewBounds.x1,viewBounds.y1 + itemY2 - viewY2 });
return VirtualRepeatEnsureItemVisibleResult::Moved;
}
}
bool up = itemY1 < viewY1;
while (true)
{
if (up)
{
if (itemY1 >= viewY1) break;
Layout_UpdateViewLocation({ viewBounds.x1,viewBounds.y1 + itemY1 - viewY1 });
}
else
{
if (itemY2 <= viewY2) break;
Layout_UpdateViewLocation({ viewBounds.x1,viewBounds.y1 + itemY2 - viewY2 });
}
viewY1 = viewBounds.y1 + itemYOffset;
viewY2 = viewBounds.y2;
itemY1 = itemIndex * rowHeight + itemYOffset;
itemY2 = itemY1 + rowHeight;
}
return VirtualRepeatEnsureItemVisibleResult::Moved;
}
vint GuiRepeatFixedHeightItemComposition::GetItemWidth()
{
return itemWidth;
}
void GuiRepeatFixedHeightItemComposition::SetItemWidth(vint value)
{
if (value < -1) value = -1;
if (itemWidth != value)
{
itemWidth = value;
InvalidateLayout();
}
}
vint GuiRepeatFixedHeightItemComposition::GetItemYOffset()
{
return itemYOffset;
}
void GuiRepeatFixedHeightItemComposition::SetItemYOffset(vint value)
{
if (value < 0) value = 0;
if (itemYOffset != value)
{
itemYOffset = value;
InvalidateLayout();
}
}
/***********************************************************************
GuiRepeatFixedSizeMultiColumnItemComposition
***********************************************************************/
void GuiRepeatFixedSizeMultiColumnItemComposition::Layout_BeginPlaceItem(bool firstPhase, Rect newBounds, vint& newStartIndex)
{
if (firstPhase)
{
pi_itemSize = itemSize;
vint rows = newBounds.Top() / pi_itemSize.y;
if (rows < 0) rows = 0;
vint cols = newBounds.Width() / pi_itemSize.x;
if (cols < 1) cols = 1;
newStartIndex = rows * cols;
}
}
VirtualRepeatPlaceItemResult GuiRepeatFixedSizeMultiColumnItemComposition::Layout_PlaceItem(bool firstPhase, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent)
{
if (firstPhase)
{
Size styleSize = Layout_GetStylePreferredSize(style);
if (pi_itemSize.x < styleSize.x) pi_itemSize.x = styleSize.x;
if (pi_itemSize.y < styleSize.y) pi_itemSize.y = styleSize.y;
}
vint rowItems = viewBounds.Width() / pi_itemSize.x;
if (rowItems < 1) rowItems = 1;
vint row = index / rowItems;
vint col = index % rowItems;
bounds = Rect(Point(col * pi_itemSize.x, row * pi_itemSize.y), pi_itemSize);
if (col == rowItems - 1 && bounds.Bottom() >= viewBounds.Bottom())
{
return VirtualRepeatPlaceItemResult::HitLastItem;
}
else
{
return VirtualRepeatPlaceItemResult::None;
}
}
VirtualRepeatEndPlaceItemResult GuiRepeatFixedSizeMultiColumnItemComposition::Layout_EndPlaceItem(bool firstPhase, Rect newBounds, vint newStartIndex)
{
if (firstPhase)
{
if (pi_itemSize != itemSize)
{
itemSize = pi_itemSize;
return VirtualRepeatEndPlaceItemResult::TotalSizeUpdated;
}
}
return VirtualRepeatEndPlaceItemResult::None;
}
void GuiRepeatFixedSizeMultiColumnItemComposition::Layout_EndLayout(bool totalSizeUpdated)
{
}
void GuiRepeatFixedSizeMultiColumnItemComposition::Layout_InvalidateItemSizeCache()
{
itemSize = Size(1, 1);
}
void GuiRepeatFixedSizeMultiColumnItemComposition::Layout_CalculateTotalSize(Size& full, Size& minimum)
{
if (!itemSource || itemSource->GetCount() == 0)
{
full = minimum = Size(0, 0);
return;
}
vint rowItems = viewBounds.Width() / itemSize.x;
if (rowItems < 1) rowItems = 1;
vint rows = itemSource->GetCount() / rowItems;
if (itemSource->GetCount() % rowItems) rows++;
vint h = itemSize.y * rows;
full = Size(itemSize.x * rowItems, h);
minimum = Size(itemSize.x, h);
}
Size GuiRepeatFixedSizeMultiColumnItemComposition::Layout_GetAdoptedSize(Size expectedSize)
{
if (!itemSource) return expectedSize;
vint count = itemSource->GetCount();
vint columnCount = viewBounds.Width() / itemSize.x;
vint rowCount = count / columnCount;
if (count % columnCount != 0) rowCount++;
if (columnCount == 0) columnCount = 1;
if (rowCount == 0) rowCount = 1;
return Size(
CalculateAdoptedSize(expectedSize.x, columnCount, itemSize.x),
CalculateAdoptedSize(expectedSize.y, rowCount, itemSize.y)
);
}
vint GuiRepeatFixedSizeMultiColumnItemComposition::FindItemByVirtualKeyDirection(vint itemIndex, compositions::KeyDirection key)
{
vint count = itemSource->GetCount();
if (itemIndex < 0 || itemIndex >= count) return -1;
vint columnCount = viewBounds.Width() / itemSize.x;
if (columnCount == 0) columnCount = 1;
vint rowCount = viewBounds.Height() / itemSize.y;
if (rowCount == 0) rowCount = 1;
switch (key)
{
case KeyDirection::Up:
itemIndex -= columnCount;
break;
case KeyDirection::Down:
itemIndex += columnCount;
break;
case KeyDirection::Left:
itemIndex--;
break;
case KeyDirection::Right:
itemIndex++;
break;
case KeyDirection::Home:
itemIndex = 0;
break;
case KeyDirection::End:
itemIndex = count;
break;
case KeyDirection::PageUp:
itemIndex -= columnCount * rowCount;
break;
case KeyDirection::PageDown:
itemIndex += columnCount * rowCount;
break;
case KeyDirection::PageLeft:
itemIndex -= itemIndex % columnCount;
break;
case KeyDirection::PageRight:
itemIndex += columnCount - itemIndex % columnCount - 1;
break;
default:
return -1;
}
if (itemIndex < 0) return 0;
else if (itemIndex >= count) return count - 1;
else return itemIndex;
}
VirtualRepeatEnsureItemVisibleResult GuiRepeatFixedSizeMultiColumnItemComposition::EnsureItemVisible(vint itemIndex)
{
if (!itemSource) return VirtualRepeatEnsureItemVisibleResult::NotMoved;
if (itemIndex < 0 || itemIndex >= itemSource->GetCount())
{
return VirtualRepeatEnsureItemVisibleResult::ItemNotExists;
}
bool moved = false;
while (true)
{
vint rowHeight = itemSize.y;
vint columnCount = viewBounds.Width() / itemSize.x;
if (columnCount == 0) columnCount = 1;
vint rowIndex = itemIndex / columnCount;
vint top = rowIndex * rowHeight;
vint bottom = top + rowHeight;
if (viewBounds.Height() < rowHeight)
{
if (viewBounds.Top() < bottom && top < viewBounds.Bottom())
{
break;
}
}
Point location = viewBounds.LeftTop();
if (top < viewBounds.Top())
{
location.y = top;
}
else if (viewBounds.Bottom() < bottom)
{
location.y = bottom - viewBounds.Height();
}
else
{
break;
}
auto oldLeftTop = viewBounds.LeftTop();
Layout_UpdateViewLocation(location);
moved |= viewBounds.LeftTop() != oldLeftTop;
if (viewBounds.LeftTop() != location) break;
}
return moved ? VirtualRepeatEnsureItemVisibleResult::Moved : VirtualRepeatEnsureItemVisibleResult::NotMoved;
}
/***********************************************************************
GuiRepeatFixedHeightMultiColumnItemComposition
***********************************************************************/
void GuiRepeatFixedHeightMultiColumnItemComposition::FixColumnWidth(vint index)
{
vint c = index / pi_rows - pi_firstColumn;
vint r = index % pi_rows;
vint w = pi_visibleItemWidths[index - pi_firstColumn * pi_rows];
if (r == 0)
{
while (pi_visibleColumnWidths.Count() <= c) pi_visibleColumnWidths.Add(0);
while (pi_visibleColumnOffsets.Count() <= c) pi_visibleColumnOffsets.Add(0);
pi_visibleColumnWidths[c] = w;
if (c == 0)
{
pi_visibleColumnOffsets[c] = 0;
}
else
{
pi_visibleColumnOffsets[c] = pi_visibleColumnOffsets[c - 1] + pi_visibleColumnWidths[c - 1];
}
}
else
{
if (pi_visibleColumnWidths[c] < w)
{
pi_visibleColumnWidths[c] = w;
}
}
}
void GuiRepeatFixedHeightMultiColumnItemComposition::Layout_BeginPlaceItem(bool firstPhase, Rect newBounds, vint& newStartIndex)
{
if (firstPhase)
{
pi_firstColumn = newBounds.Width() == 0 ? 0 : newBounds.x1 / newBounds.Width();
pi_itemHeight = itemHeight;
pi_visibleItemWidths.Clear();
pi_visibleColumnWidths.Clear();
pi_visibleColumnOffsets.Clear();
pi_rows = newBounds.Height() / itemHeight;
if (pi_rows < 1) pi_rows = 1;
if (pi_firstColumn < 0)
{
pi_firstColumn = 0;
}
else if (pi_firstColumn * pi_rows >= itemSource->GetCount())
{
pi_firstColumn = (itemSource->GetCount() + pi_rows - 1) / pi_rows - 1;
}
newStartIndex = pi_firstColumn * pi_rows;
}
}
VirtualRepeatPlaceItemResult GuiRepeatFixedHeightMultiColumnItemComposition::Layout_PlaceItem(bool firstPhase, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent)
{
#define ERROR_MESSAGE_INTERNAL_ERROR L"vl::presentation::compositions::GuiRepeatFixedHeightMultiColumnItemComposition::Layout_PlaceItem(...)#Internal error."
vint visibleColumn = index / pi_rows - pi_firstColumn;
vint visibleRow = index % pi_rows;
if (firstPhase)
{
Size styleSize = Layout_GetStylePreferredSize(style);
if (pi_itemHeight < styleSize.y)
{
pi_itemHeight = styleSize.y;
vint newRows = viewBounds.Height() / pi_itemHeight;
if (newRows != pi_rows)
{
CHECK_ERROR(newRows < pi_rows, ERROR_MESSAGE_INTERNAL_ERROR);
vint oldFirstIndex = pi_firstColumn * pi_rows;
pi_rows = newRows > 0 ? newRows : 1;
vint newFirstIndex = pi_firstColumn * pi_rows;
if (oldFirstIndex == newFirstIndex)
{
for (vint i = newFirstIndex; i < index; i++)
{
FixColumnWidth(i + newFirstIndex);
}
}
else
{
CHECK_ERROR(oldFirstIndex > newFirstIndex, ERROR_MESSAGE_INTERNAL_ERROR);
return VirtualRepeatPlaceItemResult::Restart;
}
visibleColumn = index / pi_rows - pi_firstColumn;
visibleRow = index % pi_rows;
}
}
pi_visibleItemWidths.Add(styleSize.x);
FixColumnWidth(index);
}
vint x = viewBounds.x1 + pi_visibleColumnOffsets[visibleColumn];
vint y = pi_itemHeight * visibleRow;
vint w = pi_visibleItemWidths[index - pi_firstColumn * pi_rows];
bounds = Rect({ x,y }, { w,pi_itemHeight });
if (visibleRow == pi_rows - 1 && pi_visibleColumnOffsets[visibleColumn] + pi_visibleColumnWidths[visibleColumn] >= viewBounds.Width())
{
return VirtualRepeatPlaceItemResult::HitLastItem;
}
else
{
return VirtualRepeatPlaceItemResult::None;
}
#undef ERROR_MESSAGE_INTERNAL_ERROR
}
VirtualRepeatEndPlaceItemResult GuiRepeatFixedHeightMultiColumnItemComposition::Layout_EndPlaceItem(bool firstPhase, Rect newBounds, vint newStartIndex)
{
if (firstPhase)
{
bool itemHeightUpdated = pi_itemHeight != itemHeight;
firstColumn = pi_firstColumn;
itemHeight = pi_itemHeight;
if (pi_visibleColumnOffsets.Count() <= 1)
{
fullVisibleColumns = pi_visibleColumnOffsets.Count();
}
else
{
vint c = pi_visibleColumnOffsets.Count() - 1;
vint x = pi_visibleColumnOffsets[c] + pi_visibleColumnWidths[c];
if (x <= viewBounds.Width())
{
fullVisibleColumns = c + 1;
}
else
{
fullVisibleColumns = c;
}
}
if (itemHeightUpdated)
{
return VirtualRepeatEndPlaceItemResult::TotalSizeUpdated;
}
}
return VirtualRepeatEndPlaceItemResult::None;
}
void GuiRepeatFixedHeightMultiColumnItemComposition::Layout_EndLayout(bool totalSizeUpdated)
{
}
void GuiRepeatFixedHeightMultiColumnItemComposition::Layout_InvalidateItemSizeCache()
{
itemHeight = 1;
}
void GuiRepeatFixedHeightMultiColumnItemComposition::Layout_CalculateTotalSize(Size& full, Size& minimum)
{
if (!itemSource || itemSource->GetCount() == 0)
{
full = minimum = Size(0, 0);
return;
}
vint rows = viewBounds.Height() / itemHeight;
if (rows < 1) rows = 1;
vint columns = (itemSource->GetCount() + rows - 1) / rows;
vint w = viewBounds.Width() * (columns + 1);
vint h = rows * itemHeight;
full = Size(w, h);
minimum = Size(w, 0);
}
Size GuiRepeatFixedHeightMultiColumnItemComposition::Layout_GetAdoptedSize(Size expectedSize)
{
if (!itemSource) return expectedSize;
vint count = itemSource->GetCount();
vint rowCount = viewBounds.Height() / itemHeight;
if (rowCount > count) rowCount = count;
if (rowCount == 0) rowCount = 1;
return Size(expectedSize.x, CalculateAdoptedSize(expectedSize.y, rowCount, itemHeight));
}
vint GuiRepeatFixedHeightMultiColumnItemComposition::FindItemByVirtualKeyDirection(vint itemIndex, compositions::KeyDirection key)
{
vint count = itemSource->GetCount();
if (itemIndex < 0 || itemIndex >= count) return -1;
vint rowCount = viewBounds.Height() / itemHeight;
if (rowCount == 0) rowCount = 1;
switch (key)
{
case KeyDirection::Up:
itemIndex--;
break;
case KeyDirection::Down:
itemIndex++;
break;
case KeyDirection::Left:
itemIndex -= rowCount;
break;
case KeyDirection::Right:
itemIndex += rowCount;
break;
case KeyDirection::Home:
itemIndex = 0;
break;
case KeyDirection::End:
itemIndex = count;
break;
case KeyDirection::PageUp:
itemIndex -= itemIndex % rowCount;
break;
case KeyDirection::PageDown:
itemIndex += rowCount - itemIndex % rowCount - 1;
break;
default:
return -1;
}
if (itemIndex < 0) return 0;
else if (itemIndex >= count) return count - 1;
else return itemIndex;
}
VirtualRepeatEnsureItemVisibleResult GuiRepeatFixedHeightMultiColumnItemComposition::EnsureItemVisible(vint itemIndex)
{
if (!itemSource) return VirtualRepeatEnsureItemVisibleResult::NotMoved;
if (itemIndex < 0 || itemIndex >= itemSource->GetCount())
{
return VirtualRepeatEnsureItemVisibleResult::ItemNotExists;
}
bool moved = false;
while (true)
{
vint rowCount = viewBounds.Height() / itemHeight;
if (rowCount == 0) rowCount = 1;
vint column = itemIndex / rowCount;
Point location = viewBounds.LeftTop();
if (column < firstColumn)
{
location.x = viewBounds.Width() * column;
}
else if (column >= firstColumn + fullVisibleColumns)
{
location.x = viewBounds.Width() * (column - fullVisibleColumns + 1);
}
else
{
break;
}
auto oldLeftTop = viewBounds.LeftTop();
Layout_UpdateViewLocation(location);
moved |= viewBounds.LeftTop() != oldLeftTop;
if (viewBounds.LeftTop() != location) break;
}
return moved ? VirtualRepeatEnsureItemVisibleResult::Moved : VirtualRepeatEnsureItemVisibleResult::NotMoved;
}
}
}
}
/***********************************************************************
.\GRAPHICSCOMPOSITION\GUIGRAPHICSRESPONSIVECOMPOSITION.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
using namespace collections;
using namespace controls;
/***********************************************************************
GuiResponsiveCompositionBase
***********************************************************************/
void GuiResponsiveCompositionBase::OnParentLineChanged()
{
GuiBoundsComposition::OnParentLineChanged();
GuiResponsiveCompositionBase* responsive = nullptr;
{
auto parent = GetParent();
while (parent)
{
if ((responsive = dynamic_cast<GuiResponsiveCompositionBase*>(parent)))
{
break;
}
parent = parent->GetParent();
}
}
if (responsiveParent != responsive)
{
if (responsiveParent)
{
responsiveParent->OnResponsiveChildRemoved(this);
responsiveParent->OnResponsiveChildLevelUpdated();
}
responsiveParent = responsive;
if (responsiveParent)
{
responsiveParent->OnResponsiveChildInserted(this);
responsiveParent->OnResponsiveChildLevelUpdated();
}
}
}
void GuiResponsiveCompositionBase::OnResponsiveChildInserted(GuiResponsiveCompositionBase* child)
{
}
void GuiResponsiveCompositionBase::OnResponsiveChildRemoved(GuiResponsiveCompositionBase* child)
{
}
void GuiResponsiveCompositionBase::OnResponsiveChildLevelUpdated()
{
if (responsiveParent)
{
responsiveParent->OnResponsiveChildLevelUpdated();
}
else
{
InvokeOnCompositionStateChanged();
}
}
GuiResponsiveCompositionBase::GuiResponsiveCompositionBase()
{
SetMinSizeLimitation(LimitToElementAndChildren);
SetPreferredMinSize(Size(1, 1));
LevelCountChanged.SetAssociatedComposition(this);
CurrentLevelChanged.SetAssociatedComposition(this);
}
ResponsiveDirection GuiResponsiveCompositionBase::GetDirection()
{
return direction;
}
void GuiResponsiveCompositionBase::SetDirection(ResponsiveDirection value)
{
if (direction != value)
{
direction = value;
OnResponsiveChildLevelUpdated();
}
}
/***********************************************************************
GuiResponsiveSharedCollection
***********************************************************************/
void GuiResponsiveSharedCollection::BeforeInsert(vint index, controls::GuiControl* const& value)
{
CHECK_ERROR(!value->GetBoundsComposition()->GetParent(), L"GuiResponsiveSharedCollection::BeforeInsert(vint, GuiResponsiveSharedCollection* const&)#Cannot insert a shared control that is currently in use.");
}
void GuiResponsiveSharedCollection::AfterInsert(vint index, controls::GuiControl* const& value)
{
view->OnResponsiveChildLevelUpdated();
}
void GuiResponsiveSharedCollection::BeforeRemove(vint index, controls::GuiControl* const& value)
{
CHECK_ERROR(!value->GetBoundsComposition()->GetParent(), L"GuiResponsiveSharedCollection::BeforeRemove(vint, GuiResponsiveSharedCollection* const&)#Cannot remove a shared control that is currently in use.");
}
void GuiResponsiveSharedCollection::AfterRemove(vint index, vint count)
{
view->OnResponsiveChildLevelUpdated();
}
GuiResponsiveSharedCollection::GuiResponsiveSharedCollection(GuiResponsiveViewComposition* _view)
:view(_view)
{
}
/***********************************************************************
GuiResponsiveViewCollection
***********************************************************************/
void GuiResponsiveViewCollection::BeforeInsert(vint index, GuiResponsiveCompositionBase* const& value)
{
CHECK_ERROR(!value->GetParent(), L"GuiResponsiveViewCollection::BeforeRemove(vint, GuiResponsiveCompositionBase* const&)#Cannot insert a view that is currently in use.");
}
void GuiResponsiveViewCollection::AfterInsert(vint index, GuiResponsiveCompositionBase* const& value)
{
if (!view->currentView)
{
view->skipUpdatingLevels = true;
view->currentView = value;
view->currentView->SetAlignmentToParent(Margin(0, 0, 0, 0));
view->AddChild(view->currentView);
view->skipUpdatingLevels = false;
}
view->OnResponsiveChildLevelUpdated();
}
void GuiResponsiveViewCollection::BeforeRemove(vint index, GuiResponsiveCompositionBase* const& value)
{
CHECK_ERROR(!value->GetParent(), L"GuiResponsiveViewCollection::BeforeRemove(vint, GuiResponsiveCompositionBase* const&)#Cannot remove a view that is currently in use.");
}
void GuiResponsiveViewCollection::AfterRemove(vint index, vint count)
{
view->OnResponsiveChildLevelUpdated();
}
GuiResponsiveViewCollection::GuiResponsiveViewCollection(GuiResponsiveViewComposition* _view)
:view(_view)
{
}
/***********************************************************************
GuiResponsiveSharedComposition
***********************************************************************/
void GuiResponsiveSharedComposition::SetSharedControl()
{
if (shared && view && !view->destructing)
{
auto sharedParent = shared->GetBoundsComposition()->GetParent();
CHECK_ERROR(view->sharedControls.Contains(shared), L"GuiResponsiveSharedComposition::SetSharedControl()#The specified shared control is not in GuiResponsiveViewComposition::GetSharedControls().");
CHECK_ERROR(!sharedParent || sharedParent == this, L"GuiResponsiveSharedComposition::SetSharedControl()#The specified shared control has not been released. This usually means this control is not in GuiResponsiveViewComposition::GetSharedControls().");
if (!sharedParent)
{
shared->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
AddChild(shared->GetBoundsComposition());
view->usedSharedControls.Add(shared);
}
}
}
void GuiResponsiveSharedComposition::OnParentLineChanged()
{
GuiBoundsComposition::OnParentLineChanged();
if (view && view->destructing)
{
return;
}
GuiResponsiveViewComposition* currentView = nullptr;
{
auto parent = GetParent();
while (parent)
{
if ((currentView = dynamic_cast<GuiResponsiveViewComposition*>(parent)))
{
break;
}
parent = parent->GetParent();
}
}
if (currentView != view && view && shared)
{
RemoveChild(shared->GetBoundsComposition());
view->usedSharedControls.Remove(shared);
}
view = currentView;
SetSharedControl();
}
GuiResponsiveSharedComposition::GuiResponsiveSharedComposition()
{
SetMinSizeLimitation(LimitToElementAndChildren);
}
controls::GuiControl* GuiResponsiveSharedComposition::GetShared()
{
return shared;
}
void GuiResponsiveSharedComposition::SetShared(controls::GuiControl* value)
{
if (shared != value)
{
CHECK_ERROR(!shared || !shared->GetBoundsComposition()->GetParent(), L"GuiResponsiveSharedComposition::SetShared(GuiControl*)#Cannot replace a shared control that is currently in use.");
shared = value;
SetSharedControl();
}
}
/***********************************************************************
GuiResponsiveViewComposition
***********************************************************************/
bool GuiResponsiveViewComposition::CalculateLevelCount()
{
vint old = levelCount;
if (views.Count() == 0)
{
levelCount = 1;
}
else
{
levelCount = 0;
// TODO: (enumerable) foreach
for (vint i = 0; i < views.Count(); i++)
{
auto view = views[i];
if (((vint)direction & (vint)view->GetDirection()) != 0)
{
levelCount += view->GetLevelCount();
}
else
{
levelCount += 1;
}
}
}
if (old != levelCount)
{
LevelCountChanged.Execute(GuiEventArgs(this));
return true;
}
return false;
}
bool GuiResponsiveViewComposition::CalculateCurrentLevel()
{
vint old = currentLevel;
currentLevel = 0;
// TODO: (enumerable) foreach:reversed
for (vint i = views.Count() - 1; i >= 0; i--)
{
auto view = views[i];
if (((vint)direction & (vint)view->GetDirection()) != 0)
{
if (currentView == view)
{
currentLevel += view->GetCurrentLevel() + 1;
break;
}
else
{
currentLevel += view->GetLevelCount();
}
}
else
{
currentLevel++;
}
}
currentLevel--;
if (old != currentLevel)
{
CurrentLevelChanged.Execute(GuiEventArgs(this));
return true;
}
return false;
}
void GuiResponsiveViewComposition::OnResponsiveChildLevelUpdated()
{
if (!skipUpdatingLevels)
{
CalculateLevelCount();
CalculateCurrentLevel();
GuiResponsiveCompositionBase::OnResponsiveChildLevelUpdated();
}
}
GuiResponsiveViewComposition::GuiResponsiveViewComposition()
:sharedControls(this)
, views(this)
{
BeforeSwitchingView.SetAssociatedComposition(this);
}
GuiResponsiveViewComposition::~GuiResponsiveViewComposition()
{
destructing = true;
for (auto view : views)
{
if (view != currentView)
{
SafeDeleteComposition(view);
}
}
for (auto shared : From(sharedControls).Except(usedSharedControls))
{
SafeDeleteControl(shared);
}
}
vint GuiResponsiveViewComposition::GetLevelCount()
{
return levelCount;
}
vint GuiResponsiveViewComposition::GetCurrentLevel()
{
return currentLevel;
}
bool GuiResponsiveViewComposition::LevelDown()
{
skipUpdatingLevels = true;
if (((vint)direction & (vint)currentView->GetDirection()) != 0 && !currentView->LevelDown())
{
vint index = views.IndexOf(currentView);
if (index < views.Count() - 1)
{
RemoveChild(currentView);
currentView = views[index + 1];
currentView->SetAlignmentToParent(Margin(0, 0, 0, 0));
{
GuiItemEventArgs arguments(this);
arguments.itemIndex = views.IndexOf(currentView);
BeforeSwitchingView.Execute(arguments);
}
AddChild(currentView);
}
}
skipUpdatingLevels = false;
auto x = CalculateLevelCount();
auto y = CalculateCurrentLevel();
if (!x && !y) return false;
InvokeOnCompositionStateChanged();
return true;
}
bool GuiResponsiveViewComposition::LevelUp()
{
skipUpdatingLevels = true;
if (((vint)direction & (vint)currentView->GetDirection()) != 0 && !currentView->LevelUp())
{
vint index = views.IndexOf(currentView);
if (index > 0)
{
RemoveChild(currentView);
currentView = views[index - 1];
currentView->SetAlignmentToParent(Margin(0, 0, 0, 0));
{
GuiItemEventArgs arguments(this);
arguments.itemIndex = views.IndexOf(currentView);
BeforeSwitchingView.Execute(arguments);
}
AddChild(currentView);
}
}
skipUpdatingLevels = false;
auto x = CalculateLevelCount();
auto y = CalculateCurrentLevel();
if (!x && !y) return false;
InvokeOnCompositionStateChanged();
return true;
}
GuiResponsiveCompositionBase* GuiResponsiveViewComposition::GetCurrentView()
{
return currentView;
}
collections::ObservableListBase<controls::GuiControl*>& GuiResponsiveViewComposition::GetSharedControls()
{
return sharedControls;
}
collections::ObservableListBase<GuiResponsiveCompositionBase*>& GuiResponsiveViewComposition::GetViews()
{
return views;
}
/***********************************************************************
GuiResponsiveFixedComposition
***********************************************************************/
void GuiResponsiveFixedComposition::OnResponsiveChildLevelUpdated()
{
InvokeOnCompositionStateChanged();
}
vint GuiResponsiveFixedComposition::GetLevelCount()
{
return 1;
}
vint GuiResponsiveFixedComposition::GetCurrentLevel()
{
return 0;
}
bool GuiResponsiveFixedComposition::LevelDown()
{
return false;
}
bool GuiResponsiveFixedComposition::LevelUp()
{
return false;
}
/***********************************************************************
GuiResponsiveStackComposition
***********************************************************************/
#define DEFINE_AVAILABLE \
auto availables = From(responsiveChildren) \
.Where([=](GuiResponsiveCompositionBase* child) \
{ \
return ((vint)direction & (vint)child->GetDirection()) != 0; \
}) \
bool GuiResponsiveStackComposition::CalculateLevelCount()
{
vint old = levelCount;
DEFINE_AVAILABLE;
if (availables.IsEmpty())
{
levelCount = 1;
}
else
{
levelCount = availables
.Select([](GuiResponsiveCompositionBase* child)
{
return child->GetLevelCount() - 1;
})
.Aggregate([](vint a, vint b)
{
return a + b;
}) + 1;
}
if (old != levelCount)
{
LevelCountChanged.Execute(GuiEventArgs(this));
return true;
}
return false;
}
bool GuiResponsiveStackComposition::CalculateCurrentLevel()
{
vint old = currentLevel;
DEFINE_AVAILABLE;
if (availables.IsEmpty())
{
currentLevel = 0;
}
else
{
currentLevel = availables
.Select([](GuiResponsiveCompositionBase* child)
{
return child->GetCurrentLevel();
})
.Aggregate([](vint a, vint b)
{
return a + b;
});
}
if (old != currentLevel)
{
CurrentLevelChanged.Execute(GuiEventArgs(this));
return true;
}
return false;
}
void GuiResponsiveStackComposition::OnResponsiveChildInserted(GuiResponsiveCompositionBase* child)
{
responsiveChildren.Add(child);
}
void GuiResponsiveStackComposition::OnResponsiveChildRemoved(GuiResponsiveCompositionBase* child)
{
responsiveChildren.Remove(child);
}
void GuiResponsiveStackComposition::OnResponsiveChildLevelUpdated()
{
CalculateLevelCount();
CalculateCurrentLevel();
GuiResponsiveCompositionBase::OnResponsiveChildLevelUpdated();
}
bool GuiResponsiveStackComposition::ChangeLevel(bool levelDown)
{
DEFINE_AVAILABLE;
SortedList<GuiResponsiveCompositionBase*> ignored;
while (true)
{
GuiResponsiveCompositionBase* selected = nullptr;
vint size = 0;
for (auto child : availables)
{
if (!ignored.Contains(child))
{
Size childSize = child->GetCachedBounds().GetSize();
vint childSizeToCompare =
direction == ResponsiveDirection::Horizontal ? childSize.x :
direction == ResponsiveDirection::Vertical ? childSize.y :
childSize.x * childSize.y;
if (!selected || (levelDown ? size < childSizeToCompare : size > childSizeToCompare))
{
selected = child;
size = childSizeToCompare;
}
}
}
if (!selected)
{
break;
}
else if (levelDown ? selected->LevelDown() : selected->LevelUp())
{
break;
}
else
{
ignored.Add(selected);
}
}
if (!CalculateCurrentLevel()) return false;
InvokeOnCompositionStateChanged();
return true;
}
vint GuiResponsiveStackComposition::GetLevelCount()
{
return levelCount;
}
vint GuiResponsiveStackComposition::GetCurrentLevel()
{
return currentLevel;
}
bool GuiResponsiveStackComposition::LevelDown()
{
return ChangeLevel(true);
}
bool GuiResponsiveStackComposition::LevelUp()
{
return ChangeLevel(false);
}
/***********************************************************************
GuiResponsiveGroupComposition
***********************************************************************/
bool GuiResponsiveGroupComposition::CalculateLevelCount()
{
vint old = levelCount;
DEFINE_AVAILABLE;
if (availables.IsEmpty())
{
levelCount = 1;
}
else
{
levelCount = availables
.Select([](GuiResponsiveCompositionBase* child)
{
return child->GetLevelCount();
})
.Max();
}
if (old != levelCount)
{
LevelCountChanged.Execute(GuiEventArgs(this));
return true;
}
return false;
}
bool GuiResponsiveGroupComposition::CalculateCurrentLevel()
{
vint old = currentLevel;
DEFINE_AVAILABLE;
if (availables.IsEmpty())
{
currentLevel = 0;
}
else
{
currentLevel = availables
.Select([](GuiResponsiveCompositionBase* child)
{
return child->GetCurrentLevel();
})
.Max();
}
if (old != currentLevel)
{
CurrentLevelChanged.Execute(GuiEventArgs(this));
return true;
}
return false;
}
void GuiResponsiveGroupComposition::OnResponsiveChildInserted(GuiResponsiveCompositionBase* child)
{
responsiveChildren.Add(child);
}
void GuiResponsiveGroupComposition::OnResponsiveChildRemoved(GuiResponsiveCompositionBase* child)
{
responsiveChildren.Remove(child);
}
void GuiResponsiveGroupComposition::OnResponsiveChildLevelUpdated()
{
CalculateLevelCount();
CalculateCurrentLevel();
GuiResponsiveCompositionBase::OnResponsiveChildLevelUpdated();
}
vint GuiResponsiveGroupComposition::GetLevelCount()
{
return levelCount;
}
vint GuiResponsiveGroupComposition::GetCurrentLevel()
{
return currentLevel;
}
bool GuiResponsiveGroupComposition::LevelDown()
{
DEFINE_AVAILABLE;
vint level = currentLevel;
for (auto child : availables)
{
if (child->GetCurrentLevel() >= level)
{
if (!child->LevelDown())
{
break;
}
}
}
if (!CalculateCurrentLevel()) return false;
InvokeOnCompositionStateChanged();
return true;
}
bool GuiResponsiveGroupComposition::LevelUp()
{
DEFINE_AVAILABLE;
vint level = currentLevel;
for (auto child : availables)
{
while (child->GetCurrentLevel() <= level)
{
if (!child->LevelUp())
{
break;
}
}
}
if (!CalculateCurrentLevel()) return false;
InvokeOnCompositionStateChanged();
return true;
}
#undef DEFINE_AVAILABLE
/***********************************************************************
GuiResponsiveContainerComposition
***********************************************************************/
std::strong_ordering GuiResponsiveContainerComposition::Layout_CompareSize(Size first, Size second)
{
auto ordX = testX ? first.x <=> second.x : std::strong_ordering::equivalent;
auto ordY = testY ? first.y <=> second.y : std::strong_ordering::equivalent;
if (ordX == std::strong_ordering::less || ordY == std::strong_ordering::less)
{
return std::strong_ordering::less;
}
if (ordX == std::strong_ordering::greater || ordY == std::strong_ordering::greater)
{
return std::strong_ordering::greater;
}
return std::strong_ordering::equivalent;
}
void GuiResponsiveContainerComposition::Layout_AdjustLevelUp(Size containerSize)
{
while (true)
{
if (responsiveTarget->GetCurrentLevel() == responsiveTarget->GetLevelCount() - 1) break;
if (Layout_CompareSize(minSizeLowerBound, minSizeUpperBound) == std::strong_ordering::less)
{
if (Layout_CompareSize(containerSize, minSizeUpperBound) == std::strong_ordering::less) break;
}
else
{
if (Layout_CompareSize(containerSize, minSizeUpperBound) != std::strong_ordering::greater) break;
}
if (!responsiveTarget->LevelUp()) break;
responsiveTarget->Layout_UpdateMinSize();
minSizeUpperBound = responsiveTarget->GetCachedMinSize();
if (Layout_CompareSize(containerSize, minSizeUpperBound) == std::strong_ordering::less)
{
responsiveTarget->LevelDown();
responsiveTarget->Layout_UpdateMinSize();
break;
}
minSizeLowerBound = minSizeUpperBound;
}
}
void GuiResponsiveContainerComposition::Layout_AdjustLevelDown(Size containerSize)
{
while (true)
{
if (responsiveTarget->GetCurrentLevel() == 0) break;
if (Layout_CompareSize(containerSize, minSizeLowerBound) != std::strong_ordering::less) break;
if (!responsiveTarget->LevelDown()) break;
responsiveTarget->Layout_UpdateMinSize();
minSizeUpperBound = minSizeLowerBound;
minSizeLowerBound = responsiveTarget->GetCachedMinSize();
}
}
Rect GuiResponsiveContainerComposition::Layout_CalculateBounds(Size parentSize)
{
auto bounds = GuiBoundsComposition::Layout_CalculateBounds(parentSize);
if (responsiveTarget)
{
bool needAdjust = false;
auto containerSize = bounds.GetSize();
auto ordering = std::strong_ordering::equivalent;
if (containerSize != cachedBounds.GetSize())
{
ordering = Layout_CompareSize(containerSize, cachedBounds.GetSize());
needAdjust = true;
}
if (responsiveTarget)
{
if (responsiveTarget->GetCachedMinSize() != minSizeLowerBound)
{
minSizeLowerBound = responsiveTarget->GetCachedMinSize();
if (minSizeUpperBound.x < minSizeLowerBound.x) minSizeUpperBound.x = minSizeLowerBound.x;
if (minSizeUpperBound.y < minSizeLowerBound.y) minSizeUpperBound.y = minSizeLowerBound.y;
}
if (Layout_CompareSize(containerSize, minSizeLowerBound) == std::strong_ordering::less)
{
ordering = std::strong_ordering::less;
needAdjust = true;
}
}
if (needAdjust)
{
if (ordering == std::strong_ordering::less)
{
Layout_AdjustLevelDown(containerSize);
}
else if (ordering == std::strong_ordering::greater)
{
Layout_AdjustLevelUp(containerSize);
}
}
}
return bounds;
}
GuiResponsiveContainerComposition::GuiResponsiveContainerComposition()
{
}
GuiResponsiveCompositionBase* GuiResponsiveContainerComposition::GetResponsiveTarget()
{
return responsiveTarget;
}
void GuiResponsiveContainerComposition::SetResponsiveTarget(GuiResponsiveCompositionBase* value)
{
if (responsiveTarget != value)
{
if (responsiveTarget)
{
RemoveChild(responsiveTarget);
}
responsiveTarget = value;
if (responsiveTarget)
{
responsiveTarget->SetAlignmentToParent(Margin(0, 0, 0, 0));
while (responsiveTarget->LevelUp());
AddChild(responsiveTarget);
responsiveTarget->Layout_UpdateMinSize();
minSizeUpperBound = responsiveTarget->GetCachedMinSize();
minSizeLowerBound = responsiveTarget->GetCachedMinSize();
testX = (vint)responsiveTarget->GetDirection() & (vint)ResponsiveDirection::Horizontal;
testY = (vint)responsiveTarget->GetDirection() & (vint)ResponsiveDirection::Vertical;
Layout_AdjustLevelDown(cachedBounds.GetSize());
}
else
{
minSizeUpperBound = {};
minSizeLowerBound = {};
testX = false;
testY = false;
}
}
}
}
}
}
/***********************************************************************
.\GRAPHICSCOMPOSITION\GUIGRAPHICSSHAREDSIZECOMPOSITION.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
using namespace reflection::description;
using namespace collections;
using namespace controls;
using namespace elements;
/***********************************************************************
GuiSharedSizeItemComposition
***********************************************************************/
void GuiSharedSizeItemComposition::OnParentLineChanged()
{
GuiBoundsComposition::OnParentLineChanged();
if (parentRoot)
{
parentRoot->childItems.Remove(this);
parentRoot = nullptr;
}
auto current = GetParent();
while (current)
{
if (auto item = dynamic_cast<GuiSharedSizeItemComposition*>(current))
{
break;
}
else if (auto root = dynamic_cast<GuiSharedSizeRootComposition*>(current))
{
parentRoot = root;
break;
}
current = current->GetParent();
}
if (parentRoot)
{
parentRoot->childItems.Add(this);
}
}
Size GuiSharedSizeItemComposition::Layout_CalculateMinSize()
{
if (parentRoot)
{
return cachedMinSize;
}
else
{
return GuiBoundsComposition::Layout_CalculateMinSize();
}
}
Size GuiSharedSizeItemComposition::Layout_CalculateOriginalMinSize()
{
return GuiBoundsComposition::Layout_CalculateMinSize();
}
GuiSharedSizeItemComposition::GuiSharedSizeItemComposition()
{
SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
}
const WString& GuiSharedSizeItemComposition::GetGroup()
{
return group;
}
void GuiSharedSizeItemComposition::SetGroup(const WString& value)
{
if (group != value)
{
group = value;
InvokeOnCompositionStateChanged();
}
}
bool GuiSharedSizeItemComposition::GetSharedWidth()
{
return sharedWidth;
}
void GuiSharedSizeItemComposition::SetSharedWidth(bool value)
{
if (sharedWidth != value)
{
sharedWidth = value;
InvokeOnCompositionStateChanged();
}
}
bool GuiSharedSizeItemComposition::GetSharedHeight()
{
return sharedHeight;
}
void GuiSharedSizeItemComposition::SetSharedHeight(bool value)
{
if (sharedHeight != value)
{
sharedHeight = value;
InvokeOnCompositionStateChanged();
}
}
/***********************************************************************
GuiSharedSizeRootComposition
***********************************************************************/
void GuiSharedSizeRootComposition::AddSizeComponent(collections::Dictionary<WString, vint>& sizes, const WString& group, vint sizeComponent)
{
vint index = sizes.Keys().IndexOf(group);
if (index == -1)
{
sizes.Add(group, sizeComponent);
}
else if (sizes.Values().Get(index) < sizeComponent)
{
sizes.Set(group, sizeComponent);
}
}
void GuiSharedSizeRootComposition::CalculateOriginalMinSizes()
{
for (auto item : childItems)
{
item->originalMinSize = item->Layout_CalculateOriginalMinSize();
}
}
void GuiSharedSizeRootComposition::CollectSizes(collections::Dictionary<WString, vint>& widths, collections::Dictionary<WString, vint>& heights)
{
for (auto item : childItems)
{
auto group = item->GetGroup();
if (item->GetSharedWidth())
{
AddSizeComponent(widths, group, item->originalMinSize.x);
}
if (item->GetSharedHeight())
{
AddSizeComponent(heights, group, item->originalMinSize.y);
}
}
}
void GuiSharedSizeRootComposition::AlignSizes(collections::Dictionary<WString, vint>& widths, collections::Dictionary<WString, vint>& heights)
{
for (auto item : childItems)
{
auto group = item->GetGroup();
auto size = item->originalMinSize;
if (item->GetSharedWidth())
{
size.x = widths[group];
}
if (item->GetSharedHeight())
{
size.y = heights[group];
}
item->Layout_SetCachedMinSize(size);
}
}
Size GuiSharedSizeRootComposition::Layout_CalculateMinSize()
{
itemWidths.Clear();
itemHeights.Clear();
CalculateOriginalMinSizes();
CollectSizes(itemWidths, itemHeights);
AlignSizes(itemWidths, itemHeights);
return GuiBoundsComposition::Layout_CalculateMinSize();
}
}
}
}
/***********************************************************************
.\GRAPHICSCOMPOSITION\GUIGRAPHICSSPECIALIZEDCOMPOSITION.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
/***********************************************************************
GuiSideAlignedComposition
***********************************************************************/
Rect GuiSideAlignedComposition::Layout_CalculateBounds(Size parentSize)
{
Rect result;
if (auto parent = GetParent())
{
Rect bounds({}, parentSize);
vint w = (vint)(bounds.Width() * maxRatio);
vint h = (vint)(bounds.Height() * maxRatio);
if (w > maxLength) w = maxLength;
if (h > maxLength) h = maxLength;
switch (direction)
{
case Left:
{
bounds.x2 = bounds.x1 + w;
}
break;
case Top:
{
bounds.y2 = bounds.y1 + h;
}
break;
case Right:
{
bounds.x1 = bounds.x2 - w;
}
break;
case Bottom:
{
bounds.y1 = bounds.y2 - h;
}
break;
}
result = bounds;
}
return result;
}
GuiSideAlignedComposition::Direction GuiSideAlignedComposition::GetDirection()
{
return direction;
}
void GuiSideAlignedComposition::SetDirection(Direction value)
{
if (direction != value)
{
direction = value;
InvokeOnCompositionStateChanged();
}
}
vint GuiSideAlignedComposition::GetMaxLength()
{
return maxLength;
}
void GuiSideAlignedComposition::SetMaxLength(vint value)
{
if (value < 0) value = 0;
if (maxLength != value)
{
maxLength = value;
InvokeOnCompositionStateChanged();
}
}
double GuiSideAlignedComposition::GetMaxRatio()
{
return maxRatio;
}
void GuiSideAlignedComposition::SetMaxRatio(double value)
{
if (value < 0) value = 0; else if (value > 1) value = 1;
if (maxRatio != value)
{
maxRatio = value;
InvokeOnCompositionStateChanged();
}
}
/***********************************************************************
GuiPartialViewComposition
***********************************************************************/
Rect GuiPartialViewComposition::Layout_CalculateBounds(Size parentSize)
{
Rect result;
if (auto parent = GetParent())
{
Rect bounds({}, parentSize);
vint w = bounds.Width();
vint h = bounds.Height();
vint pw = (vint)(wPageSize * w);
vint ph = (vint)(hPageSize * h);
vint ow = preferredMinSize.x - pw;
if (ow < 0) ow = 0;
vint oh = preferredMinSize.y - ph;
if (oh < 0) oh = 0;
w -= ow;
h -= oh;
pw += ow;
ph += oh;
result = Rect(Point((vint)(wRatio * w), (vint)(hRatio * h)), Size(pw, ph));
}
return result;
}
double GuiPartialViewComposition::GetWidthRatio()
{
return wRatio;
}
double GuiPartialViewComposition::GetWidthPageSize()
{
return wPageSize;
}
double GuiPartialViewComposition::GetHeightRatio()
{
return hRatio;
}
double GuiPartialViewComposition::GetHeightPageSize()
{
return hPageSize;
}
void GuiPartialViewComposition::SetWidthRatio(double value)
{
if (wRatio != value)
{
wRatio = value;
InvokeOnCompositionStateChanged();
}
}
void GuiPartialViewComposition::SetWidthPageSize(double value)
{
if (wPageSize != value)
{
wPageSize = value;
InvokeOnCompositionStateChanged();
}
}
void GuiPartialViewComposition::SetHeightRatio(double value)
{
if (hRatio != value)
{
hRatio = value;
InvokeOnCompositionStateChanged();
}
}
void GuiPartialViewComposition::SetHeightPageSize(double value)
{
if (hPageSize != value)
{
hPageSize = value;
InvokeOnCompositionStateChanged();
}
}
}
}
}
/***********************************************************************
.\GRAPHICSCOMPOSITION\GUIGRAPHICSSTACKCOMPOSITION.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
/***********************************************************************
GuiStackComposition
***********************************************************************/
void GuiStackComposition::Layout_UpdateStackItemMinSizes()
{
for (auto item : layout_stackItems)
{
item->Layout_SetCachedMinSize(item->Layout_CalculateMinSizeHelper());
}
if (!layout_invalid) return;
layout_invalid = false;
Point virtualOffset;
layout_stackItemTotalSize = Size(0, 0);
for (auto [item, index] : indexed(layout_stackItems))
{
Size itemSize = item->GetCachedMinSize();
switch (direction)
{
case GuiStackComposition::Horizontal:
case GuiStackComposition::ReversedHorizontal:
{
if (layout_stackItemTotalSize.y < itemSize.y)
{
layout_stackItemTotalSize.y = itemSize.y;
}
if (index > 0)
{
layout_stackItemTotalSize.x += padding;
}
layout_stackItemTotalSize.x += itemSize.x;
}
break;
case GuiStackComposition::Vertical:
case GuiStackComposition::ReversedVertical:
{
if (layout_stackItemTotalSize.x < itemSize.x)
{
layout_stackItemTotalSize.x = itemSize.x;
}
if (index > 0)
{
layout_stackItemTotalSize.y += padding;
}
layout_stackItemTotalSize.y += itemSize.y;
}
break;
}
item->layout_virtualOffset = virtualOffset;
virtualOffset.x += itemSize.x + padding;
virtualOffset.y += itemSize.y + padding;
}
}
void GuiStackComposition::Layout_UpdateStackItemBounds(Rect contentBounds)
{
if (layout_ensuringVisibleStackItem)
{
Rect itemBounds(
layout_ensuringVisibleStackItem->layout_virtualOffset,
layout_ensuringVisibleStackItem->GetCachedMinSize()
);
switch (direction)
{
case Horizontal:
case ReversedHorizontal:
if (itemBounds.x1 <= 0)
{
layout_adjustment = -itemBounds.x1;
}
else
{
vint overflow = itemBounds.x2 - contentBounds.x2;
if (overflow > 0)
{
layout_adjustment = -overflow;
}
}
break;
case Vertical:
case ReversedVertical:
if (itemBounds.y1 <= 0)
{
layout_adjustment = -itemBounds.y1;
}
else
{
vint overflow = itemBounds.y2 - contentBounds.y2;
if (overflow > 0)
{
layout_adjustment = -overflow;
}
}
break;
}
}
for (auto item : layout_stackItems)
{
item->Layout_SetStackItemBounds(contentBounds, item->layout_virtualOffset);
}
}
void GuiStackComposition::OnChildInserted(GuiGraphicsComposition* child)
{
GuiBoundsComposition::OnChildInserted(child);
GuiStackItemComposition* item = dynamic_cast<GuiStackItemComposition*>(child);
if (item)
{
if (!layout_stackItems.Contains(item))
{
layout_stackItems.Add(item);
}
}
}
void GuiStackComposition::OnChildRemoved(GuiGraphicsComposition* child)
{
GuiBoundsComposition::OnChildRemoved(child);
GuiStackItemComposition* item = dynamic_cast<GuiStackItemComposition*>(child);
if (item)
{
layout_stackItems.Remove(item);
if (item == layout_ensuringVisibleStackItem)
{
layout_ensuringVisibleStackItem = nullptr;
}
}
}
void GuiStackComposition::OnCompositionStateChanged()
{
GuiBoundsComposition::OnCompositionStateChanged();
layout_invalid = true;
}
Size GuiStackComposition::Layout_CalculateMinSize()
{
Layout_UpdateStackItemMinSizes();
Size minStackSize;
if (GetMinSizeLimitation() == GuiGraphicsComposition::LimitToElementAndChildren)
{
if (!layout_ensuringVisibleStackItem || direction == Vertical || direction == ReversedVertical)
{
minStackSize.x = layout_stackItemTotalSize.x;
}
if (!layout_ensuringVisibleStackItem || direction == Horizontal || direction == ReversedHorizontal)
{
minStackSize.y = layout_stackItemTotalSize.y;
}
}
minStackSize.x += extraMargin.left;
minStackSize.x += extraMargin.right;
minStackSize.y += extraMargin.top;
minStackSize.y += extraMargin.bottom;
Size minClientSize = GuiBoundsComposition::Layout_CalculateMinSize();
return Size(
minStackSize.x > minClientSize.x ? minStackSize.x : minClientSize.x,
minStackSize.y > minClientSize.y ? minStackSize.y : minClientSize.y
);
return minStackSize;
}
Rect GuiStackComposition::Layout_CalculateBounds(Size parentSize)
{
Rect bounds = GuiBoundsComposition::Layout_CalculateBounds(parentSize);
Rect contentBounds(
extraMargin.left,
extraMargin.top,
bounds.Width() - extraMargin.right,
bounds.Height() - extraMargin.bottom
);
Layout_UpdateStackItemBounds(contentBounds);
return bounds;
}
const GuiStackComposition::ItemCompositionList& GuiStackComposition::GetStackItems()
{
return layout_stackItems;
}
bool GuiStackComposition::InsertStackItem(vint index, GuiStackItemComposition* item)
{
index = layout_stackItems.Insert(index, item);
if (AddChild(item))
{
return true;
}
layout_stackItems.RemoveAt(index);
return false;
}
GuiStackComposition::Direction GuiStackComposition::GetDirection()
{
return direction;
}
void GuiStackComposition::SetDirection(Direction value)
{
if (direction != value)
{
direction = value;
InvokeOnCompositionStateChanged();
}
}
vint GuiStackComposition::GetPadding()
{
return padding;
}
void GuiStackComposition::SetPadding(vint value)
{
if (padding != value)
{
padding = value;
InvokeOnCompositionStateChanged();
}
}
Margin GuiStackComposition::GetExtraMargin()
{
return extraMargin;
}
void GuiStackComposition::SetExtraMargin(Margin value)
{
if (value.left < 0) value.left = 0;
if (value.top < 0) value.top = 0;
if (value.right < 0) value.right = 0;
if (value.bottom < 0) value.bottom = 0;
if (extraMargin != value)
{
extraMargin = value;
InvokeOnCompositionStateChanged();
}
}
bool GuiStackComposition::IsStackItemClipped()
{
Rect clientArea = GetCachedClientArea();
switch(direction)
{
case Horizontal:
case ReversedHorizontal:
{
vint width = layout_stackItemTotalSize.x + extraMargin.left + extraMargin.right;
return width > clientArea.Width();
}
break;
case Vertical:
case ReversedVertical:
{
vint height = layout_stackItemTotalSize.y + extraMargin.top + extraMargin.bottom;
return height > clientArea.Height();
}
break;
}
return false;
}
bool GuiStackComposition::EnsureVisible(vint index)
{
if (0 <= index && index < layout_stackItems.Count())
{
layout_ensuringVisibleStackItem = layout_stackItems[index];
}
else
{
layout_ensuringVisibleStackItem = nullptr;
}
InvokeOnCompositionStateChanged();
return layout_ensuringVisibleStackItem != nullptr;
}
/***********************************************************************
GuiStackItemComposition
***********************************************************************/
void GuiStackItemComposition::Layout_SetStackItemBounds(Rect contentBounds, Point virtualOffset)
{
vint x = 0;
vint y = 0;
switch (layout_stackParent->direction)
{
case GuiStackComposition::Horizontal:
x = contentBounds.x1 + virtualOffset.x;
y = contentBounds.y1;
break;
case GuiStackComposition::ReversedHorizontal:
x = contentBounds.x2 - virtualOffset.x - cachedMinSize.x;
y = contentBounds.y1;
break;
case GuiStackComposition::Vertical:
x = contentBounds.x1;
y = contentBounds.y1 + virtualOffset.y;
break;
case GuiStackComposition::ReversedVertical:
x = contentBounds.x1;
y = contentBounds.y2 - virtualOffset.y - cachedMinSize.y;
break;
}
switch (layout_stackParent->direction)
{
case GuiStackComposition::Horizontal:
x += layout_stackParent->layout_adjustment;
break;
case GuiStackComposition::ReversedHorizontal:
x -= layout_stackParent->layout_adjustment;
break;
case GuiStackComposition::Vertical:
y += layout_stackParent->layout_adjustment;
break;
case GuiStackComposition::ReversedVertical:
y -= layout_stackParent->layout_adjustment;
break;
}
vint w = 0;
vint h = 0;
switch (layout_stackParent->direction)
{
case GuiStackComposition::Horizontal:
case GuiStackComposition::ReversedHorizontal:
w = cachedMinSize.x;
h = contentBounds.Height();
break;
case GuiStackComposition::Vertical:
case GuiStackComposition::ReversedVertical:
w = contentBounds.Width();
h = cachedMinSize.y;
break;
}
Rect result(
x - extraMargin.left,
y - extraMargin.top,
x + w + extraMargin.right,
y + h + extraMargin.bottom
);
Layout_SetCachedBounds(result);
}
void GuiStackItemComposition::OnParentLineChanged()
{
layout_stackParent = dynamic_cast<GuiStackComposition*>(GetParent());
GuiGraphicsComposition::OnParentLineChanged();
}
GuiStackItemComposition::GuiStackItemComposition()
{
SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
CachedMinSizeChanged.AttachLambda([this](GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
if (layout_stackParent) layout_stackParent->layout_invalid = true;
});
}
Margin GuiStackItemComposition::GetExtraMargin()
{
return extraMargin;
}
void GuiStackItemComposition::SetExtraMargin(Margin value)
{
if (extraMargin != value)
{
extraMargin = value;
InvokeOnCompositionStateChanged();
}
}
}
}
}
/***********************************************************************
.\GRAPHICSCOMPOSITION\GUIGRAPHICSTABLECOMPOSITION.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace compositions
{
using namespace collections;
using namespace controls;
using namespace elements;
/***********************************************************************
GuiTableComposition
***********************************************************************/
namespace update_cell_bounds_helpers
{
vint First(vint a, vint b)
{
return a;
}
vint Second(vint a, vint b)
{
return b;
}
vint X(Size s)
{
return s.x;
}
vint Y(Size s)
{
return s.y;
}
vint RL(GuiCellComposition* cell)
{
return cell->GetRow();
}
vint CL(GuiCellComposition* cell)
{
return cell->GetColumn();
}
vint RS(GuiCellComposition* cell)
{
return cell->GetRowSpan();
}
vint CS(GuiCellComposition* cell)
{
return cell->GetColumnSpan();
}
}
using namespace update_cell_bounds_helpers;
Rect GuiTableComposition::Layout_CalculateCellArea(Rect tableBounds)
{
Rect bounds(Point(0, 0), tableBounds.GetSize());
vint borderThickness = borderVisible ? cellPadding : 0;
bounds.x1 += borderThickness;
bounds.y1 += borderThickness;
bounds.x2 -= borderThickness;
bounds.y2 -= borderThickness;
if (bounds.x2 < bounds.x1) bounds.x2 = bounds.x1;
if (bounds.y2 < bounds.y1) bounds.y2 = bounds.y1;
return bounds;
}
void GuiTableComposition::Layout_UpdateCellBoundsInternal(
collections::Array<vint>& dimSizes,
vint& dimSize,
vint& dimSizeWithPercentage,
collections::Array<GuiCellOption>& dimOptions,
vint GuiTableComposition::* dim1,
vint GuiTableComposition::* dim2,
vint(*getSize)(Size),
vint(*getLocation)(GuiCellComposition*),
vint(*getSpan)(GuiCellComposition*),
vint(*getRow)(vint, vint),
vint(*getCol)(vint, vint)
)
{
for (vint i = 0; i < this->*dim1; i++)
{
dimSizes[i] = 0;
}
for (vint i = 0; i < this->*dim1; i++)
{
GuiCellOption option = dimOptions[i];
switch (option.composeType)
{
case GuiCellOption::Absolute:
{
dimSizes[i] = option.absolute;
}
break;
case GuiCellOption::MinSize:
{
for (vint j = 0; j < this->*dim2; j++)
{
if (auto cell = GetSitedCell(getRow(i, j), getCol(i, j)))
{
if (getSpan(cell) == 1)
{
vint size = getSize(cell->GetCachedMinSize());
vint span = getSpan(cell);
for (vint k = 1; k < span; k++)
{
size -= dimSizes[i - k] + cellPadding;
}
if (dimSizes[i] < size)
{
dimSizes[i] = size;
}
}
}
}
}
break;
default:;
}
}
{
for (vint i = 0; i < this->*dim1; i++)
{
GuiCellOption option = dimOptions[i];
if (option.composeType == GuiCellOption::Percentage)
{
for (vint j = 0; j < this->*dim2; j++)
{
GuiCellComposition* cell = GetSitedCell(getRow(i, j), getCol(i, j));
if (cell)
{
vint size = getSize(cell->GetCachedMinSize());
vint start = getLocation(cell);
vint span = getSpan(cell);
size -= (span - 1)*cellPadding;
double totalPercentage = 0;
for (vint k = start; k < start + span; k++)
{
if (dimOptions[k].composeType == GuiCellOption::Percentage)
{
totalPercentage += dimOptions[k].percentage;
}
else
{
size -= dimSizes[k];
}
}
size = (vint)ceil(size*option.percentage / totalPercentage);
if (dimSizes[i] < size)
{
dimSizes[i] = size;
}
}
}
}
}
double totalPercentage = 0;
for (vint i = 0; i < this->*dim1; i++)
{
GuiCellOption option = dimOptions[i];
if (option.composeType == GuiCellOption::Percentage)
{
totalPercentage += option.percentage;
}
}
vint percentageTotalSize = 0;
for (vint i = 0; i < this->*dim1; i++)
{
GuiCellOption option = dimOptions[i];
if (option.composeType == GuiCellOption::Percentage)
{
vint size = (vint)ceil(dimSizes[i] * totalPercentage / option.percentage);
if (percentageTotalSize < size)
{
percentageTotalSize = size;
}
}
}
for (vint i = 0; i < this->*dim1; i++)
{
GuiCellOption option = dimOptions[i];
if (option.composeType == GuiCellOption::Percentage)
{
vint size = (vint)ceil(percentageTotalSize * option.percentage / totalPercentage);
if (dimSizes[i] < size)
{
dimSizes[i] = size;
}
}
}
}
for (vint i = 0; i < this->*dim1; i++)
{
if (dimOptions[i].composeType != GuiCellOption::Percentage)
{
dimSize += dimSizes[i];
}
dimSizeWithPercentage += dimSizes[i];
}
}
void GuiTableComposition::Layout_UpdateCellBoundsPercentages(
collections::Array<vint>& dimSizes,
vint dimSize,
vint maxDimSize,
collections::Array<GuiCellOption>& dimOptions
)
{
if (maxDimSize > dimSize)
{
double totalPercentage = 0;
vint percentageCount = 0;
// TODO: (enumerable) foreach
for (vint i = 0; i < dimOptions.Count(); i++)
{
GuiCellOption option = dimOptions[i];
if (option.composeType == GuiCellOption::Percentage)
{
totalPercentage += option.percentage;
percentageCount++;
}
}
if (percentageCount > 0 && totalPercentage > 0)
{
// TODO: (enumerable) foreach
for (vint i = 0; i < dimOptions.Count(); i++)
{
GuiCellOption option = dimOptions[i];
if (option.composeType == GuiCellOption::Percentage)
{
dimSizes[i] = (vint)((maxDimSize - dimSize)*option.percentage / totalPercentage);
}
}
}
}
}
vint GuiTableComposition::GetSiteIndex(vint _rows, vint _columns, vint _row, vint _column)
{
return _row * _columns + _column;
}
void GuiTableComposition::SetSitedCell(vint _row, vint _column, GuiCellComposition* cell)
{
layout_cellCompositions[GetSiteIndex(rows, columns, _row, _column)] = cell;
layout_invalid = true;
}
void GuiTableComposition::OnCompositionStateChanged()
{
GuiBoundsComposition::OnCompositionStateChanged();
ConfigChanged.Execute(GuiEventArgs(this));
layout_invalid = true;
}
Size GuiTableComposition::Layout_CalculateMinSize()
{
for (auto child : Children())
{
if (auto cell = dynamic_cast<GuiCellComposition*>(child))
{
cell->Layout_SetCachedMinSize(cell->Layout_CalculateMinSizeHelper());
}
}
if (layout_invalid)
{
layout_invalid = false;
layout_invalidCellBounds = true;
layout_rowOffsets.Resize(rows);
layout_rowSizes.Resize(rows);
layout_columnOffsets.Resize(columns);
layout_columnSizes.Resize(columns);
layout_rowTotal = (rows - 1) * cellPadding;
layout_columnTotal = (columns - 1) * cellPadding;
layout_rowTotalWithPercentage = layout_rowTotal;
layout_columnTotalWithPercentage = layout_columnTotal;
Layout_UpdateCellBoundsInternal(
layout_rowSizes,
layout_rowTotal,
layout_rowTotalWithPercentage,
rowOptions,
&GuiTableComposition::rows,
&GuiTableComposition::columns,
&Y,
&RL,
&RS,
&First,
&Second
);
Layout_UpdateCellBoundsInternal(
layout_columnSizes,
layout_columnTotal,
layout_columnTotalWithPercentage,
columnOptions,
&GuiTableComposition::columns,
&GuiTableComposition::rows,
&X,
&CL,
&CS,
&Second,
&First
);
}
Size minTableSize;
if (GetMinSizeLimitation() == GuiGraphicsComposition::LimitToElementAndChildren)
{
vint offset = (borderVisible ? 2 * cellPadding : 0);
minTableSize.x = layout_columnTotalWithPercentage + offset;
minTableSize.y = layout_rowTotalWithPercentage + offset;
}
Size minClientSize = GuiBoundsComposition::Layout_CalculateMinSize();
return Size(
minTableSize.x > minClientSize.x ? minTableSize.x : minClientSize.x,
minTableSize.y > minClientSize.y ? minTableSize.y : minClientSize.y
);
}
Rect GuiTableComposition::Layout_CalculateBounds(Size parentSize)
{
Rect bounds = GuiBoundsComposition::Layout_CalculateBounds(parentSize);
if (layout_lastTableSize != bounds.GetSize())
{
layout_invalidCellBounds = true;
layout_lastTableSize = bounds.GetSize();
}
if (layout_invalidCellBounds)
{
layout_invalidCellBounds = false;
Size area = Layout_CalculateCellArea(bounds).GetSize();
Layout_UpdateCellBoundsPercentages(
layout_rowSizes,
layout_rowTotal,
area.y,
rowOptions
);
Layout_UpdateCellBoundsPercentages(
layout_columnSizes,
layout_columnTotal,
area.x,
columnOptions
);
layout_rowExtending = Layout_UpdateCellBoundsOffsets(layout_rowOffsets, layout_rowSizes, area.y);
layout_columnExtending = Layout_UpdateCellBoundsOffsets(layout_columnOffsets, layout_columnSizes, area.x);
for (vint i = 0; i < rows; i++)
{
for (vint j = 0; j < columns; j++)
{
vint index = GetSiteIndex(rows, columns, i, j);
layout_cellBounds[index] = Rect(Point(layout_columnOffsets[j], layout_rowOffsets[i]), Size(layout_columnSizes[j], layout_rowSizes[i]));
}
}
for (auto child : Children())
{
if (auto cell = dynamic_cast<GuiCellComposition*>(child))
{
cell->Layout_SetCellBounds();
}
}
}
return bounds;
}
vint GuiTableComposition::Layout_UpdateCellBoundsOffsets(
collections::Array<vint>& offsets,
collections::Array<vint>& sizes,
vint max
)
{
offsets[0] = 0;
for (vint i = 1; i < offsets.Count(); i++)
{
offsets[i] = offsets[i - 1] + cellPadding + sizes[i - 1];
}
vint last = offsets.Count() - 1;
vint right = offsets[last] + sizes[last];
return max > right ? max - right : 0;
}
GuiTableComposition::GuiTableComposition()
{
ConfigChanged.SetAssociatedComposition(this);
SetRowsAndColumns(1, 1);
}
vint GuiTableComposition::GetRows()
{
return rows;
}
vint GuiTableComposition::GetColumns()
{
return columns;
}
bool GuiTableComposition::SetRowsAndColumns(vint _rows, vint _columns)
{
if (_rows <= 0 || _columns <= 0) return false;
rowOptions.Resize(_rows);
columnOptions.Resize(_columns);
layout_cellCompositions.Resize(_rows*_columns);
layout_cellBounds.Resize(_rows*_columns);
for (vint i = 0; i < _rows*_columns; i++)
{
layout_cellCompositions[i] = nullptr;
layout_cellBounds[i] = Rect();
}
rows = _rows;
columns = _columns;
// TODO: (enumerable) foreach
vint childCount = Children().Count();
for (vint i = 0; i < childCount; i++)
{
GuiCellComposition* cell = dynamic_cast<GuiCellComposition*>(Children().Get(i));
if (cell)
{
cell->OnTableRowsAndColumnsChanged();
}
}
InvokeOnCompositionStateChanged();
return true;
}
GuiCellComposition* GuiTableComposition::GetSitedCell(vint _row, vint _column)
{
return layout_cellCompositions[GetSiteIndex(rows, columns, _row, _column)];
}
GuiCellOption GuiTableComposition::GetRowOption(vint _row)
{
return rowOptions[_row];
}
void GuiTableComposition::SetRowOption(vint _row, GuiCellOption option)
{
if (option.composeType == GuiCellOption::Percentage && option.percentage < 0.001)
{
option.percentage = 0;
}
if (rowOptions[_row] != option)
{
rowOptions[_row] = option;
InvokeOnCompositionStateChanged();
}
}
GuiCellOption GuiTableComposition::GetColumnOption(vint _column)
{
return columnOptions[_column];
}
void GuiTableComposition::SetColumnOption(vint _column, GuiCellOption option)
{
if (option.composeType == GuiCellOption::Percentage && option.percentage < 0.001)
{
option.percentage = 0;
}
if (columnOptions[_column] != option)
{
columnOptions[_column] = option;
InvokeOnCompositionStateChanged();
}
}
vint GuiTableComposition::GetCellPadding()
{
return cellPadding;
}
void GuiTableComposition::SetCellPadding(vint value)
{
if (value < 0) value = 0;
if (cellPadding != value)
{
cellPadding = value;
InvokeOnCompositionStateChanged();
}
}
bool GuiTableComposition::GetBorderVisible()
{
return borderVisible;
}
void GuiTableComposition::SetBorderVisible(bool value)
{
if (borderVisible != value)
{
borderVisible = value;
InvokeOnCompositionStateChanged();
}
}
/***********************************************************************
GuiCellComposition
***********************************************************************/
void GuiCellComposition::ClearSitedCells(GuiTableComposition* table)
{
if (row != -1 && column != -1)
{
for (vint r = 0; r < rowSpan; r++)
{
for (vint c = 0; c < columnSpan; c++)
{
table->SetSitedCell(row + r, column + c, nullptr);
}
}
}
}
void GuiCellComposition::SetSitedCells(GuiTableComposition* table)
{
for (vint r = 0; r < rowSpan; r++)
{
for (vint c = 0; c < columnSpan; c++)
{
table->SetSitedCell(row + r, column + c, this);
}
}
}
void GuiCellComposition::ResetSiteInternal()
{
row = -1;
column = -1;
rowSpan = 1;
columnSpan = 1;
}
bool GuiCellComposition::SetSiteInternal(vint _row, vint _column, vint _rowSpan, vint _columnSpan)
{
if (layout_tableParent)
{
if (_row < 0 || _row >= layout_tableParent->rows || _column < 0 || _column >= layout_tableParent->columns) return false;
if (_rowSpan<1 || _row + _rowSpan>layout_tableParent->rows || _columnSpan<1 || _column + _columnSpan>layout_tableParent->columns) return false;
for (vint r = 0; r < _rowSpan; r++)
{
for (vint c = 0; c < _columnSpan; c++)
{
GuiCellComposition* cell = layout_tableParent->GetSitedCell(_row + r, _column + c);
if (cell && cell != this)
{
return false;
}
}
}
ClearSitedCells(layout_tableParent);
}
row = _row;
column = _column;
rowSpan = _rowSpan;
columnSpan = _columnSpan;
if (layout_tableParent)
{
SetSitedCells(layout_tableParent);
}
return true;
}
void GuiCellComposition::OnParentChanged(GuiGraphicsComposition* oldParent, GuiGraphicsComposition* newParent)
{
GuiGraphicsComposition::OnParentChanged(oldParent, newParent);
if (layout_tableParent)
{
ClearSitedCells(layout_tableParent);
}
layout_tableParent = dynamic_cast<GuiTableComposition*>(newParent);
if (!layout_tableParent || !SetSiteInternal(row, column, rowSpan, columnSpan))
{
ResetSiteInternal();
}
if (layout_tableParent)
{
if (row != -1 && column != -1)
{
SetSiteInternal(row, column, rowSpan, columnSpan);
}
}
}
void GuiCellComposition::OnTableRowsAndColumnsChanged()
{
if(!SetSiteInternal(row, column, rowSpan, columnSpan))
{
ResetSiteInternal();
}
}
void GuiCellComposition::Layout_SetCellBounds()
{
Rect result;
if (layout_tableParent && row != -1 && column != -1)
{
Rect bounds1, bounds2;
{
vint index = layout_tableParent->GetSiteIndex(layout_tableParent->rows, layout_tableParent->columns, row, column);
bounds1 = layout_tableParent->layout_cellBounds[index];
}
{
vint index = layout_tableParent->GetSiteIndex(layout_tableParent->rows, layout_tableParent->columns, row + rowSpan - 1, column + columnSpan - 1);
bounds2 = layout_tableParent->layout_cellBounds[index];
if (row + rowSpan == layout_tableParent->rows)
{
bounds2.y2 += layout_tableParent->layout_rowExtending;
}
if (column + columnSpan == layout_tableParent->columns)
{
bounds2.x2 += layout_tableParent->layout_columnExtending;
}
}
vint offset = layout_tableParent->borderVisible ? layout_tableParent->cellPadding : 0;
result = Rect(bounds1.x1 + offset, bounds1.y1 + offset, bounds2.x2 + offset, bounds2.y2 + offset);
}
else
{
result = Rect();
}
Layout_SetCachedBounds(result);
}
GuiCellComposition::GuiCellComposition()
{
SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
CachedMinSizeChanged.AttachLambda([this](GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
if (layout_tableParent) layout_tableParent->layout_invalid = true;
});
}
GuiTableComposition* GuiCellComposition::GetTableParent()
{
return layout_tableParent;
}
vint GuiCellComposition::GetRow()
{
return row;
}
vint GuiCellComposition::GetRowSpan()
{
return rowSpan;
}
vint GuiCellComposition::GetColumn()
{
return column;
}
vint GuiCellComposition::GetColumnSpan()
{
return columnSpan;
}
bool GuiCellComposition::SetSite(vint _row, vint _column, vint _rowSpan, vint _columnSpan)
{
if (!SetSiteInternal(_row, _column, _rowSpan, _columnSpan))
{
return false;
}
InvokeOnCompositionStateChanged();
return true;
}
/***********************************************************************
GuiTableSplitterCompositionBase
***********************************************************************/
void GuiTableSplitterCompositionBase::OnParentChanged(GuiGraphicsComposition* oldParent, GuiGraphicsComposition* newParent)
{
GuiGraphicsComposition::OnParentChanged(oldParent, newParent);
tableParent = dynamic_cast<GuiTableComposition*>(newParent);
}
void GuiTableSplitterCompositionBase::OnLeftButtonDown(GuiGraphicsComposition* sender, GuiMouseEventArgs& arguments)
{
dragging = true;
draggingPoint = Point(arguments.x, arguments.y);
}
void GuiTableSplitterCompositionBase::OnLeftButtonUp(GuiGraphicsComposition* sender, GuiMouseEventArgs& arguments)
{
dragging = false;
}
void GuiTableSplitterCompositionBase::OnMouseMoveHelper(
vint cellsBefore,
vint GuiTableComposition::* cells,
collections::Array<vint>& cellSizes,
vint offset,
GuiCellOption(GuiTableComposition::*getOption)(vint),
void(GuiTableComposition::*setOption)(vint, GuiCellOption)
)
{
if (dragging)
{
if (tableParent)
{
if (0 < cellsBefore && cellsBefore < tableParent->*cells)
{
auto o1 = (tableParent->*getOption)(cellsBefore - 1);
auto o2 = (tableParent->*getOption)(cellsBefore);
vint indexStart = -1;
vint indexEnd = -1;
vint indexStep = -1;
vint max = 0;
if (offset < 0)
{
indexStart = cellsBefore - 1;
indexEnd = -1;
indexStep = -1;
}
else if (offset > 0)
{
indexStart = cellsBefore;
indexEnd = tableParent->*cells;
indexStep = 1;
}
else
{
return;
}
{
auto o = (tableParent->*getOption)(indexStart);
if (o.composeType == GuiCellOption::Absolute)
{
max = o.absolute - 1;
}
else
{
for (vint i = indexStart; i != indexEnd; i += indexStep)
{
o = (tableParent->*getOption)(i);
if (o.composeType == GuiCellOption::Absolute)
{
break;
}
else if (o.composeType == GuiCellOption::Percentage)
{
max += cellSizes[i] - 1;
}
}
}
if (max <= 0)
{
return;
}
}
if (offset < 0)
{
if (max < -offset)
{
offset = -max;
}
}
else
{
if (max < offset)
{
offset = max;
}
}
if (o1.composeType == GuiCellOption::Absolute)
{
o1.absolute += offset;
(tableParent->*setOption)(cellsBefore - 1, o1);
}
if (o2.composeType == GuiCellOption::Absolute)
{
o2.absolute -= offset;
(tableParent->*setOption)(cellsBefore, o2);
}
tableParent->ForceCalculateSizeImmediately();
}
}
}
}
Rect GuiTableSplitterCompositionBase::GetBoundsHelper(
vint cellsBefore,
vint GuiTableComposition::* cells,
vint(Rect::* dimSize)()const,
collections::Array<vint>& cellOffsets,
vint Rect::* dimU1,
vint Rect::* dimU2,
vint Rect::* dimV1,
vint Rect::* dimV2
)
{
Rect result;
if (tableParent)
{
if (0 < cellsBefore && cellsBefore < tableParent->*cells)
{
vint offset = tableParent->borderVisible ? tableParent->cellPadding : 0;
result.*dimU1 = offset;
result.*dimU2 = offset + (tableParent->Layout_CalculateCellArea(tableParent->GetCachedBounds()).*dimSize)();
result.*dimV1 = offset + cellOffsets[cellsBefore] - tableParent->cellPadding;
result.*dimV2 = (result.*dimV1) + tableParent->cellPadding;
}
}
return result;
}
GuiTableSplitterCompositionBase::GuiTableSplitterCompositionBase()
{
GetEventReceiver()->leftButtonDown.AttachMethod(this, &GuiTableSplitterCompositionBase::OnLeftButtonDown);
GetEventReceiver()->leftButtonUp.AttachMethod(this, &GuiTableSplitterCompositionBase::OnLeftButtonUp);
}
GuiTableComposition* GuiTableSplitterCompositionBase::GetTableParent()
{
return tableParent;
}
/***********************************************************************
GuiRowSplitterComposition
***********************************************************************/
void GuiRowSplitterComposition::OnMouseMove(GuiGraphicsComposition* sender, GuiMouseEventArgs& arguments)
{
OnMouseMoveHelper(
rowsToTheTop,
&GuiTableComposition::rows,
tableParent->layout_rowSizes,
arguments.y - draggingPoint.y,
&GuiTableComposition::GetRowOption,
&GuiTableComposition::SetRowOption
);
}
Rect GuiRowSplitterComposition::Layout_CalculateBounds(Size parentSize)
{
return GetBoundsHelper(
rowsToTheTop,
&GuiTableComposition::rows,
&Rect::Width,
tableParent->layout_rowOffsets,
&Rect::x1,
&Rect::x2,
&Rect::y1,
&Rect::y2
);
}
GuiRowSplitterComposition::GuiRowSplitterComposition()
{
if (auto controller = GetCurrentController())
{
SetAssociatedCursor(controller->ResourceService()->GetSystemCursor(INativeCursor::SizeNS));
}
GetEventReceiver()->mouseMove.AttachMethod(this, &GuiRowSplitterComposition::OnMouseMove);
}
vint GuiRowSplitterComposition::GetRowsToTheTop()
{
return rowsToTheTop;
}
void GuiRowSplitterComposition::SetRowsToTheTop(vint value)
{
if (rowsToTheTop != value)
{
rowsToTheTop = value;
InvokeOnCompositionStateChanged();
}
}
/***********************************************************************
GuiColumnSplitterComposition
***********************************************************************/
void GuiColumnSplitterComposition::OnMouseMove(GuiGraphicsComposition* sender, GuiMouseEventArgs& arguments)
{
OnMouseMoveHelper(
columnsToTheLeft,
&GuiTableComposition::columns,
tableParent->layout_columnSizes,
arguments.x - draggingPoint.x,
&GuiTableComposition::GetColumnOption,
&GuiTableComposition::SetColumnOption
);
}
Rect GuiColumnSplitterComposition::Layout_CalculateBounds(Size parentSize)
{
return GetBoundsHelper(
columnsToTheLeft,
&GuiTableComposition::columns,
&Rect::Height,
tableParent->layout_columnOffsets,
&Rect::y1,
&Rect::y2,
&Rect::x1,
&Rect::x2
);
}
GuiColumnSplitterComposition::GuiColumnSplitterComposition()
{
if (auto controller = GetCurrentController())
{
SetAssociatedCursor(controller->ResourceService()->GetSystemCursor(INativeCursor::SizeWE));
}
GetEventReceiver()->mouseMove.AttachMethod(this, &GuiColumnSplitterComposition::OnMouseMove);
}
vint GuiColumnSplitterComposition::GetColumnsToTheLeft()
{
return columnsToTheLeft;
}
void GuiColumnSplitterComposition::SetColumnsToTheLeft(vint value)
{
if (columnsToTheLeft != value)
{
columnsToTheLeft = value;
InvokeOnCompositionStateChanged();
}
}
}
}
}
/***********************************************************************
.\GRAPHICSELEMENT\GUIGRAPHICSDOCUMENTELEMENT.CPP
***********************************************************************/
namespace vl
{
using namespace collections;
namespace presentation
{
namespace elements
{
/***********************************************************************
SetPropertiesVisitor
***********************************************************************/
namespace visitors
{
class SetPropertiesVisitor : public Object, public DocumentRun::IVisitor
{
typedef GuiDocumentElement::GuiDocumentElementRenderer Renderer;
typedef DocumentModel::ResolvedStyle ResolvedStyle;
public:
vint start;
vint length;
vint selectionBegin;
vint selectionEnd;
List<ResolvedStyle> styles;
DocumentModel* model;
Renderer* renderer;
Ptr<Renderer::ParagraphCache> cache;
IGuiGraphicsParagraph* paragraph;
SetPropertiesVisitor(DocumentModel* _model, Renderer* _renderer, Ptr<Renderer::ParagraphCache> _cache, vint _selectionBegin, vint _selectionEnd)
:start(0)
,length(0)
,model(_model)
,renderer(_renderer)
,cache(_cache)
,paragraph(_cache->graphicsParagraph.Obj())
,selectionBegin(_selectionBegin)
,selectionEnd(_selectionEnd)
{
ResolvedStyle style;
style=model->GetStyle(DocumentModel::DefaultStyleName, style);
styles.Add(style);
}
void VisitContainer(DocumentContainerRun* run)
{
for (auto subRun : run->runs)
{
subRun->Accept(this);
}
}
void ApplyStyle(vint start, vint length, const ResolvedStyle& style)
{
paragraph->SetFont(start, length, style.style.fontFamily);
paragraph->SetSize(start, length, style.style.size);
paragraph->SetStyle(start, length,
(IGuiGraphicsParagraph::TextStyle)
( (style.style.bold?IGuiGraphicsParagraph::Bold:0)
| (style.style.italic?IGuiGraphicsParagraph::Italic:0)
| (style.style.underline?IGuiGraphicsParagraph::Underline:0)
| (style.style.strikeline?IGuiGraphicsParagraph::Strikeline:0)
));
}
void ApplyColor(vint start, vint length, const ResolvedStyle& style)
{
paragraph->SetColor(start, length, style.color);
paragraph->SetBackgroundColor(start, length, style.backgroundColor);
}
void Visit(DocumentTextRun* run)override
{
length=run->GetRepresentationText().Length();
if(length>0)
{
ResolvedStyle style=styles[styles.Count()-1];
ApplyStyle(start, length, style);
ApplyColor(start, length, style);
vint styleStart=start;
vint styleEnd=styleStart+length;
if(styleStart<selectionEnd && selectionBegin<styleEnd)
{
vint s2=styleStart>selectionBegin?styleStart:selectionBegin;
vint s3=selectionEnd<styleEnd?selectionEnd:styleEnd;
if(s2<s3)
{
ResolvedStyle selectionStyle=model->GetStyle(DocumentModel::SelectionStyleName, style);
ApplyColor(s2, s3-s2, selectionStyle);
}
}
}
start+=length;
}
void Visit(DocumentStylePropertiesRun* run)override
{
ResolvedStyle style=styles[styles.Count()-1];
style=model->GetStyle(run->style, style);
styles.Add(style);
VisitContainer(run);
styles.RemoveAt(styles.Count()-1);
}
void Visit(DocumentStyleApplicationRun* run)override
{
ResolvedStyle style=styles[styles.Count()-1];
style=model->GetStyle(run->styleName, style);
styles.Add(style);
VisitContainer(run);
styles.RemoveAt(styles.Count()-1);
}
void Visit(DocumentHyperlinkRun* run)override
{
ResolvedStyle style=styles[styles.Count()-1];
style=model->GetStyle(run->styleName, style);
styles.Add(style);
VisitContainer(run);
styles.RemoveAt(styles.Count()-1);
}
void Visit(DocumentImageRun* run)override
{
length=run->GetRepresentationText().Length();
auto element=Ptr(GuiImageFrameElement::Create());
element->SetImage(run->image, run->frameIndex);
element->SetStretch(true);
IGuiGraphicsParagraph::InlineObjectProperties properties;
properties.size=run->size;
properties.baseline=run->baseline;
properties.breakCondition=IGuiGraphicsParagraph::Alone;
properties.backgroundImage = element;
paragraph->SetInlineObject(start, length, properties);
if(start<selectionEnd && selectionBegin<start+length)
{
ResolvedStyle style=styles[styles.Count()-1];
ResolvedStyle selectionStyle=model->GetStyle(DocumentModel::SelectionStyleName, style);
ApplyColor(start, length, selectionStyle);
}
start+=length;
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
length=run->GetRepresentationText().Length();
IGuiGraphicsParagraph::InlineObjectProperties properties;
properties.breakCondition=IGuiGraphicsParagraph::Alone;
if (run->name != L"")
{
vint index = renderer->nameCallbackIdMap.Keys().IndexOf(run->name);
if (index != -1)
{
auto id = renderer->nameCallbackIdMap.Values()[index];
index = cache->embeddedObjects.Keys().IndexOf(id);
if (index != -1)
{
auto eo = cache->embeddedObjects.Values()[index];
if (eo->start == start)
{
properties.size = eo->size;
properties.callbackId = id;
}
}
}
else
{
auto eo = Ptr(new Renderer::EmbeddedObject);
eo->name = run->name;
eo->size = Size(0, 0);
eo->start = start;
vint id = -1;
vint count = renderer->freeCallbackIds.Count();
if (count > 0)
{
id = renderer->freeCallbackIds[count - 1];
renderer->freeCallbackIds.RemoveAt(count - 1);
}
else
{
id = renderer->usedCallbackIds++;
}
renderer->nameCallbackIdMap.Add(eo->name, id);
cache->embeddedObjects.Add(id, eo);
properties.callbackId = id;
}
}
paragraph->SetInlineObject(start, length, properties);
if(start<selectionEnd && selectionBegin<start+length)
{
ResolvedStyle style=styles[styles.Count()-1];
ResolvedStyle selectionStyle=model->GetStyle(DocumentModel::SelectionStyleName, style);
ApplyColor(start, length, selectionStyle);
}
start+=length;
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
static vint SetProperty(DocumentModel* model, Renderer* renderer, Ptr<Renderer::ParagraphCache> cache, Ptr<DocumentParagraphRun> run, vint selectionBegin, vint selectionEnd)
{
SetPropertiesVisitor visitor(model, renderer, cache, selectionBegin, selectionEnd);
run->Accept(&visitor);
return visitor.length;
}
};
}
using namespace visitors;
/***********************************************************************
GuiDocumentElement::GuiDocumentElementRenderer
***********************************************************************/
Size GuiDocumentElement::GuiDocumentElementRenderer::OnRenderInlineObject(vint callbackId, Rect location)
{
if (element->callback)
{
auto cache = paragraphCaches[renderingParagraph];
auto relativeLocation = Rect(Point(location.x1 + renderingParagraphOffset.x, location.y1 + renderingParagraphOffset.y), location.GetSize());
auto eo = cache->embeddedObjects[callbackId];
auto size = element->callback->OnRenderEmbeddedObject(eo->name, relativeLocation);
eo->resized = eo->size != size;
eo->size = size;
return eo->size;
}
else
{
return Size();
}
}
void GuiDocumentElement::GuiDocumentElementRenderer::InitializeInternal()
{
}
void GuiDocumentElement::GuiDocumentElementRenderer::FinalizeInternal()
{
}
void GuiDocumentElement::GuiDocumentElementRenderer::RenderTargetChangedInternal(IGuiGraphicsRenderTarget* oldRenderTarget, IGuiGraphicsRenderTarget* newRenderTarget)
{
// TODO: (enumerable) foreach
for(vint i=0;i<paragraphCaches.Count();i++)
{
ParagraphCache* cache=paragraphCaches[i].Obj();
if(cache)
{
cache->graphicsParagraph=0;
}
}
}
Ptr<GuiDocumentElement::GuiDocumentElementRenderer::ParagraphCache> GuiDocumentElement::GuiDocumentElementRenderer::EnsureAndGetCache(vint paragraphIndex, bool createParagraph)
{
if(paragraphIndex<0 || paragraphIndex>=paragraphCaches.Count()) return 0;
Ptr<DocumentParagraphRun> paragraph=element->document->paragraphs[paragraphIndex];
Ptr<ParagraphCache> cache=paragraphCaches[paragraphIndex];
if(!cache)
{
cache=Ptr(new ParagraphCache);
cache->fullText=paragraph->GetText(false);
paragraphCaches[paragraphIndex]=cache;
}
if(createParagraph)
{
if(!cache->graphicsParagraph)
{
cache->graphicsParagraph=layoutProvider->CreateParagraph(cache->fullText, renderTarget, this);
cache->graphicsParagraph->SetParagraphAlignment(paragraph->alignment ? paragraph->alignment.Value() : Alignment::Left);
SetPropertiesVisitor::SetProperty(element->document.Obj(), this, cache, paragraph, cache->selectionBegin, cache->selectionEnd);
}
if(cache->graphicsParagraph->GetMaxWidth()!=lastMaxWidth)
{
cache->graphicsParagraph->SetMaxWidth(lastMaxWidth);
}
vint paragraphHeight=paragraphHeights[paragraphIndex];
vint height=cache->graphicsParagraph->GetHeight();
if(paragraphHeight!=height)
{
cachedTotalHeight+=height-paragraphHeight;
paragraphHeight=height;
paragraphHeights[paragraphIndex]=paragraphHeight;
minSize=Size(0, cachedTotalHeight);
}
}
return cache;
}
bool GuiDocumentElement::GuiDocumentElementRenderer::GetParagraphIndexFromPoint(Point point, vint& top, vint& index)
{
vint y=0;
// TODO: (enumerable) foreach
for(vint i=0;i<paragraphHeights.Count();i++)
{
vint paragraphHeight=paragraphHeights[i];
vint nextY=y+paragraphHeight+paragraphDistance;
top=y;
index=i;
if(nextY<=point.y)
{
y=nextY;
continue;
}
else
{
break;
}
}
return true;
}
GuiDocumentElement::GuiDocumentElementRenderer::GuiDocumentElementRenderer()
:paragraphDistance(0)
,lastMaxWidth(-1)
,cachedTotalHeight(0)
,layoutProvider(GetGuiGraphicsResourceManager()->GetLayoutProvider())
,lastCaret(-1, -1)
,lastCaretFrontSide(false)
{
}
void GuiDocumentElement::GuiDocumentElementRenderer::Render(Rect bounds)
{
if (element->callback)
{
element->callback->OnStartRender();
}
renderTarget->PushClipper(bounds, element);
if(!renderTarget->IsClipperCoverWholeTarget())
{
vint maxWidth=bounds.Width();
Rect clipper=renderTarget->GetClipper();
vint cx=bounds.Left();
vint cy=bounds.Top();
vint y1=clipper.Top()-bounds.Top();
vint y2=y1+clipper.Height();
vint y=0;
lastMaxWidth=maxWidth;
// TODO: (enumerable) foreach
for(vint i=0;i<paragraphHeights.Count();i++)
{
vint paragraphHeight=paragraphHeights[i];
if(y+paragraphHeight<=y1)
{
y+=paragraphHeight+paragraphDistance;
continue;
}
else if(y>=y2)
{
break;
}
else
{
Ptr<DocumentParagraphRun> paragraph=element->document->paragraphs[i];
Ptr<ParagraphCache> cache=paragraphCaches[i];
bool created=cache && cache->graphicsParagraph;
cache=EnsureAndGetCache(i, true);
if(!created && i==lastCaret.row && element->caretVisible)
{
cache->graphicsParagraph->OpenCaret(lastCaret.column, lastCaretColor, lastCaretFrontSide);
}
paragraphHeight=cache->graphicsParagraph->GetHeight();
renderingParagraph = i;
renderingParagraphOffset = Point(cx - bounds.x1, cy + y - bounds.y1);
cache->graphicsParagraph->Render(Rect(Point(cx, cy+y), Size(maxWidth, paragraphHeight)));
renderingParagraph = -1;
bool resized = false;
// TODO: (enumerable) foreach
for (vint j = 0; j < cache->embeddedObjects.Count(); j++)
{
auto eo = cache->embeddedObjects.Values()[j];
if (eo->resized)
{
eo->resized = false;
resized = true;
}
}
if (resized)
{
cache->graphicsParagraph = 0;
}
}
y+=paragraphHeight+paragraphDistance;
}
}
renderTarget->PopClipper(element);
if (element->callback)
{
element->callback->OnFinishRender();
}
}
void GuiDocumentElement::GuiDocumentElementRenderer::OnElementStateChanged()
{
if (element->document && element->document->paragraphs.Count() > 0)
{
vint defaultSize = GetCurrentController()->ResourceService()->GetDefaultFont().size;
paragraphDistance = defaultSize;
vint defaultHeight = defaultSize;
paragraphCaches.Resize(element->document->paragraphs.Count());
paragraphHeights.Resize(element->document->paragraphs.Count());
for (vint i = 0; i < paragraphCaches.Count(); i++)
{
paragraphCaches[i] = 0;
}
for (vint i = 0; i < paragraphHeights.Count(); i++)
{
paragraphHeights[i] = defaultHeight;
}
cachedTotalHeight = paragraphHeights.Count() * (defaultHeight + paragraphDistance);
if (paragraphHeights.Count()>0)
{
cachedTotalHeight -= paragraphDistance;
}
minSize = Size(0, cachedTotalHeight);
}
else
{
paragraphCaches.Resize(0);
paragraphHeights.Resize(0);
cachedTotalHeight = 0;
minSize = Size(0, 0);
}
nameCallbackIdMap.Clear();
freeCallbackIds.Clear();
usedCallbackIds = 0;
}
void GuiDocumentElement::GuiDocumentElementRenderer::NotifyParagraphUpdated(vint index, vint oldCount, vint newCount, bool updatedText)
{
if (0 <= index && index < paragraphCaches.Count() && 0 <= oldCount && index + oldCount <= paragraphCaches.Count() && 0 <= newCount)
{
vint paragraphCount = element->document->paragraphs.Count();
CHECK_ERROR(updatedText || oldCount == newCount, L"GuiDocumentlement::GuiDocumentElementRenderer::NotifyParagraphUpdated(vint, vint, vint, bool)#Illegal values of oldCount and newCount.");
CHECK_ERROR(paragraphCount - paragraphCaches.Count() == newCount - oldCount, L"GuiDocumentElement::GuiDocumentElementRenderer::NotifyParagraphUpdated(vint, vint, vint, bool)#Illegal values of oldCount and newCount.");
ParagraphCacheArray oldCaches;
CopyFrom(oldCaches, paragraphCaches);
paragraphCaches.Resize(paragraphCount);
ParagraphHeightArray oldHeights;
CopyFrom(oldHeights, paragraphHeights);
paragraphHeights.Resize(paragraphCount);
vint defaultHeight = GetCurrentController()->ResourceService()->GetDefaultFont().size;
cachedTotalHeight = 0;
for (vint i = 0; i < paragraphCount; i++)
{
if (i < index)
{
paragraphCaches[i] = oldCaches[i];
paragraphHeights[i] = oldHeights[i];
}
else if (i < index + newCount)
{
paragraphCaches[i] = 0;
paragraphHeights[i] = defaultHeight;
if (!updatedText && i < index + oldCount)
{
auto cache = oldCaches[i];
if(cache)
{
cache->graphicsParagraph = 0;
}
paragraphCaches[i] = cache;
paragraphHeights[i] = oldHeights[i];
}
}
else
{
paragraphCaches[i] = oldCaches[i - (newCount - oldCount)];
paragraphHeights[i] = oldHeights[i - (newCount - oldCount)];
}
cachedTotalHeight += paragraphHeights[i] + paragraphDistance;
}
if (paragraphCount > 0)
{
cachedTotalHeight -= paragraphDistance;
}
if (updatedText)
{
vint count = oldCount < newCount ? oldCount : newCount;
for (vint i = 0; i < count; i++)
{
if (auto cache = oldCaches[index + i])
{
// TODO: (enumerable) foreach on dictionary
for (vint j = 0; j < cache->embeddedObjects.Count(); j++)
{
auto id = cache->embeddedObjects.Keys()[j];
auto name = cache->embeddedObjects.Values()[j]->name;
nameCallbackIdMap.Remove(name);
freeCallbackIds.Add(id);
}
}
}
}
}
}
Ptr<DocumentHyperlinkRun::Package> GuiDocumentElement::GuiDocumentElementRenderer::GetHyperlinkFromPoint(Point point)
{
if (!renderTarget) return nullptr;
vint top=0;
vint index=-1;
if(GetParagraphIndexFromPoint(point, top, index))
{
Ptr<ParagraphCache> cache=EnsureAndGetCache(index, true);
Point paragraphPoint(point.x, point.y-top);
vint start=-1;
vint length=0;
if(cache->graphicsParagraph->GetInlineObjectFromPoint(paragraphPoint, start, length))
{
return element->document->GetHyperlink(index, start, start+length);
}
vint caret=cache->graphicsParagraph->GetCaretFromPoint(paragraphPoint);
return element->document->GetHyperlink(index, caret, caret);
}
return nullptr;
}
void GuiDocumentElement::GuiDocumentElementRenderer::OpenCaret(TextPos caret, Color color, bool frontSide)
{
CloseCaret(caret);
lastCaret=caret;
lastCaretColor=color;
lastCaretFrontSide=frontSide;
Ptr<ParagraphCache> cache=paragraphCaches[lastCaret.row];
if(cache && cache->graphicsParagraph)
{
cache->graphicsParagraph->OpenCaret(lastCaret.column, lastCaretColor, lastCaretFrontSide);
}
}
void GuiDocumentElement::GuiDocumentElementRenderer::CloseCaret(TextPos caret)
{
if(lastCaret!=TextPos(-1, -1))
{
if(0<=lastCaret.row && lastCaret.row<paragraphCaches.Count())
{
Ptr<ParagraphCache> cache=paragraphCaches[lastCaret.row];
if(cache && cache->graphicsParagraph)
{
cache->graphicsParagraph->CloseCaret();
}
}
}
lastCaret=caret;
}
void GuiDocumentElement::GuiDocumentElementRenderer::SetSelection(TextPos begin, TextPos end)
{
if(begin>end)
{
TextPos t=begin;
begin=end;
end=t;
}
if(begin==end)
{
begin=TextPos(-1, -1);
end=TextPos(-1, -1);
}
if (!renderTarget) return;
// TODO: (enumerable) foreach:indexed
for(vint i=0;i<paragraphCaches.Count();i++)
{
if(begin.row<=i && i<=end.row)
{
Ptr<ParagraphCache> cache=EnsureAndGetCache(i, false);
vint newBegin=i==begin.row?begin.column:0;
vint newEnd=i==end.row?end.column:cache->fullText.Length();
if(cache->selectionBegin!=newBegin || cache->selectionEnd!=newEnd)
{
cache->selectionBegin=newBegin;
cache->selectionEnd=newEnd;
NotifyParagraphUpdated(i, 1, 1, false);
}
}
else
{
Ptr<ParagraphCache> cache=paragraphCaches[i];
if(cache)
{
if(cache->selectionBegin!=-1 || cache->selectionEnd!=-1)
{
cache->selectionBegin=-1;
cache->selectionEnd=-1;
NotifyParagraphUpdated(i, 1, 1, false);
}
}
}
}
}
TextPos GuiDocumentElement::GuiDocumentElementRenderer::CalculateCaret(TextPos comparingCaret, IGuiGraphicsParagraph::CaretRelativePosition position, bool& preferFrontSide)
{
if (!renderTarget) return comparingCaret;
Ptr<ParagraphCache> cache=EnsureAndGetCache(comparingCaret.row, true);
if(cache)
{
switch(position)
{
case IGuiGraphicsParagraph::CaretFirst:
{
preferFrontSide=false;
vint caret=cache->graphicsParagraph->GetCaret(0, IGuiGraphicsParagraph::CaretFirst, preferFrontSide);
return TextPos(comparingCaret.row, caret);
}
case IGuiGraphicsParagraph::CaretLast:
{
preferFrontSide=true;
vint caret=cache->graphicsParagraph->GetCaret(0, IGuiGraphicsParagraph::CaretLast, preferFrontSide);
return TextPos(comparingCaret.row, caret);
}
case IGuiGraphicsParagraph::CaretLineFirst:
{
preferFrontSide=false;
vint caret=cache->graphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretLineFirst, preferFrontSide);
return TextPos(comparingCaret.row, caret);
}
case IGuiGraphicsParagraph::CaretLineLast:
{
preferFrontSide=true;
vint caret=cache->graphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretLineLast, preferFrontSide);
return TextPos(comparingCaret.row, caret);
}
case IGuiGraphicsParagraph::CaretMoveUp:
{
vint caret=cache->graphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretMoveUp, preferFrontSide);
if(caret==comparingCaret.column && comparingCaret.row>0)
{
Rect caretBounds=cache->graphicsParagraph->GetCaretBounds(comparingCaret.column, preferFrontSide);
Ptr<ParagraphCache> anotherCache=EnsureAndGetCache(comparingCaret.row-1, true);
vint height=anotherCache->graphicsParagraph->GetHeight();
caret=anotherCache->graphicsParagraph->GetCaretFromPoint(Point(caretBounds.x1, height));
return TextPos(comparingCaret.row-1, caret);
}
else
{
return TextPos(comparingCaret.row, caret);
}
}
case IGuiGraphicsParagraph::CaretMoveDown:
{
vint caret=cache->graphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretMoveDown, preferFrontSide);
if(caret==comparingCaret.column && comparingCaret.row<paragraphCaches.Count()-1)
{
Rect caretBounds=cache->graphicsParagraph->GetCaretBounds(comparingCaret.column, preferFrontSide);
Ptr<ParagraphCache> anotherCache=EnsureAndGetCache(comparingCaret.row+1, true);
caret=anotherCache->graphicsParagraph->GetCaretFromPoint(Point(caretBounds.x1, 0));
return TextPos(comparingCaret.row+1, caret);
}
else
{
return TextPos(comparingCaret.row, caret);
}
}
case IGuiGraphicsParagraph::CaretMoveLeft:
{
preferFrontSide=false;
vint caret=cache->graphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretMoveLeft, preferFrontSide);
if(caret==comparingCaret.column && comparingCaret.row>0)
{
Ptr<ParagraphCache> anotherCache=EnsureAndGetCache(comparingCaret.row-1, true);
caret=anotherCache->graphicsParagraph->GetCaret(0, IGuiGraphicsParagraph::CaretLast, preferFrontSide);
return TextPos(comparingCaret.row-1, caret);
}
else
{
return TextPos(comparingCaret.row, caret);
}
}
case IGuiGraphicsParagraph::CaretMoveRight:
{
preferFrontSide=true;
vint caret=cache->graphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretMoveRight, preferFrontSide);
if(caret==comparingCaret.column && comparingCaret.row<paragraphCaches.Count()-1)
{
Ptr<ParagraphCache> anotherCache=EnsureAndGetCache(comparingCaret.row+1, true);
caret=anotherCache->graphicsParagraph->GetCaret(0, IGuiGraphicsParagraph::CaretFirst, preferFrontSide);
return TextPos(comparingCaret.row+1, caret);
}
else
{
return TextPos(comparingCaret.row, caret);
}
}
}
}
return comparingCaret;
}
TextPos GuiDocumentElement::GuiDocumentElementRenderer::CalculateCaretFromPoint(Point point)
{
if (!renderTarget) return TextPos(-1, -1);
vint top=0;
vint index=-1;
if(GetParagraphIndexFromPoint(point, top, index))
{
Ptr<ParagraphCache> cache=EnsureAndGetCache(index, true);
Point paragraphPoint(point.x, point.y-top);
vint caret=cache->graphicsParagraph->GetCaretFromPoint(paragraphPoint);
return TextPos(index, caret);
}
return TextPos(-1, -1);
}
Rect GuiDocumentElement::GuiDocumentElementRenderer::GetCaretBounds(TextPos caret, bool frontSide)
{
if (!renderTarget) return Rect();
Ptr<ParagraphCache> cache=EnsureAndGetCache(caret.row, true);
if(cache)
{
Rect bounds=cache->graphicsParagraph->GetCaretBounds(caret.column, frontSide);
if(bounds!=Rect())
{
vint y=0;
for(vint i=0;i<caret.row;i++)
{
EnsureAndGetCache(i, true);
y+=paragraphHeights[i]+paragraphDistance;
}
bounds.y1+=y;
bounds.y2+=y;
return bounds;
}
}
return Rect();
}
/***********************************************************************
GuiDocumentElement
***********************************************************************/
void GuiDocumentElement::UpdateCaret()
{
auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>();
if (elementRenderer)
{
elementRenderer->SetSelection(caretBegin, caretEnd);
if (caretVisible)
{
elementRenderer->OpenCaret(caretEnd, caretColor, caretFrontSide);
}
else
{
elementRenderer->CloseCaret(caretEnd);
}
InvokeOnCompositionStateChanged();
}
}
GuiDocumentElement::GuiDocumentElement()
:caretVisible(false)
,caretFrontSide(false)
{
}
GuiDocumentElement::ICallback* GuiDocumentElement::GetCallback()
{
return callback;
}
void GuiDocumentElement::SetCallback(ICallback* value)
{
callback = value;
}
Ptr<DocumentModel> GuiDocumentElement::GetDocument()
{
return document;
}
void GuiDocumentElement::SetDocument(Ptr<DocumentModel> value)
{
document=value;
InvokeOnElementStateChanged();
SetCaret(TextPos(), TextPos(), false);
}
TextPos GuiDocumentElement::GetCaretBegin()
{
return caretBegin;
}
TextPos GuiDocumentElement::GetCaretEnd()
{
return caretEnd;
}
bool GuiDocumentElement::IsCaretEndPreferFrontSide()
{
return caretFrontSide;
}
void GuiDocumentElement::SetCaret(TextPos begin, TextPos end, bool frontSide)
{
caretBegin=begin;
caretEnd=end;
if(caretBegin<caretEnd)
{
caretFrontSide=true;
}
else if(caretBegin>caretEnd)
{
caretFrontSide=false;
}
else
{
caretFrontSide=frontSide;
}
UpdateCaret();
}
bool GuiDocumentElement::GetCaretVisible()
{
return caretVisible;
}
void GuiDocumentElement::SetCaretVisible(bool value)
{
caretVisible=value;
UpdateCaret();
}
Color GuiDocumentElement::GetCaretColor()
{
return caretColor;
}
void GuiDocumentElement::SetCaretColor(Color value)
{
caretColor=value;
UpdateCaret();
}
TextPos GuiDocumentElement::CalculateCaret(TextPos comparingCaret, IGuiGraphicsParagraph::CaretRelativePosition position, bool& preferFrontSide)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
TextPos caret=elementRenderer->CalculateCaret(comparingCaret, position, preferFrontSide);
return caret.column==-1?comparingCaret:caret;
}
else
{
return comparingCaret;
}
}
TextPos GuiDocumentElement::CalculateCaretFromPoint(Point point)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
return elementRenderer->CalculateCaretFromPoint(point);
}
else
{
return TextPos(0, 0);
}
}
Rect GuiDocumentElement::GetCaretBounds(TextPos caret, bool frontSide)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
return elementRenderer->GetCaretBounds(caret, frontSide);
}
else
{
return Rect();
}
}
void GuiDocumentElement::NotifyParagraphUpdated(vint index, vint oldCount, vint newCount, bool updatedText)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
elementRenderer->NotifyParagraphUpdated(index, oldCount, newCount, updatedText);
InvokeOnCompositionStateChanged();
}
}
void GuiDocumentElement::EditRun(TextPos begin, TextPos end, Ptr<DocumentModel> model, bool copy)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
if (begin > end)
{
TextPos temp = begin;
begin = end;
end = temp;
}
vint newRows = document->EditRun(begin, end, model, copy);
if (newRows != -1)
{
elementRenderer->NotifyParagraphUpdated(begin.row, end.row - begin.row + 1, newRows, true);
}
InvokeOnCompositionStateChanged();
}
}
void GuiDocumentElement::EditText(TextPos begin, TextPos end, bool frontSide, const collections::Array<WString>& text)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
if (begin > end)
{
TextPos temp = begin;
begin = end;
end = temp;
}
vint newRows = document->EditText(begin, end, frontSide, text);
if (newRows != -1)
{
elementRenderer->NotifyParagraphUpdated(begin.row, end.row - begin.row + 1, newRows, true);
}
InvokeOnCompositionStateChanged();
}
}
void GuiDocumentElement::EditStyle(TextPos begin, TextPos end, Ptr<DocumentStyleProperties> style)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
if (begin > end)
{
TextPos temp = begin;
begin = end;
end = temp;
}
if (document->EditStyle(begin, end, style))
{
elementRenderer->NotifyParagraphUpdated(begin.row, end.row - begin.row + 1, end.row - begin.row + 1, false);
}
InvokeOnCompositionStateChanged();
}
}
void GuiDocumentElement::EditImage(TextPos begin, TextPos end, Ptr<GuiImageData> image)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
if (begin > end)
{
TextPos temp = begin;
begin = end;
end = temp;
}
if (document->EditImage(begin, end, image))
{
elementRenderer->NotifyParagraphUpdated(begin.row, end.row - begin.row + 1, 1, true);
}
InvokeOnCompositionStateChanged();
}
}
void GuiDocumentElement::EditHyperlink(vint paragraphIndex, vint begin, vint end, const WString& reference, const WString& normalStyleName, const WString& activeStyleName)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
if (begin > end)
{
vint temp = begin;
begin = end;
end = temp;
}
if (document->EditHyperlink(paragraphIndex, begin, end, reference, normalStyleName, activeStyleName))
{
elementRenderer->NotifyParagraphUpdated(paragraphIndex, 1, 1, false);
}
InvokeOnCompositionStateChanged();
}
}
void GuiDocumentElement::RemoveHyperlink(vint paragraphIndex, vint begin, vint end)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
if (begin > end)
{
vint temp = begin;
begin = end;
end = temp;
}
if (document->RemoveHyperlink(paragraphIndex, begin, end))
{
elementRenderer->NotifyParagraphUpdated(paragraphIndex, 1, 1, false);
}
InvokeOnCompositionStateChanged();
}
}
void GuiDocumentElement::EditStyleName(TextPos begin, TextPos end, const WString& styleName)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
if (begin > end)
{
TextPos temp = begin;
begin = end;
end = temp;
}
if (document->EditStyleName(begin, end, styleName))
{
elementRenderer->NotifyParagraphUpdated(begin.row, end.row - begin.row + 1, end.row - begin.row + 1, false);
}
InvokeOnCompositionStateChanged();
}
}
void GuiDocumentElement::RemoveStyleName(TextPos begin, TextPos end)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
if (begin > end)
{
TextPos temp = begin;
begin = end;
end = temp;
}
if (document->RemoveStyleName(begin, end))
{
elementRenderer->NotifyParagraphUpdated(begin.row, end.row - begin.row + 1, end.row - begin.row + 1, false);
}
InvokeOnCompositionStateChanged();
}
}
void GuiDocumentElement::RenameStyle(const WString& oldStyleName, const WString& newStyleName)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
document->RenameStyle(oldStyleName, newStyleName);
}
}
void GuiDocumentElement::ClearStyle(TextPos begin, TextPos end)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
if (begin > end)
{
TextPos temp = begin;
begin = end;
end = temp;
}
if (document->ClearStyle(begin, end))
{
elementRenderer->NotifyParagraphUpdated(begin.row, end.row - begin.row + 1, end.row - begin.row + 1, false);
}
InvokeOnCompositionStateChanged();
}
}
Ptr<DocumentStyleProperties> GuiDocumentElement::SummarizeStyle(TextPos begin, TextPos end)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
if (begin > end)
{
TextPos temp = begin;
begin = end;
end = temp;
}
return document->SummarizeStyle(begin, end);
}
return nullptr;
}
Nullable<WString> GuiDocumentElement::SummarizeStyleName(TextPos begin, TextPos end)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
if (begin > end)
{
TextPos temp = begin;
begin = end;
end = temp;
}
return document->SummarizeStyleName(begin, end);
}
return {};
}
void GuiDocumentElement::SetParagraphAlignment(TextPos begin, TextPos end, const collections::Array<Nullable<Alignment>>& alignments)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
vint first = begin.row;
vint last = end.row;
if (first > last)
{
vint temp = first;
first = last;
last = temp;
}
if (0 <= first && first < document->paragraphs.Count() && 0 <= last && last < document->paragraphs.Count() && last - first + 1 == alignments.Count())
{
for (vint i = first; i <= last; i++)
{
document->paragraphs[i]->alignment = alignments[i - first];
}
elementRenderer->NotifyParagraphUpdated(first, alignments.Count(), alignments.Count(), false);
}
InvokeOnCompositionStateChanged();
}
}
Nullable<Alignment> GuiDocumentElement::SummarizeParagraphAlignment(TextPos begin, TextPos end)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
if (begin > end)
{
TextPos temp = begin;
begin = end;
end = temp;
}
return document->SummarizeParagraphAlignment(begin, end);
}
return {};
}
Ptr<DocumentHyperlinkRun::Package> GuiDocumentElement::GetHyperlinkFromPoint(Point point)
{
if (auto elementRenderer = renderer.Cast<GuiDocumentElementRenderer>())
{
return elementRenderer->GetHyperlinkFromPoint(point);
}
return nullptr;
}
}
}
}
/***********************************************************************
.\GRAPHICSELEMENT\GUIGRAPHICSELEMENT.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace elements
{
using namespace collections;
/***********************************************************************
GuiFocusRectangleElement
***********************************************************************/
GuiFocusRectangleElement::GuiFocusRectangleElement()
{
}
/***********************************************************************
GuiSolidBorderElement
***********************************************************************/
GuiSolidBorderElement::GuiSolidBorderElement()
:color(0, 0, 0)
{
}
Color GuiSolidBorderElement::GetColor()
{
return color;
}
void GuiSolidBorderElement::SetColor(Color value)
{
if(color!=value)
{
color=value;
InvokeOnElementStateChanged();
}
}
ElementShape GuiSolidBorderElement::GetShape()
{
return shape;
}
void GuiSolidBorderElement::SetShape(ElementShape value)
{
shape=value;
}
/***********************************************************************
Gui3DBorderElement
***********************************************************************/
Gui3DBorderElement::Gui3DBorderElement()
{
}
Color Gui3DBorderElement::GetColor1()
{
return color1;
}
void Gui3DBorderElement::SetColor1(Color value)
{
SetColors(value, color2);
}
Color Gui3DBorderElement::GetColor2()
{
return color2;
}
void Gui3DBorderElement::SetColor2(Color value)
{
SetColors(color1, value);
}
void Gui3DBorderElement::SetColors(Color value1, Color value2)
{
if(color1!=value1 || color2!=value2)
{
color1=value1;
color2=value2;
InvokeOnElementStateChanged();
}
}
/***********************************************************************
Gui3DSplitterElement
***********************************************************************/
Gui3DSplitterElement::Gui3DSplitterElement()
:direction(Horizontal)
{
}
Color Gui3DSplitterElement::GetColor1()
{
return color1;
}
void Gui3DSplitterElement::SetColor1(Color value)
{
SetColors(value, color2);
}
Color Gui3DSplitterElement::GetColor2()
{
return color2;
}
void Gui3DSplitterElement::SetColor2(Color value)
{
SetColors(color1, value);
}
void Gui3DSplitterElement::SetColors(Color value1, Color value2)
{
if(color1!=value1 || color2!=value2)
{
color1=value1;
color2=value2;
InvokeOnElementStateChanged();
}
}
Gui3DSplitterElement::Direction Gui3DSplitterElement::GetDirection()
{
return direction;
}
void Gui3DSplitterElement::SetDirection(Direction value)
{
if(direction!=value)
{
direction=value;
InvokeOnElementStateChanged();
}
}
/***********************************************************************
GuiSolidBackgroundElement
***********************************************************************/
GuiSolidBackgroundElement::GuiSolidBackgroundElement()
:color(255, 255, 255)
{
}
Color GuiSolidBackgroundElement::GetColor()
{
return color;
}
void GuiSolidBackgroundElement::SetColor(Color value)
{
if(color!=value)
{
color=value;
InvokeOnElementStateChanged();
}
}
ElementShape GuiSolidBackgroundElement::GetShape()
{
return shape;
}
void GuiSolidBackgroundElement::SetShape(ElementShape value)
{
shape=value;
}
/***********************************************************************
GuiGradientBackgroundElement
***********************************************************************/
GuiGradientBackgroundElement::GuiGradientBackgroundElement()
:direction(Horizontal)
{
}
Color GuiGradientBackgroundElement::GetColor1()
{
return color1;
}
void GuiGradientBackgroundElement::SetColor1(Color value)
{
SetColors(value, color2);
}
Color GuiGradientBackgroundElement::GetColor2()
{
return color2;
}
void GuiGradientBackgroundElement::SetColor2(Color value)
{
SetColors(color1, value);
}
void GuiGradientBackgroundElement::SetColors(Color value1, Color value2)
{
if(color1!=value1 || color2!=value2)
{
color1=value1;
color2=value2;
InvokeOnElementStateChanged();
}
}
GuiGradientBackgroundElement::Direction GuiGradientBackgroundElement::GetDirection()
{
return direction;
}
void GuiGradientBackgroundElement::SetDirection(Direction value)
{
if(direction!=value)
{
direction=value;
InvokeOnElementStateChanged();
}
}
ElementShape GuiGradientBackgroundElement::GetShape()
{
return shape;
}
void GuiGradientBackgroundElement::SetShape(ElementShape value)
{
shape=value;
}
/***********************************************************************
GuiInnerShadowElement
***********************************************************************/
GuiInnerShadowElement::GuiInnerShadowElement()
{
}
Color GuiInnerShadowElement::GetColor()
{
return color;
}
void GuiInnerShadowElement::SetColor(Color value)
{
if (color != value)
{
color = value;
InvokeOnElementStateChanged();
}
}
vint GuiInnerShadowElement::GetThickness()
{
return thickness;
}
void GuiInnerShadowElement::SetThickness(vint value)
{
if (thickness != value)
{
thickness = value;
InvokeOnElementStateChanged();
}
}
/***********************************************************************
GuiSolidLabelElement
***********************************************************************/
GuiSolidLabelElement::GuiSolidLabelElement()
:color(0, 0, 0)
,hAlignment(Alignment::Left)
,vAlignment(Alignment::Top)
,wrapLine(false)
,ellipse(false)
,multiline(false)
,wrapLineHeightCalculation(false)
{
fontProperties.fontFamily=L"Lucida Console";
fontProperties.size=12;
}
Color GuiSolidLabelElement::GetColor()
{
return color;
}
void GuiSolidLabelElement::SetColor(Color value)
{
if(color!=value)
{
color=value;
InvokeOnElementStateChanged();
}
}
const FontProperties& GuiSolidLabelElement::GetFont()
{
return fontProperties;
}
void GuiSolidLabelElement::SetFont(const FontProperties& value)
{
if(fontProperties!=value)
{
fontProperties=value;
InvokeOnElementStateChanged();
}
}
const WString& GuiSolidLabelElement::GetText()
{
return text;
}
void GuiSolidLabelElement::SetText(const WString& value)
{
if(text!=value)
{
text=value;
InvokeOnElementStateChanged();
}
}
Alignment GuiSolidLabelElement::GetHorizontalAlignment()
{
return hAlignment;
}
Alignment GuiSolidLabelElement::GetVerticalAlignment()
{
return vAlignment;
}
void GuiSolidLabelElement::SetHorizontalAlignment(Alignment value)
{
SetAlignments(value, vAlignment);
}
void GuiSolidLabelElement::SetVerticalAlignment(Alignment value)
{
SetAlignments(hAlignment, value);
}
void GuiSolidLabelElement::SetAlignments(Alignment horizontal, Alignment vertical)
{
if(hAlignment!=horizontal || vAlignment!=vertical)
{
hAlignment=horizontal;
vAlignment=vertical;
InvokeOnElementStateChanged();
}
}
bool GuiSolidLabelElement::GetWrapLine()
{
return wrapLine;
}
void GuiSolidLabelElement::SetWrapLine(bool value)
{
if(wrapLine!=value)
{
wrapLine=value;
InvokeOnElementStateChanged();
}
}
bool GuiSolidLabelElement::GetEllipse()
{
return ellipse;
}
void GuiSolidLabelElement::SetEllipse(bool value)
{
if(ellipse!=value)
{
ellipse=value;
InvokeOnElementStateChanged();
}
}
bool GuiSolidLabelElement::GetMultiline()
{
return multiline;
}
void GuiSolidLabelElement::SetMultiline(bool value)
{
if(multiline!=value)
{
multiline=value;
InvokeOnElementStateChanged();
}
}
bool GuiSolidLabelElement::GetWrapLineHeightCalculation()
{
return wrapLineHeightCalculation;
}
void GuiSolidLabelElement::SetWrapLineHeightCalculation(bool value)
{
if(wrapLineHeightCalculation!=value)
{
wrapLineHeightCalculation=value;
InvokeOnElementStateChanged();
}
}
/***********************************************************************
GuiImageFrameElement
***********************************************************************/
GuiImageFrameElement::GuiImageFrameElement()
: frameIndex(0)
, hAlignment(Alignment::Left)
, vAlignment(Alignment::Top)
, stretch(false)
, enabled(true)
{
}
Ptr<INativeImage> GuiImageFrameElement::GetImage()
{
return image;
}
vint GuiImageFrameElement::GetFrameIndex()
{
return frameIndex;
}
void GuiImageFrameElement::SetImage(Ptr<INativeImage> value)
{
SetImage(value, frameIndex);
}
void GuiImageFrameElement::SetFrameIndex(vint value)
{
SetImage(image, value);
}
void GuiImageFrameElement::SetImage(Ptr<INativeImage> _image, vint _frameIndex)
{
if (image != _image || frameIndex != _frameIndex)
{
if (!_image)
{
image = nullptr;
frameIndex = 0;
}
else if (0 <= _frameIndex)
{
// do not check frame count because
// on remote protocol metadata could have not been loaded yet
image = _image;
frameIndex = _frameIndex;
}
InvokeOnElementStateChanged();
}
}
Alignment GuiImageFrameElement::GetHorizontalAlignment()
{
return hAlignment;
}
Alignment GuiImageFrameElement::GetVerticalAlignment()
{
return vAlignment;
}
void GuiImageFrameElement::SetHorizontalAlignment(Alignment value)
{
SetAlignments(value, vAlignment);
}
void GuiImageFrameElement::SetVerticalAlignment(Alignment value)
{
SetAlignments(hAlignment, value);
}
void GuiImageFrameElement::SetAlignments(Alignment horizontal, Alignment vertical)
{
if (hAlignment != horizontal || vAlignment != vertical)
{
hAlignment = horizontal;
vAlignment = vertical;
InvokeOnElementStateChanged();
}
}
bool GuiImageFrameElement::GetStretch()
{
return stretch;
}
void GuiImageFrameElement::SetStretch(bool value)
{
if (stretch != value)
{
stretch = value;
InvokeOnElementStateChanged();
}
}
bool GuiImageFrameElement::GetEnabled()
{
return enabled;
}
void GuiImageFrameElement::SetEnabled(bool value)
{
if (enabled != value)
{
enabled = value;
InvokeOnElementStateChanged();
}
}
/***********************************************************************
GuiPolygonElement
***********************************************************************/
GuiPolygonElement::GuiPolygonElement()
{
}
Size GuiPolygonElement::GetSize()
{
return size;
}
void GuiPolygonElement::SetSize(Size value)
{
if(size!=value)
{
size=value;
InvokeOnElementStateChanged();
}
}
const Point& GuiPolygonElement::GetPoint(vint index)
{
return points[index];
}
vint GuiPolygonElement::GetPointCount()
{
return points.Count();
}
void GuiPolygonElement::SetPoints(const Point* p, vint count)
{
points.Resize(count);
if(count>0)
{
memcpy(&points[0], p, sizeof(*p)*count);
}
InvokeOnElementStateChanged();
}
const GuiPolygonElement::PointArray& GuiPolygonElement::GetPointsArray()
{
return points;
}
void GuiPolygonElement::SetPointsArray(const PointArray& value)
{
CopyFrom(points, value);
InvokeOnElementStateChanged();
}
Color GuiPolygonElement::GetBorderColor()
{
return borderColor;
}
void GuiPolygonElement::SetBorderColor(Color value)
{
if(borderColor!=value)
{
borderColor=value;
InvokeOnElementStateChanged();
}
}
Color GuiPolygonElement::GetBackgroundColor()
{
return backgroundColor;
}
void GuiPolygonElement::SetBackgroundColor(Color value)
{
if(backgroundColor!=value)
{
backgroundColor=value;
InvokeOnElementStateChanged();
}
}
}
}
}
/***********************************************************************
.\GRAPHICSELEMENT\GUIGRAPHICSELEMENTINTERFACES.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace elements
{
using namespace collections;
/***********************************************************************
GuiGraphicsRenderTarget
***********************************************************************/
bool GuiGraphicsRenderTarget::IsInHostedRendering()
{
return hostedRendering;
}
void GuiGraphicsRenderTarget::StartHostedRendering()
{
CHECK_ERROR(!hostedRendering && !rendering, L"vl::presentation::elements::GuiGraphicsRenderTarget::StartHostedRendering()#Wrong timing to call this function.");
hostedRendering = true;
StartRenderingOnNativeWindow();
}
RenderTargetFailure GuiGraphicsRenderTarget::StopHostedRendering()
{
CHECK_ERROR(hostedRendering && !rendering, L"vl::presentation::elements::GuiGraphicsRenderTarget::StopHostedRendering()#Wrong timing to call this function.");
hostedRendering = false;
return StopRenderingOnNativeWindow();
}
void GuiGraphicsRenderTarget::StartRendering()
{
CHECK_ERROR(!rendering, L"vl::presentation::elements::GuiGraphicsRenderTarget::StartRendering()#Wrong timing to call this function.");
rendering = true;
if (!hostedRendering)
{
StartRenderingOnNativeWindow();
}
}
RenderTargetFailure GuiGraphicsRenderTarget::StopRendering()
{
CHECK_ERROR(rendering, L"vl::presentation::elements::GuiGraphicsRenderTarget::StopRendering()#Wrong timing to call this function.");
rendering = false;
if (!hostedRendering)
{
return StopRenderingOnNativeWindow();
}
return RenderTargetFailure::None;
}
void GuiGraphicsRenderTarget::PushClipper(Rect clipper, reflection::DescriptableObject* generator)
{
if (clipperCoverWholeTargetCounter > 0)
{
clipperCoverWholeTargetCounter++;
}
else
{
Rect currentClipper = GetClipper().Intersect(clipper);
if (currentClipper.x1 < currentClipper.x2 && currentClipper.y1 < currentClipper.y2)
{
clippers.Add(currentClipper);
AfterPushedClipper(clipper, currentClipper, generator);
}
else
{
clipperCoverWholeTargetCounter++;
AfterPushedClipperAndBecameInvalid(clipper, generator);
}
}
}
void GuiGraphicsRenderTarget::PopClipper(reflection::DescriptableObject* generator)
{
if (clipperCoverWholeTargetCounter > 0)
{
clipperCoverWholeTargetCounter--;
if (clipperCoverWholeTargetCounter == 0)
{
AfterPoppedClipperAndBecameValid(GetClipper(), clippers.Count() > 0, generator);
}
}
else if (clippers.Count() > 0)
{
clippers.RemoveAt(clippers.Count() - 1);
AfterPoppedClipper(GetClipper(), clippers.Count() > 0, generator);
}
}
Rect GuiGraphicsRenderTarget::GetClipper()
{
if (clipperCoverWholeTargetCounter > 0)
{
return { {-1,-1},{0,0} };
}
else if (clippers.Count() == 0)
{
return Rect(Point(0, 0), GetCanvasSize());
}
else
{
return clippers[clippers.Count() - 1];
}
}
bool GuiGraphicsRenderTarget::IsClipperCoverWholeTarget()
{
return clipperCoverWholeTargetCounter > 0;
}
}
}
}
/***********************************************************************
.\GRAPHICSELEMENT\GUIGRAPHICSRESOURCEMANAGER.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace elements
{
using namespace collections;
/***********************************************************************
GuiGraphicsResourceManager
***********************************************************************/
GuiGraphicsResourceManager::GuiGraphicsResourceManager()
{
}
GuiGraphicsResourceManager::~GuiGraphicsResourceManager()
{
}
vint GuiGraphicsResourceManager::RegisterElementType(const WString& elementTypeName)
{
CHECK_ERROR(!elementTypes.Contains(elementTypeName), L"GuiGraphicsResourceManager::RegisterElementType(const WString&)#This element type has already been registered.");
return elementTypes.Add(elementTypeName);
}
void GuiGraphicsResourceManager::RegisterRendererFactory(vint elementType, Ptr<IGuiGraphicsRendererFactory> factory)
{
if (rendererFactories.Count() <= elementType)
{
rendererFactories.Resize(elementType + 1);
rendererFactories[elementType] = factory;
}
else
{
CHECK_ERROR(!rendererFactories[elementType], L"GuiGraphicsResourceManager::RegisterRendererFactory(vint, Ptr<IGuiGraphicsRendererFactory>)#This element type has already been binded a renderer factory.");
rendererFactories[elementType] = factory;
}
}
IGuiGraphicsRendererFactory* GuiGraphicsResourceManager::GetRendererFactory(vint elementType)
{
return rendererFactories.Count() > elementType ? rendererFactories[elementType].Obj() : nullptr;
}
IGuiGraphicsResourceManager* guiGraphicsResourceManager = nullptr;
IGuiGraphicsResourceManager* GetGuiGraphicsResourceManager()
{
return guiGraphicsResourceManager;
}
void SetGuiGraphicsResourceManager(IGuiGraphicsResourceManager* resourceManager)
{
guiGraphicsResourceManager=resourceManager;
}
}
}
}
/***********************************************************************
.\GRAPHICSELEMENT\GUIGRAPHICSTEXTELEMENT.CPP
***********************************************************************/
namespace vl
{
using namespace collections;
namespace presentation
{
namespace elements
{
namespace text
{
/***********************************************************************
text::TextLine
***********************************************************************/
TextLine::TextLine()
:text(0)
,att(0)
,availableOffsetCount(0)
,bufferLength(0)
,dataLength(0)
,lexerFinalState(-1)
,contextFinalState(-1)
{
}
TextLine::~TextLine()
{
}
vint TextLine::CalculateBufferLength(vint dataLength)
{
if(dataLength<1)dataLength=1;
vint bufferLength=dataLength-dataLength%BlockSize;
if(bufferLength<dataLength)
{
bufferLength+=BlockSize;
}
return bufferLength;
}
void TextLine::Initialize()
{
Finalize();
text=new wchar_t[BlockSize];
att=new CharAtt[BlockSize];
bufferLength=BlockSize;
memset(text, 0, sizeof(wchar_t)*bufferLength);
memset(att, 0, sizeof(CharAtt)*bufferLength);
}
void TextLine::Finalize()
{
if(text)
{
delete[] text;
text=0;
}
if(att)
{
delete[] att;
att=0;
}
availableOffsetCount=0;
bufferLength=0;
dataLength=0;
}
bool TextLine::IsReady()
{
return text && att;
}
bool TextLine::Modify(vint start, vint count, const wchar_t* input, vint inputCount)
{
if(!text || !att || start<0 || count<0 || start+count>dataLength || inputCount<0) return false;
vint newDataLength=dataLength-count+inputCount;
vint newBufferLength=CalculateBufferLength(newDataLength);
if(newBufferLength!=bufferLength)
{
wchar_t* newText=new wchar_t[newBufferLength];
memcpy(newText, text, start*sizeof(wchar_t));
memcpy(newText+start, input, inputCount*sizeof(wchar_t));
memcpy(newText+start+inputCount, text+start+count, (dataLength-start-count)*sizeof(wchar_t));
CharAtt* newAtt=new CharAtt[newBufferLength];
memcpy(newAtt, att, start*sizeof(CharAtt));
memset(newAtt+start, 0, inputCount*sizeof(CharAtt));
memcpy(newAtt+start+inputCount, att+start+count, (dataLength-start-count)*sizeof(CharAtt));
delete[] text;
delete[] att;
text=newText;
att=newAtt;
}
else
{
memmove(text+start+inputCount, text+start+count, (dataLength-start-count)*sizeof(wchar_t));
memmove(att+start+inputCount, att+start+count, (dataLength-start-count)*sizeof(CharAtt));
memcpy(text+start, input, inputCount*sizeof(wchar_t));
memset(att+start, 0, inputCount*sizeof(CharAtt));
}
dataLength=newDataLength;
bufferLength=newBufferLength;
if(availableOffsetCount>start)
{
availableOffsetCount=start;
}
return true;
}
TextLine TextLine::Split(vint index)
{
if(index<0 || index>dataLength) return TextLine();
vint count=dataLength-index;
TextLine line;
line.Initialize();
line.Modify(0, 0, text+index, count);
memcpy(line.att, att+index, count*sizeof(CharAtt));
Modify(index, count, L"", 0);
return line;
}
void TextLine::AppendAndFinalize(TextLine& line)
{
vint oldDataLength=dataLength;
Modify(oldDataLength, 0, line.text, line.dataLength);
memcpy(att+oldDataLength, line.att, line.dataLength*sizeof(CharAtt));
line.Finalize();
}
/***********************************************************************
text::CharMeasurer
***********************************************************************/
CharMeasurer::CharMeasurer(vint _rowHeight)
:rowHeight(_rowHeight)
{
memset(widths, 0, sizeof(widths));
}
CharMeasurer::~CharMeasurer()
{
}
void CharMeasurer::SetRenderTarget(IGuiGraphicsRenderTarget* value)
{
if(oldRenderTarget!=value)
{
oldRenderTarget=value;
rowHeight=GetRowHeightInternal(oldRenderTarget);
memset(widths, 0, sizeof(widths));
}
}
vint CharMeasurer::MeasureWidth(UnicodeCodePoint codePoint)
{
vuint32_t index = codePoint.GetCodePoint();
if (0 <= index && index < 65536)
{
vint w = widths[index];
if (w == 0)
{
widths[index] = w = MeasureWidthInternal(codePoint, oldRenderTarget);
}
return w;
}
else if (index < 0x110000)
{
return MeasureWidthInternal(codePoint, oldRenderTarget);
}
else
{
return 0;
}
}
vint CharMeasurer::GetRowHeight()
{
return rowHeight;
}
/***********************************************************************
text::TextLines
***********************************************************************/
TextLines::TextLines(GuiColorizedTextElement* _ownerElement)
:ownerElement(_ownerElement)
,charMeasurer(0)
,renderTarget(0)
,tabWidth(1)
,tabSpaceCount(4)
,passwordChar(L'\0')
{
TextLine line;
line.Initialize();
lines.Add(line);
}
TextLines::~TextLines()
{
RemoveLines(0, lines.Count());
}
//--------------------------------------------------------
vint TextLines::GetCount()
{
return lines.Count();
}
TextLine& TextLines::GetLine(vint row)
{
return lines[row];
}
CharMeasurer* TextLines::GetCharMeasurer()
{
return charMeasurer;
}
void TextLines::SetCharMeasurer(CharMeasurer* value)
{
charMeasurer=value;
if(charMeasurer) charMeasurer->SetRenderTarget(renderTarget);
ClearMeasurement();
}
IGuiGraphicsRenderTarget* TextLines::GetRenderTarget()
{
return renderTarget;
}
void TextLines::SetRenderTarget(IGuiGraphicsRenderTarget* value)
{
renderTarget=value;
if(charMeasurer) charMeasurer->SetRenderTarget(renderTarget);
ClearMeasurement();
}
WString TextLines::GetText(TextPos start, TextPos end)
{
if(!IsAvailable(start) || !IsAvailable(end) || start>end) return L"";
if(start.row==end.row)
{
return WString::CopyFrom(lines[start.row].text+start.column, end.column-start.column);
}
vint count=0;
for(vint i=start.row+1;i<end.row;i++)
{
count+=lines[i].dataLength;
}
count+=lines[start.row].dataLength-start.column;
count+=end.column;
Array<wchar_t> buffer;
buffer.Resize(count+(end.row-start.row)*2);
wchar_t* writing=&buffer[0];
for(vint i=start.row;i<=end.row;i++)
{
wchar_t* text=lines[i].text;
vint chars=0;
if(i==start.row)
{
text+=start.column;
chars=lines[i].dataLength-start.column;
}
else if(i==end.row)
{
chars=end.column;
}
else
{
chars=lines[i].dataLength;
}
if(i!=start.row)
{
*writing++=L'\r';
*writing++=L'\n';
}
memcpy(writing, text, chars*sizeof(wchar_t));
writing+=chars;
}
return WString::CopyFrom(&buffer[0], buffer.Count());
}
WString TextLines::GetText()
{
return GetText(TextPos(0, 0), TextPos(lines.Count()-1, lines[lines.Count()-1].dataLength));
}
void TextLines::SetText(const WString& value)
{
Modify(TextPos(0, 0), TextPos(lines.Count()-1, lines[lines.Count()-1].dataLength), value);
}
//--------------------------------------------------------
bool TextLines::RemoveLines(vint start, vint count)
{
if(start<0 || count<0 || start+count>lines.Count()) return false;
for(vint i=start+count-1;i>=start;i--)
{
lines[i].Finalize();
}
lines.RemoveRange(start, count);
return true;
}
bool TextLines::IsAvailable(TextPos pos)
{
return 0<=pos.row && pos.row<lines.Count() && 0<=pos.column && pos.column<=lines[pos.row].dataLength;
}
TextPos TextLines::Normalize(TextPos pos)
{
if(pos.row<0)
{
return TextPos(0, 0);
}
else if(pos.row>=lines.Count())
{
return TextPos(lines.Count()-1, lines[lines.Count()-1].dataLength);
}
else
{
TextLine& line=lines[pos.row];
if(pos.column<0)
{
return TextPos(pos.row, 0);
}
else if(pos.column>line.dataLength)
{
return TextPos(pos.row, line.dataLength);
}
else
{
return pos;
}
}
}
TextPos TextLines::Modify(TextPos start, TextPos end, const wchar_t** inputs, vint* inputCounts, vint rows)
{
if(!IsAvailable(start) || !IsAvailable(end) || start>end) return TextPos(-1, -1);
if (ownerElement)
{
ownerElement->InvokeOnElementStateChanged();
}
if(rows==1)
{
if(start.row==end.row)
{
lines[start.row].Modify(start.column, end.column-start.column, inputs[0], inputCounts[0]);
}
else
{
if(end.row-start.row>1)
{
RemoveLines(start.row+1, end.row-start.row-1);
}
vint modifyCount=lines[start.row].dataLength-start.column+end.column;
lines[start.row].AppendAndFinalize(lines[start.row+1]);
lines.RemoveAt(start.row+1);
lines[start.row].Modify(start.column, modifyCount, inputs[0], inputCounts[0]);
}
return TextPos(start.row, start.column+inputCounts[0]);
}
if(start.row==end.row)
{
TextLine newLine=lines[start.row].Split(end.column);
lines.Insert(start.row+1, newLine);
end=TextPos(start.row+1, 0);
}
vint oldMiddleLines=end.row-start.row-1;
vint newMiddleLines=rows-2;
if(oldMiddleLines<newMiddleLines)
{
for(vint i=oldMiddleLines;i<newMiddleLines;i++)
{
TextLine line;
line.Initialize();
lines.Insert(end.row, line);
}
}
else if(oldMiddleLines>newMiddleLines)
{
RemoveLines(start.row+newMiddleLines+1, oldMiddleLines-newMiddleLines);
}
end.row+=newMiddleLines-oldMiddleLines;
lines[start.row].Modify(start.column, lines[start.row].dataLength-start.column, inputs[0], inputCounts[0]);
lines[end.row].Modify(0, end.column, inputs[rows-1], inputCounts[rows-1]);
for(vint i=1;i<rows-1;i++)
{
lines[start.row+i].Modify(0, lines[start.row+i].dataLength, inputs[i], inputCounts[i]);
}
return TextPos(end.row, inputCounts[rows-1]);
}
TextPos TextLines::Modify(TextPos start, TextPos end, const wchar_t* input, vint inputCount)
{
List<const wchar_t*> inputs;
List<vint> inputCounts;
const wchar_t* previous=input;
const wchar_t* current=input;
while(true)
{
if(current==input+inputCount)
{
inputs.Add(previous);
inputCounts.Add(current-previous);
break;
}
else if(*current==L'\r' || *current==L'\n')
{
inputs.Add(previous);
inputCounts.Add(current-previous);
previous=current+(current[1]==L'\n'?2:1);
current=previous;
}
else
{
current++;
}
}
return Modify(start, end, &inputs[0], &inputCounts[0], inputs.Count());
}
TextPos TextLines::Modify(TextPos start, TextPos end, const wchar_t* input)
{
return Modify(start, end, input, wcslen(input));
}
TextPos TextLines::Modify(TextPos start, TextPos end, const WString& input)
{
return Modify(start, end, input.Buffer(), input.Length());
}
void TextLines::Clear()
{
RemoveLines(0, lines.Count());
TextLine line;
line.Initialize();
lines.Add(line);
if (ownerElement)
{
ownerElement->InvokeOnElementStateChanged();
}
}
//--------------------------------------------------------
void TextLines::ClearMeasurement()
{
for (vint i = 0; i < lines.Count(); i++)
{
lines[i].availableOffsetCount = 0;
}
tabWidth = tabSpaceCount * (charMeasurer ? charMeasurer->MeasureWidth({ L' ' }) : 1);
if (tabWidth == 0)
{
tabWidth = 1;
}
if (ownerElement)
{
ownerElement->InvokeOnElementStateChanged();
}
}
vint TextLines::GetTabSpaceCount()
{
return tabSpaceCount;
}
void TextLines::SetTabSpaceCount(vint value)
{
if(value<1) value=1;
if(tabSpaceCount!=value)
{
tabSpaceCount=value;
ClearMeasurement();
}
}
void TextLines::MeasureRow(vint row)
{
TextLine& line = lines[row];
vint offset = 0;
if (line.availableOffsetCount)
{
offset = line.att[line.availableOffsetCount - 1].rightOffset;
}
for (vint i = line.availableOffsetCount; i < line.dataLength; i++)
{
CharAtt& att = line.att[i];
wchar_t c = line.text[i];
vint width = 0;
vint passwordWidth = 0;
if (passwordChar)
{
passwordWidth = charMeasurer ? charMeasurer->MeasureWidth({ passwordChar }) : 1;
}
if (c == L'\t')
{
width = tabWidth - offset % tabWidth;
}
#if defined VCZH_MSVC
else if (UTF16SPFirst(c) && (i + 1 < line.dataLength) && UTF16SPSecond(line.text[i + 1]))
{
width = passwordChar ? passwordWidth : (charMeasurer ? charMeasurer->MeasureWidth({ c, line.text[i + 1] }) : 1);
offset += width;
att.rightOffset = (int)offset;
line.att[i + 1].rightOffset = (int)offset;
i++;
continue;
}
#endif
else
{
width = passwordChar ? passwordWidth : (charMeasurer ? charMeasurer->MeasureWidth({ c }) : 1);
}
offset += width;
att.rightOffset = (int)offset;
}
line.availableOffsetCount = line.dataLength;
}
vint TextLines::GetRowWidth(vint row)
{
if(row<0 || row>=lines.Count()) return -1;
TextLine& line=lines[row];
if(line.dataLength==0)
{
return 0;
}
else
{
MeasureRow(row);
return line.att[line.dataLength-1].rightOffset;
}
}
vint TextLines::GetRowHeight()
{
return charMeasurer ? charMeasurer->GetRowHeight() : 1;
}
vint TextLines::GetMaxWidth()
{
vint width=0;
for(vint i=0;i<lines.Count();i++)
{
vint rowWidth=GetRowWidth(i);
if(width<rowWidth)
{
width=rowWidth;
}
}
return width;
}
vint TextLines::GetMaxHeight()
{
return lines.Count() * GetRowHeight();
}
TextPos TextLines::GetTextPosFromPoint(Point point)
{
vint h = GetRowHeight();
if(point.y<0)
{
point.y=0;
}
else if(point.y>=h*lines.Count())
{
point.y=h*lines.Count()-1;
}
vint row=point.y/h;
if(point.x<0)
{
return TextPos(row, 0);
}
else if(point.x>=GetRowWidth(row))
{
return TextPos(row, lines[row].dataLength);
}
TextLine& line=lines[row];
vint i1=0, i2=line.dataLength;
vint p1=0, p2=line.att[line.dataLength-1].rightOffset;
while(i2-i1>1)
{
vint i=(i1+i2)/2;
vint p=i==0?0:line.att[i-1].rightOffset;
if(point.x<p)
{
i2=i;
p2=p;
}
else
{
i1=i;
p1=p;
}
}
#if defined VCZH_MSVC
if (UTF16SPSecond(line.text[i1]) && i1 > 0 && UTF16SPFirst(line.text[i1 - 1]))
{
i1--;
}
#endif
return TextPos(row, i1);
}
Point TextLines::GetPointFromTextPos(TextPos pos)
{
if(IsAvailable(pos))
{
vint y = pos.row * GetRowHeight();
if(pos.column==0)
{
return Point(0, y);
}
else
{
MeasureRow(pos.row);
TextLine& line=lines[pos.row];
return Point(line.att[pos.column-1].rightOffset, y);
}
}
else
{
return Point(-1, -1);
}
}
Rect TextLines::GetRectFromTextPos(TextPos pos)
{
Point point=GetPointFromTextPos(pos);
if(point==Point(-1, -1))
{
return Rect(-1, -1, -1, -1);
}
else
{
vint h = GetRowHeight();
TextLine& line=lines[pos.row];
if(pos.column==line.dataLength)
{
return Rect(point, Size(h/2, h));
}
else
{
return Rect(point, Size(line.att[pos.column].rightOffset-point.x, h));
}
}
}
//--------------------------------------------------------
wchar_t TextLines::GetPasswordChar()
{
return passwordChar;
}
void TextLines::SetPasswordChar(wchar_t value)
{
passwordChar=value;
ClearMeasurement();
}
}
using namespace text;
/***********************************************************************
GuiColorizedTextElement
***********************************************************************/
GuiColorizedTextElement::GuiColorizedTextElement()
:callback(0)
,isVisuallyEnabled(true)
,isFocused(false)
,caretVisible(false)
,lines(this)
{
}
text::TextLines& GuiColorizedTextElement::GetLines()
{
return lines;
}
GuiColorizedTextElement::ICallback* GuiColorizedTextElement::GetCallback()
{
return callback;
}
void GuiColorizedTextElement::SetCallback(ICallback* value)
{
callback=value;
if(!callback)
{
lines.SetCharMeasurer(0);
}
}
const GuiColorizedTextElement::ColorArray& GuiColorizedTextElement::GetColors()
{
return colors;
}
void GuiColorizedTextElement::SetColors(const ColorArray& value)
{
CopyFrom(colors, value);
if(callback) callback->ColorChanged();
InvokeOnElementStateChanged();
}
void GuiColorizedTextElement::ResetTextColorIndex(vint index)
{
vint lineCount = lines.GetCount();
for (vint i = 0; i < lineCount; i++)
{
auto& line = lines.GetLine(i);
line.lexerFinalState = -1;
line.contextFinalState = -1;
for (vint j = 0; j < line.dataLength; j++)
{
line.att[j].colorIndex = (vuint32_t)index;
}
}
}
const FontProperties& GuiColorizedTextElement::GetFont()
{
return font;
}
void GuiColorizedTextElement::SetFont(const FontProperties& value)
{
if(font!=value)
{
font=value;
if(callback)
{
callback->FontChanged();
}
InvokeOnElementStateChanged();
}
}
wchar_t GuiColorizedTextElement::GetPasswordChar()
{
return lines.GetPasswordChar();
}
void GuiColorizedTextElement::SetPasswordChar(wchar_t value)
{
if(lines.GetPasswordChar()!=value)
{
lines.SetPasswordChar(value);
InvokeOnElementStateChanged();
}
}
Point GuiColorizedTextElement::GetViewPosition()
{
return viewPosition;
}
void GuiColorizedTextElement::SetViewPosition(Point value)
{
if(viewPosition!=value)
{
viewPosition=value;
InvokeOnElementStateChanged();
}
}
bool GuiColorizedTextElement::GetVisuallyEnabled()
{
return isVisuallyEnabled;
}
void GuiColorizedTextElement::SetVisuallyEnabled(bool value)
{
if(isVisuallyEnabled!=value)
{
isVisuallyEnabled=value;
InvokeOnElementStateChanged();
}
}
bool GuiColorizedTextElement::GetFocused()
{
return isFocused;
}
void GuiColorizedTextElement::SetFocused(bool value)
{
if(isFocused!=value)
{
isFocused=value;
InvokeOnElementStateChanged();
}
}
TextPos GuiColorizedTextElement::GetCaretBegin()
{
return caretBegin;
}
void GuiColorizedTextElement::SetCaretBegin(TextPos value)
{
caretBegin=value;
InvokeOnElementStateChanged();
}
TextPos GuiColorizedTextElement::GetCaretEnd()
{
return caretEnd;
}
void GuiColorizedTextElement::SetCaretEnd(TextPos value)
{
caretEnd=value;
InvokeOnElementStateChanged();
}
bool GuiColorizedTextElement::GetCaretVisible()
{
return caretVisible;
}
void GuiColorizedTextElement::SetCaretVisible(bool value)
{
caretVisible=value;
InvokeOnElementStateChanged();
}
Color GuiColorizedTextElement::GetCaretColor()
{
return caretColor;
}
void GuiColorizedTextElement::SetCaretColor(Color value)
{
if(caretColor!=value)
{
caretColor=value;
InvokeOnElementStateChanged();
}
}
}
}
}
/***********************************************************************
.\NATIVEWINDOW\GUINATIVEWINDOW.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
const NativeWindowFrameConfig NativeWindowFrameConfig::Default = {};
/***********************************************************************
INativeWindowListener
***********************************************************************/
INativeWindowListener::HitTestResult INativeWindowListener::HitTest(NativePoint location)
{
return INativeWindowListener::NoDecision;
}
void INativeWindowListener::Moving(NativeRect& bounds, bool fixSizeOnly, bool draggingBorder)
{
}
void INativeWindowListener::Moved()
{
}
void INativeWindowListener::DpiChanged(bool preparing)
{
}
void INativeWindowListener::Enabled()
{
}
void INativeWindowListener::Disabled()
{
}
void INativeWindowListener::GotFocus()
{
}
void INativeWindowListener::LostFocus()
{
}
void INativeWindowListener::RenderingAsActivated()
{
}
void INativeWindowListener::RenderingAsDeactivated()
{
}
void INativeWindowListener::Opened()
{
}
void INativeWindowListener::BeforeClosing(bool& cancel)
{
}
void INativeWindowListener::AfterClosing()
{
}
void INativeWindowListener::Closed()
{
}
void INativeWindowListener::Paint()
{
}
void INativeWindowListener::Destroying()
{
}
void INativeWindowListener::Destroyed()
{
}
void INativeWindowListener::LeftButtonDown(const NativeWindowMouseInfo& info)
{
}
void INativeWindowListener::LeftButtonUp(const NativeWindowMouseInfo& info)
{
}
void INativeWindowListener::LeftButtonDoubleClick(const NativeWindowMouseInfo& info)
{
}
void INativeWindowListener::RightButtonDown(const NativeWindowMouseInfo& info)
{
}
void INativeWindowListener::RightButtonUp(const NativeWindowMouseInfo& info)
{
}
void INativeWindowListener::RightButtonDoubleClick(const NativeWindowMouseInfo& info)
{
}
void INativeWindowListener::MiddleButtonDown(const NativeWindowMouseInfo& info)
{
}
void INativeWindowListener::MiddleButtonUp(const NativeWindowMouseInfo& info)
{
}
void INativeWindowListener::MiddleButtonDoubleClick(const NativeWindowMouseInfo& info)
{
}
void INativeWindowListener::HorizontalWheel(const NativeWindowMouseInfo& info)
{
}
void INativeWindowListener::VerticalWheel(const NativeWindowMouseInfo& info)
{
}
void INativeWindowListener::MouseMoving(const NativeWindowMouseInfo& info)
{
}
void INativeWindowListener::MouseEntered()
{
}
void INativeWindowListener::MouseLeaved()
{
}
void INativeWindowListener::KeyDown(const NativeWindowKeyInfo& info)
{
}
void INativeWindowListener::KeyUp(const NativeWindowKeyInfo& info)
{
}
void INativeWindowListener::Char(const NativeWindowCharInfo& info)
{
}
bool INativeWindowListener::NeedRefresh()
{
return false;
}
void INativeWindowListener::ForceRefresh(bool handleFailure, bool& updated, bool& failureByResized, bool& failureByLostDevice)
{
}
void INativeWindowListener::AssignFrameConfig(const NativeWindowFrameConfig& config)
{
}
/***********************************************************************
INativeControllerListener
***********************************************************************/
void INativeControllerListener::GlobalTimer()
{
}
void INativeControllerListener::ClipboardUpdated()
{
}
void INativeControllerListener::GlobalShortcutKeyActivated(vint id)
{
}
void INativeControllerListener::NativeWindowCreated(INativeWindow* window)
{
}
void INativeControllerListener::NativeWindowDestroying(INativeWindow* window)
{
}
/***********************************************************************
Native Window Provider
***********************************************************************/
class SubstitutableController;
INativeController* nativeController = nullptr;
SubstitutableController* substitutableController = nullptr;
class SubstitutableController
: public Object
, public INativeController
, public INativeServiceSubstitution
{
public:
WString GetExecutablePath() override
{
return nativeController->GetExecutablePath();
}
// Substitutable Service
template<typename T, T* (INativeController::* Getter)()>
struct Substitution
{
T* service = nullptr;
bool optional = false;
bool requested = false;
bool unsubstituted = false;
void Substitute(T* _service, bool _optional)
{
CHECK_ERROR(
!requested,
L"The service cannot be substituted because it has been used."
);
service = _service;
optional = _optional;
}
void Unsubstitute(T* _service)
{
if (service == _service)
{
if (requested)
{
unsubstituted = true;
}
service = nullptr;
}
}
T* GetService()
{
CHECK_ERROR(
!unsubstituted,
L"The service cannot be used because it has been unsubstituted."
);
requested = true;
auto nativeService = (nativeController->*Getter)();
if (service && (!nativeService || !optional))
{
return service;
}
CHECK_ERROR(
nativeService != nullptr,
L"Required service does not exist."
);
return nativeService;
}
};
// Unsubstitutable Service
template<typename T, T* (INativeController::* Getter)()>
T* GetUnsubstitutableService()
{
auto nativeService = (nativeController->*Getter)();
CHECK_ERROR(
nativeService != nullptr,
L"Required service does not exist."
);
return nativeService;
}
// INativeServiceSubstitution and INativeController
#define GET_SUBSTITUTABLE_SERVICE(NAME) \
Substitution< \
INative##NAME##Service, \
&INativeController::NAME##Service \
> substituted##NAME; \
\
void Substitute(INative##NAME##Service* service, bool optional) override \
{ \
substituted##NAME.Substitute(service, optional); \
} \
\
void Unsubstitute(INative##NAME##Service* service) override \
{ \
substituted##NAME.Unsubstitute(service); \
} \
\
INative##NAME##Service* NAME##Service() override \
{ \
return substituted##NAME.GetService(); \
} \
GUI_SUBSTITUTABLE_SERVICES(GET_SUBSTITUTABLE_SERVICE)
#undef GET_SUBSTITUTABLE_SERVICE
#define GET_UNSUBSTITUTABLE_SERVICE(NAME) \
INative##NAME##Service* NAME##Service() override \
{ \
return GetUnsubstitutableService< \
INative##NAME##Service, \
&INativeController::NAME##Service \
>(); \
} \
GUI_UNSUBSTITUTABLE_SERVICES(GET_UNSUBSTITUTABLE_SERVICE)
#undef GET_UNSUBSTITUTABLE_SERVICE
};
INativeServiceSubstitution* GetNativeServiceSubstitution()
{
return substitutableController;
}
INativeController* GetCurrentController()
{
return substitutableController;
}
void SetNativeController(INativeController* controller)
{
nativeController = controller;
if (nativeController)
{
if (!substitutableController)
{
substitutableController = new SubstitutableController();
}
}
else
{
if (substitutableController)
{
delete substitutableController;
substitutableController = 0;
}
}
}
/***********************************************************************
Helper Functions
***********************************************************************/
NativeImageFrameBase::NativeImageFrameBase()
{
}
NativeImageFrameBase::~NativeImageFrameBase()
{
// TODO: (enumerable) foreach
for (vint i = 0; i < caches.Count(); i++)
{
caches.Values().Get(i)->OnDetach(this);
}
}
bool NativeImageFrameBase::SetCache(void* key, Ptr<INativeImageFrameCache> cache)
{
vint index = caches.Keys().IndexOf(key);
if (index != -1)
{
return false;
}
caches.Add(key, cache);
cache->OnAttach(this);
return true;
}
Ptr<INativeImageFrameCache> NativeImageFrameBase::GetCache(void* key)
{
vint index = caches.Keys().IndexOf(key);
return index == -1 ? nullptr : caches.Values().Get(index);
}
Ptr<INativeImageFrameCache> NativeImageFrameBase::RemoveCache(void* key)
{
vint index = caches.Keys().IndexOf(key);
if (index == -1)
{
return 0;
}
Ptr<INativeImageFrameCache> cache = caches.Values().Get(index);
cache->OnDetach(this);
caches.Remove(key);
return cache;
}
/***********************************************************************
Helper Functions
***********************************************************************/
INativeCursor* GetCursorFromHitTest(INativeWindowListener::HitTestResult hitTestResult, INativeResourceService* resourceService)
{
switch (hitTestResult)
{
case INativeWindowListener::BorderLeft:
case INativeWindowListener::BorderRight:
return resourceService->GetSystemCursor(INativeCursor::SizeWE);
case INativeWindowListener::BorderTop:
case INativeWindowListener::BorderBottom:
return resourceService->GetSystemCursor(INativeCursor::SizeNS);
case INativeWindowListener::BorderLeftTop:
case INativeWindowListener::BorderRightBottom:
return resourceService->GetSystemCursor(INativeCursor::SizeNWSE);
case INativeWindowListener::BorderRightTop:
case INativeWindowListener::BorderLeftBottom:
return resourceService->GetSystemCursor(INativeCursor::SizeNESW);
default:
return nullptr;
}
}
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\GACGEN\GACGENCONTROLLER.CPP
***********************************************************************/
using namespace vl;
using namespace vl::stream;
using namespace vl::reflection::description;
using namespace vl::presentation;
class GacGenNativeController
: public Object
, public INativeController
, protected INativeCallbackService
, protected INativeResourceService
, protected INativeImageService
, protected INativeInputService
{
public:
INativeCallbackService* CallbackService() override
{
return this;
}
INativeResourceService* ResourceService() override
{
return this;
}
INativeAsyncService* AsyncService() override
{
CHECK_FAIL(L"Not implemented!");
}
INativeClipboardService* ClipboardService() override
{
CHECK_FAIL(L"Not implemented!");
}
INativeImageService* ImageService() override
{
return this;
}
INativeScreenService* ScreenService() override
{
CHECK_FAIL(L"Not implemented!");
}
INativeWindowService* WindowService() override
{
CHECK_FAIL(L"Not implemented!");
}
INativeInputService* InputService() override
{
return this;
}
INativeDialogService* DialogService() override
{
CHECK_FAIL(L"Not implemented!");
}
WString GetExecutablePath() override
{
CHECK_FAIL(L"Not implemented!");
}
////////////////////////////////////////////////////////////////////
// INativeCallbackService
////////////////////////////////////////////////////////////////////
bool InstallListener(INativeControllerListener* listener) override
{
return true;
}
bool UninstallListener(INativeControllerListener* listener) override
{
return true;
}
INativeCallbackInvoker* Invoker() override
{
CHECK_FAIL(L"Not implemented!");
}
////////////////////////////////////////////////////////////////////
// INativeResourceService
////////////////////////////////////////////////////////////////////
INativeCursor* GetSystemCursor(INativeCursor::SystemCursorType type) override
{
CHECK_FAIL(L"Not implemented!");
}
INativeCursor* GetDefaultSystemCursor() override
{
CHECK_FAIL(L"Not implemented!");
}
FontProperties GetDefaultFont() override
{
FontProperties font;
font.fontFamily = L"GacGen";
font.size = 12;
font.bold = false;
font.italic = false;
font.underline = false;
font.strikeline = false;
font.antialias = false;
font.verticalAntialias = false;
return font;
}
void SetDefaultFont(const FontProperties& value) override
{
CHECK_FAIL(L"Not implemented!");
}
void EnumerateFonts(collections::List<WString>& fonts) override
{
CHECK_FAIL(L"Not implemented!");
}
////////////////////////////////////////////////////////////////////
// INativeImageService
////////////////////////////////////////////////////////////////////
class NativeImage : public Object, public INativeImage
{
protected:
INativeImageService* imageService;
MemoryStream memoryStream;
public:
NativeImage(INativeImageService* _imageService, IStream& inputStream)
: imageService(_imageService)
{
CopyStream(inputStream, memoryStream);
}
INativeImageService* GetImageService() override
{
return imageService;
}
FormatType GetFormat() override
{
CHECK_FAIL(L"Not implemented!");
}
vint GetFrameCount() override
{
return 0;
}
INativeImageFrame* GetFrame(vint index) override
{
CHECK_FAIL(L"Not implemented!");
}
void SaveToStream(stream::IStream& imageStream, FormatType formatType) override
{
CHECK_ERROR(formatType == FormatType::Unknown, L"Not Implemented!");
memoryStream.SeekFromBegin(0);
CopyStream(memoryStream, imageStream);
}
};
Ptr<INativeImage> CreateImageFromFile(const WString& path) override
{
FileStream imageStream(path, FileStream::ReadOnly);
if (!imageStream.IsAvailable()) return nullptr;
return Ptr(new NativeImage(this, imageStream));
}
Ptr<INativeImage> CreateImageFromMemory(void* buffer, vint length) override
{
MemoryWrapperStream imageStream(buffer, length);
return Ptr(new NativeImage(this, imageStream));
}
Ptr<INativeImage> CreateImageFromStream(stream::IStream& imageStream) override
{
return Ptr(new NativeImage(this, imageStream));
}
////////////////////////////////////////////////////////////////////
// INativeInputService
////////////////////////////////////////////////////////////////////
void StartTimer() override
{
}
void StopTimer() override
{
}
bool IsTimerEnabled() override
{
CHECK_FAIL(L"Not implemented!");
}
bool IsKeyPressing(VKEY code) override
{
CHECK_FAIL(L"Not implemented!");
}
bool IsKeyToggled(VKEY code) override
{
CHECK_FAIL(L"Not implemented!");
}
WString GetKeyName(VKEY code) override
{
CHECK_FAIL(L"Not implemented!");
}
VKEY GetKey(const WString& name) override
{
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();
int SetupGacGenNativeController()
{
GacGenNativeController controller;
SetNativeController(&controller);
GuiApplicationMain();
SetNativeController(nullptr);
return 0;
}
/***********************************************************************
.\PLATFORMPROVIDERS\HOSTED\GUIHOSTEDAPPLICATION.CPP
***********************************************************************/
namespace vl::presentation
{
IGuiHostedApplication* hostedApplication = nullptr;
IGuiHostedApplication* GetHostedApplication()
{
return hostedApplication;
}
void SetHostedApplication(IGuiHostedApplication* _hostedApp)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::SetHostedApplication(IGuiHostedApplication*)#"
if (_hostedApp)
{
CHECK_ERROR(!hostedApplication, ERROR_MESSAGE_PREFIX L"IGuiHostedApplication instance already exists during initializing.");
}
else
{
CHECK_ERROR(hostedApplication, ERROR_MESSAGE_PREFIX L"IGuiHostedApplication instance does not exist during finalizing.");
}
hostedApplication = _hostedApp;
#undef ERROR_MESSAGE_PREFIX
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\HOSTED\GUIHOSTEDCONTROLLER.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
/***********************************************************************
GuiHostedController
***********************************************************************/
NativePoint GuiHostedController::GetPointInClientSpace(NativePoint location)
{
auto windowBounds = nativeWindow->GetBounds();
auto clientBounds = nativeWindow->GetClientBoundsInScreen();
location.x.value += windowBounds.x1.value - clientBounds.x1.value;
location.y.value += windowBounds.y1.value - clientBounds.y1.value;
return location;
}
GuiHostedWindow* GuiHostedController::HitTestInClientSpace(NativePoint location)
{
auto window = wmManager->HitTest(location);
return window ? window->id : nullptr;
}
void GuiHostedController::UpdateHoveringWindow(Nullable<NativePoint> location)
{
if (location)
{
hoveringLocation = location.Value();
}
hoveringWindow = HitTestInClientSpace(hoveringLocation);
}
void GuiHostedController::UpdateEnteringWindow(GuiHostedWindow* window)
{
if (enteringWindow != window)
{
if (enteringWindow)
{
for (auto listener : enteringWindow->listeners)
{
listener->MouseLeaved();
}
}
enteringWindow = window;
if (enteringWindow)
{
for (auto listener : enteringWindow->listeners)
{
listener->MouseEntered();
}
}
}
}
/***********************************************************************
GuiHostedController::WindowManager<GuiHostedWindow*>
***********************************************************************/
void GuiHostedController::OnOpened(hosted_window_manager::Window<GuiHostedWindow*>* window)
{
if (!mainWindow || window != &mainWindow->wmWindow)
{
for (auto listener : window->id->listeners)
{
listener->Opened();
}
}
}
void GuiHostedController::OnClosed(hosted_window_manager::Window<GuiHostedWindow*>* window)
{
for (auto listener : window->id->listeners)
{
listener->Closed();
}
}
void GuiHostedController::OnEnabled(hosted_window_manager::Window<GuiHostedWindow*>* window)
{
for (auto listener : window->id->listeners)
{
listener->Enabled();
}
}
void GuiHostedController::OnDisabled(hosted_window_manager::Window<GuiHostedWindow*>* window)
{
for (auto listener : window->id->listeners)
{
listener->Disabled();
}
}
void GuiHostedController::OnGotFocus(hosted_window_manager::Window<GuiHostedWindow*>* window)
{
window->id->BecomeFocusedWindow();
for (auto listener : window->id->listeners)
{
listener->GotFocus();
}
}
void GuiHostedController::OnLostFocus(hosted_window_manager::Window<GuiHostedWindow*>* window)
{
for (auto listener : window->id->listeners)
{
listener->LostFocus();
}
}
void GuiHostedController::OnActivated(hosted_window_manager::Window<GuiHostedWindow*>* window)
{
for (auto listener : window->id->listeners)
{
listener->RenderingAsActivated();
}
}
void GuiHostedController::OnDeactivated(hosted_window_manager::Window<GuiHostedWindow*>* window)
{
for (auto listener : window->id->listeners)
{
listener->RenderingAsDeactivated();
}
}
/***********************************************************************
GuiHostedController::INativeWindowListener
***********************************************************************/
INativeWindowListener::HitTestResult GuiHostedController::HitTest(NativePoint location)
{
if (mainWindow && mainWindow->IsEnabled())
{
auto point = GetPointInClientSpace(location);
auto window = HitTestInClientSpace(point);
if (window == mainWindow)
{
return PerformHitTest(From(mainWindow->listeners), point);
}
}
return INativeWindowListener::HitTestResult::NoDecision;
}
void GuiHostedController::Moving(NativeRect& bounds, bool fixSizeOnly, bool draggingBorder)
{
if (mainWindow)
{
auto windowBounds = nativeWindow->GetBounds();
auto clientBounds = nativeWindow->GetClientBoundsInScreen();
auto w = clientBounds.Width().value - windowBounds.Width().value;
auto h = clientBounds.Height().value - windowBounds.Height().value;
NativeRect mainBounds;
mainBounds.x2 = bounds.Width().value - w;
mainBounds.y2 = bounds.Height().value - h;
for (auto listener : mainWindow->listeners)
{
listener->Moving(mainBounds, fixSizeOnly, draggingBorder);
}
bounds.x1.value += mainBounds.x1.value;
bounds.y1.value += mainBounds.y1.value;
bounds.x2.value = bounds.x1.value + mainBounds.Width().value + w;
bounds.y2.value = bounds.y1.value + mainBounds.Height().value + h;
}
}
void GuiHostedController::Moved()
{
if (mainWindow)
{
auto size = mainWindow->GetBounds().GetSize();
auto clientSize = nativeWindow->GetClientSize();
if (size != clientSize)
{
mainWindow->SetBounds({ {},clientSize });
}
for (auto listener : mainWindow->listeners)
{
listener->Moved();
}
}
}
void GuiHostedController::DpiChanged(bool preparing)
{
if (!preparing)
{
hostedResourceManager->nativeManager->RecreateRenderTarget(nativeWindow);
wmManager->needRefresh = true;
}
for (auto hostedWindow : createdWindows)
{
for (auto listener : hostedWindow->listeners)
{
listener->DpiChanged(preparing);
}
}
}
void GuiHostedController::GotFocus()
{
if (lastFocusedWindow)
{
lastFocusedWindow->wmWindow.Activate();
lastFocusedWindow = nullptr;
}
else if (mainWindow)
{
mainWindow->wmWindow.Activate();
}
}
void GuiHostedController::Opened()
{
if (mainWindow)
{
for (auto listener : mainWindow->wmWindow.id->listeners)
{
listener->Opened();
}
}
}
void GuiHostedController::LostFocus()
{
lastFocusedWindow = wmManager->activeWindow ? wmManager->activeWindow->id : nullptr;
while (wmManager->activeWindow)
{
wmManager->activeWindow->Deactivate();
}
}
void GuiHostedController::BeforeClosing(bool& cancel)
{
if (mainWindow)
{
for (auto listener : mainWindow->listeners)
{
listener->BeforeClosing(cancel);
if (cancel) return;
}
}
}
void GuiHostedController::AfterClosing()
{
if (mainWindow)
{
for (auto listener : mainWindow->listeners)
{
listener->AfterClosing();
}
}
}
void GuiHostedController::Paint()
{
}
/***********************************************************************
GuiHostedController::INativeWindowListener (GetSelectedWindow)
***********************************************************************/
GuiHostedWindow* GuiHostedController::GetSelectedWindow_MouseDown(const NativeWindowMouseInfo& info)
{
if (!capturingWindow)
{
SortedList<GuiHostedWindow*> survivedPopups;
auto current = hoveringWindow;
while (current)
{
if (current->IsVisible() && current->GetWindowMode() != INativeWindow::Normal)
{
survivedPopups.Add(current);
}
current = current->wmWindow.parent ? current->wmWindow.parent->id : nullptr;
}
List<GuiHostedWindow*> closingPopups;
CopyFrom(
closingPopups,
From(wmManager->ordinaryWindowsInOrder)
.Concat(wmManager->topMostedWindowsInOrder)
.Select([](auto window) { return window->id; })
.Where([&](auto window) { return window->GetWindowMode() != INativeWindow::Normal && !survivedPopups.Contains(window); })
);
for (auto popupWindow : closingPopups)
{
popupWindow->Hide(false);
}
}
auto selectedWindow = capturingWindow ? capturingWindow : hoveringWindow;
return selectedWindow;
}
GuiHostedWindow* GuiHostedController::GetSelectedWindow_MouseMoving(const NativeWindowMouseInfo& info)
{
UpdateHoveringWindow({ { info.x,info.y } });
auto selectedWindow = capturingWindow ? capturingWindow : hoveringWindow;
UpdateEnteringWindow(selectedWindow);
return selectedWindow;
}
GuiHostedWindow* GuiHostedController::GetSelectedWindow_Other(const NativeWindowMouseInfo& info)
{
auto selectedWindow = capturingWindow ? capturingWindow : hoveringWindow;
return selectedWindow;
}
/***********************************************************************
GuiHostedController::INativeWindowListener (PreAction)
***********************************************************************/
void GuiHostedController::PreAction_LeftButtonDown(const NativeWindowMouseInfo& info)
{
PreAction_MouseDown(info);
if (!capturingWindow && !wmWindow && hoveringWindow && hoveringWindow != mainWindow && hoveringWindow->IsEnabled())
{
auto x = info.x.value - hoveringWindow->wmWindow.bounds.x1.value;
auto y = info.y.value - hoveringWindow->wmWindow.bounds.y1.value;
auto hitTestResult = PerformHitTest(From(hoveringWindow->listeners), { {x},{y} });
switch (hitTestResult)
{
#define HANDLE_HIT_TEST_RESULT(NAME)\
case INativeWindowListener::NAME: \
wmOperation = WindowManagerOperation::NAME; \
break; \
HANDLE_HIT_TEST_RESULT(Title)
HANDLE_HIT_TEST_RESULT(BorderLeft)
HANDLE_HIT_TEST_RESULT(BorderRight)
HANDLE_HIT_TEST_RESULT(BorderTop)
HANDLE_HIT_TEST_RESULT(BorderBottom)
HANDLE_HIT_TEST_RESULT(BorderLeftTop)
HANDLE_HIT_TEST_RESULT(BorderRightBottom)
HANDLE_HIT_TEST_RESULT(BorderRightTop)
HANDLE_HIT_TEST_RESULT(BorderLeftBottom)
default:;
#undef HANDLE_HIT_TEST_RESULT
}
switch (wmOperation)
{
case WindowManagerOperation::None:
return;
case WindowManagerOperation::Title:
if (!hoveringWindow->GetTitleBar())
{
wmOperation = WindowManagerOperation::None;
return;
}
break;
default:
if (!hoveringWindow->GetSizeBox())
{
wmOperation = WindowManagerOperation::None;
return;
}
}
wmWindow = hoveringWindow;
nativeWindow->RequireCapture();
switch (wmOperation)
{
case WindowManagerOperation::Title:
case WindowManagerOperation::BorderLeft:
case WindowManagerOperation::BorderLeftTop:
case WindowManagerOperation::BorderLeftBottom:
wmRelative.x.value = x;
break;
case WindowManagerOperation::BorderTop:
case WindowManagerOperation::BorderBottom:
wmRelative.x.value = wmWindow->wmWindow.bounds.Width().value / 2;
break;
case WindowManagerOperation::BorderRight:
case WindowManagerOperation::BorderRightTop:
case WindowManagerOperation::BorderRightBottom:
wmRelative.x.value = wmWindow->wmWindow.bounds.Width().value - x;
break;
default:;
}
switch (wmOperation)
{
case WindowManagerOperation::Title:
case WindowManagerOperation::BorderTop:
case WindowManagerOperation::BorderLeftTop:
case WindowManagerOperation::BorderRightTop:
wmRelative.y.value = y;
break;
case WindowManagerOperation::BorderLeft:
case WindowManagerOperation::BorderRight:
wmRelative.y.value = wmWindow->wmWindow.bounds.Height().value / 2;
break;
case WindowManagerOperation::BorderBottom:
case WindowManagerOperation::BorderLeftBottom:
case WindowManagerOperation::BorderRightBottom:
wmRelative.y.value = wmWindow->wmWindow.bounds.Height().value - y;
break;
default:;
}
}
}
void GuiHostedController::PreAction_MouseDown(const NativeWindowMouseInfo& info)
{
if (!capturingWindow && !wmWindow && hoveringWindow && hoveringWindow->IsEnabled() && hoveringWindow->IsEnabledActivate())
{
hoveringWindow->SetActivate();
}
}
void GuiHostedController::PreAction_MouseMoving(const NativeWindowMouseInfo& info)
{
if (!capturingWindow && !wmWindow && hoveringWindow && hoveringWindow != mainWindow && hoveringWindow->IsEnabled() && hoveringWindow->GetSizeBox())
{
auto x = info.x.value - hoveringWindow->wmWindow.bounds.x1.value;
auto y = info.y.value - hoveringWindow->wmWindow.bounds.y1.value;
auto hitTestResult = PerformHitTest(From(hoveringWindow->listeners), { {x},{y} });
auto cursor = GetCursorFromHitTest(hitTestResult, ResourceService());
if (cursor == nullptr)
{
cursor = hoveringWindow->GetWindowCursor();
}
nativeWindow->SetWindowCursor(cursor);
}
if (wmWindow)
{
auto oldBounds = wmWindow->wmWindow.bounds;
auto newBounds = oldBounds;
vint mouseX = info.x.value;
vint mouseY = info.y.value;
vint displayX = mainWindow->wmWindow.bounds.Width().value;
vint displayY = mainWindow->wmWindow.bounds.Height().value;
if (mouseX < 0)
{
mouseX = 0;
}
else if (mouseX >= displayX)
{
mouseX = displayX - 1;
}
if (mouseY < 0)
{
mouseY = 0;
}
else if (mouseY >= displayY)
{
mouseY = displayY - 1;
}
if (wmOperation == WindowManagerOperation::Title)
{
newBounds = {
{
{mouseX - wmRelative.x.value},
{mouseY - wmRelative.y.value}
},
oldBounds.GetSize()
};
}
else
{
switch (wmOperation)
{
case WindowManagerOperation::BorderLeft:
case WindowManagerOperation::BorderLeftTop:
case WindowManagerOperation::BorderLeftBottom:
newBounds.x1.value = mouseX - wmRelative.x.value;
break;
case WindowManagerOperation::BorderRight:
case WindowManagerOperation::BorderRightTop:
case WindowManagerOperation::BorderRightBottom:
newBounds.x2.value = mouseX + wmRelative.x.value;
break;
default:;
}
switch (wmOperation)
{
case WindowManagerOperation::BorderTop:
case WindowManagerOperation::BorderLeftTop:
case WindowManagerOperation::BorderRightTop:
newBounds.y1.value = mouseY - wmRelative.y.value;
break;
case WindowManagerOperation::BorderBottom:
case WindowManagerOperation::BorderLeftBottom:
case WindowManagerOperation::BorderRightBottom:
newBounds.y2.value = mouseY + wmRelative.y.value;
break;
default:;
}
}
for (auto listener : wmWindow->listeners)
{
listener->Moving(newBounds, false, wmOperation != WindowManagerOperation::Title);
}
wmWindow->wmWindow.SetBounds(newBounds);
for (auto listener : wmWindow->listeners)
{
listener->Moved();
}
}
}
void GuiHostedController::PreAction_Other(const NativeWindowMouseInfo& info)
{
}
/***********************************************************************
GuiHostedController::INativeWindowListener (PostAction)
***********************************************************************/
void GuiHostedController::PostAction_LeftButtonUp(GuiHostedWindow* selectedWindow, const NativeWindowMouseInfo& info)
{
if (!capturingWindow && !wmWindow && selectedWindow && selectedWindow != mainWindow && selectedWindow->IsEnabled())
{
auto x = info.x.value - hoveringWindow->wmWindow.bounds.x1.value;
auto y = info.y.value - hoveringWindow->wmWindow.bounds.y1.value;
auto hitTestResult = PerformHitTest(From(hoveringWindow->listeners), { {x},{y} });
if (hitTestResult == INativeWindowListener::ButtonClose)
{
hoveringWindow->Hide(true);
}
}
if (wmWindow)
{
wmWindow = nullptr;
wmOperation = WindowManagerOperation::None;
nativeWindow->ReleaseCapture();
}
}
void GuiHostedController::PostAction_Other(GuiHostedWindow* selectedWindow, const NativeWindowMouseInfo& info)
{
}
/***********************************************************************
GuiHostedController::INativeWindowListener (Template)
***********************************************************************/
template<
void (GuiHostedController::* PreAction)(const NativeWindowMouseInfo&),
GuiHostedWindow*(GuiHostedController::* GetSelectedWindow)(const NativeWindowMouseInfo&),
void (GuiHostedController::* PostAction)(GuiHostedWindow*, const NativeWindowMouseInfo&),
void (INativeWindowListener::* Callback)(const NativeWindowMouseInfo&)
>
void GuiHostedController::HandleMouseCallback(const NativeWindowMouseInfo& info)
{
(this->*PreAction)(info);
auto postActionWindow = hoveringWindow;
if (!wmWindow)
{
if (auto selectedWindow = (this->*GetSelectedWindow)(info))
{
postActionWindow = selectedWindow;
if (!selectedWindow->IsEnabled()) return;
auto adjustedInfo = info;
adjustedInfo.x.value -= selectedWindow->wmWindow.bounds.x1.value;
adjustedInfo.y.value -= selectedWindow->wmWindow.bounds.y1.value;
for (auto listener : selectedWindow->listeners)
{
(listener->*Callback)(adjustedInfo);
}
}
}
(this->*PostAction)(postActionWindow, info);
}
template<
typename TInfo,
void (INativeWindowListener::* Callback)(const TInfo&)
>
void GuiHostedController::HandleKeyboardCallback(const TInfo& info)
{
if (wmManager->activeWindow && !wmWindow)
{
auto hostedWindow = wmManager->activeWindow->id;
for (auto listener : hostedWindow->listeners)
{
(listener->*Callback)(info);
}
}
}
/***********************************************************************
GuiHostedController::INativeWindowListener (IO Event Handling)
***********************************************************************/
#define IMPLEMENT_MOUSE_CALLBACK(NAME, PREACTION, POLICY, POSTACTION) \
void GuiHostedController::NAME(const NativeWindowMouseInfo& info) \
{ \
HandleMouseCallback< \
&GuiHostedController::PreAction_##PREACTION, \
&GuiHostedController::GetSelectedWindow_##POLICY, \
&GuiHostedController::PostAction_##POSTACTION, \
&INativeWindowListener::NAME \
>(info); \
} \
IMPLEMENT_MOUSE_CALLBACK(LeftButtonDown, LeftButtonDown, MouseDown, Other )
IMPLEMENT_MOUSE_CALLBACK(LeftButtonUp, Other, Other, LeftButtonUp )
IMPLEMENT_MOUSE_CALLBACK(LeftButtonDoubleClick, Other, Other, Other )
IMPLEMENT_MOUSE_CALLBACK(RightButtonDown, MouseDown, MouseDown, Other )
IMPLEMENT_MOUSE_CALLBACK(RightButtonUp, Other, Other, Other )
IMPLEMENT_MOUSE_CALLBACK(RightButtonDoubleClick, Other, Other, Other )
IMPLEMENT_MOUSE_CALLBACK(MiddleButtonDown, MouseDown, MouseDown, Other )
IMPLEMENT_MOUSE_CALLBACK(MiddleButtonUp, Other, Other, Other )
IMPLEMENT_MOUSE_CALLBACK(MiddleButtonDoubleClick, Other, Other, Other )
IMPLEMENT_MOUSE_CALLBACK(HorizontalWheel, Other, Other, Other )
IMPLEMENT_MOUSE_CALLBACK(VerticalWheel, Other, Other, Other )
IMPLEMENT_MOUSE_CALLBACK(MouseMoving, MouseMoving, MouseMoving, Other )
#undef IMPLEMENT_MOUSE_CALLBACK
void GuiHostedController::MouseEntered()
{
}
void GuiHostedController::MouseLeaved()
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::GuiHostedController::MouseLeaved()#"
UpdateEnteringWindow(nullptr);
#undef ERROR_MESSAGE_PREFIX
}
#define IMPLEMENT_KEY_CALLBACK(NAME, TYPE) \
void GuiHostedController::NAME(const NativeWindow##TYPE##Info& info) \
{ \
HandleKeyboardCallback< \
NativeWindow##TYPE##Info, \
&INativeWindowListener::NAME \
>(info); \
} \
IMPLEMENT_KEY_CALLBACK(KeyDown, Key)
IMPLEMENT_KEY_CALLBACK(KeyUp, Key)
IMPLEMENT_KEY_CALLBACK(Char, Char)
#undef IMPLEMENT_KEY_CALLBACK
/***********************************************************************
GuiHostedController::INativeControllerListener
***********************************************************************/
void GuiHostedController::GlobalTimer()
{
callbackService.InvokeGlobalTimer();
if (hostedResourceManager && nativeWindow && nativeWindow->IsVisible())
{
auto renderTarget = hostedResourceManager->nativeManager->GetRenderTarget(nativeWindow);
if (renderTarget->IsInHostedRendering())
{
return;
}
for (auto visibleWindow : From(wmManager->ordinaryWindowsInOrder).Concat(wmManager->topMostedWindowsInOrder))
{
for (auto listener : visibleWindow->id->listeners)
{
if (listener->NeedRefresh())
{
wmManager->needRefresh = true;
goto NEED_REFRESH;
}
}
}
if (!wmManager->needRefresh && !windowsUpdatedInLastFrame)
{
return;
}
NEED_REFRESH:
wmManager->needRefresh = false;
windowsUpdatedInLastFrame = false;
while (true)
{
renderTarget->StartHostedRendering();
bool failureByResized = false;
bool failureByLostDevice = false;
auto forceRefreshWindows = [&](List<hosted_window_manager::Window<GuiHostedWindow*>*>& windows)
{
// TODO: (enumerable) foreach:reversed
for (vint i = windows.Count() - 1; i >= 0; i--)
{
auto hostedWindow = windows[i]->id;
for (auto listener : hostedWindow->listeners)
{
bool updated = false;
listener->ForceRefresh(false, updated, failureByResized, failureByLostDevice);
windowsUpdatedInLastFrame |= updated;
if (failureByResized || failureByLostDevice)
{
return false;
}
}
}
return true;
};
if (!forceRefreshWindows(wmManager->ordinaryWindowsInOrder)) goto STOP_RENDERING;
if (!forceRefreshWindows(wmManager->topMostedWindowsInOrder)) goto STOP_RENDERING;
STOP_RENDERING:
switch (renderTarget->StopHostedRendering())
{
case elements::RenderTargetFailure::LostDevice:
failureByLostDevice = true;
break;
case elements::RenderTargetFailure::ResizeWhileRendering:
failureByResized = true;
break;
default:;
}
if (failureByLostDevice)
{
hostedResourceManager->nativeManager->RecreateRenderTarget(nativeWindow);
wmManager->needRefresh = true;
}
else if (failureByResized)
{
hostedResourceManager->nativeManager->ResizeRenderTarget(nativeWindow);
wmManager->needRefresh = true;
}
else
{
nativeWindow->RedrawContent();
break;
}
}
}
}
void GuiHostedController::ClipboardUpdated()
{
callbackService.InvokeClipboardUpdated();
}
void GuiHostedController::GlobalShortcutKeyActivated(vint id)
{
callbackService.InvokeGlobalShortcutKeyActivated(id);
}
void GuiHostedController::NativeWindowDestroying(INativeWindow* window)
{
if (nativeWindow == window)
{
DestroyHostedWindowsAfterRunning();
nativeWindow->UninstallListener(this);
nativeWindow = nullptr;
}
}
/***********************************************************************
GuiHostedController::INativeAsyncService
***********************************************************************/
bool GuiHostedController::IsInMainThread(INativeWindow* window)
{
return nativeController->AsyncService()->IsInMainThread(nativeWindow);
}
void GuiHostedController::InvokeAsync(const Func<void()>& proc)
{
return nativeController->AsyncService()->InvokeAsync(proc);
}
void GuiHostedController::InvokeInMainThread(INativeWindow* window, const Func<void()>& proc)
{
return nativeController->AsyncService()->InvokeInMainThread(nativeWindow, proc);
}
bool GuiHostedController::InvokeInMainThreadAndWait(INativeWindow* window, const Func<void()>& proc, vint milliseconds)
{
return nativeController->AsyncService()->InvokeInMainThreadAndWait(nativeWindow, proc, milliseconds);
}
Ptr<INativeDelay> GuiHostedController::DelayExecute(const Func<void()>& proc, vint milliseconds)
{
return nativeController->AsyncService()->DelayExecute(proc, milliseconds);
}
Ptr<INativeDelay> GuiHostedController::DelayExecuteInMainThread(const Func<void()>& proc, vint milliseconds)
{
return nativeController->AsyncService()->DelayExecuteInMainThread(proc, milliseconds);
}
/***********************************************************************
GuiHostedController::INativeScreenService
***********************************************************************/
vint GuiHostedController::GetScreenCount()
{
return 1;
}
INativeScreen* GuiHostedController::GetScreen(vint index)
{
CHECK_ERROR(index == 0, L"vl::presentation::GuiHostedController::GetScreen(vint)#Index out of range.");
return this;
}
INativeScreen* GuiHostedController::GetScreen(INativeWindow* window)
{
return this;
}
/***********************************************************************
GuiHostedController::INativeScreen
***********************************************************************/
NativeRect GuiHostedController::GetBounds()
{
if (nativeWindow->IsCustomFrameModeEnabled())
{
return { {},nativeWindow->GetBounds().GetSize() };
}
else
{
return { {},nativeWindow->GetClientSize() };
}
}
NativeRect GuiHostedController::GetClientBounds()
{
return { {},nativeWindow->GetClientSize() };
}
WString GuiHostedController::GetName()
{
return WString::Unmanaged(L"GacUI Virtual Screen");
}
bool GuiHostedController::IsPrimary()
{
return true;
}
double GuiHostedController::GetScalingX()
{
return nativeController->ScreenService()->GetScreen(nativeWindow)->GetScalingX();
}
double GuiHostedController::GetScalingY()
{
return nativeController->ScreenService()->GetScreen(nativeWindow)->GetScalingY();
}
/***********************************************************************
GuiHostedController::INativeWindowService
***********************************************************************/
const NativeWindowFrameConfig& GuiHostedController::GetMainWindowFrameConfig()
{
return nativeController->WindowService()->GetMainWindowFrameConfig();
}
const NativeWindowFrameConfig& GuiHostedController::GetNonMainWindowFrameConfig()
{
static const NativeWindowFrameConfig config = {
.MaximizedBoxOption = BoolOption::AlwaysFalse,
.MinimizedBoxOption = BoolOption::AlwaysFalse,
.CustomFrameEnabled = BoolOption::AlwaysTrue,
};
return config;
}
INativeWindow* GuiHostedController::CreateNativeWindow(INativeWindow::WindowMode windowMode)
{
auto hostedWindow = Ptr(new GuiHostedWindow(this, windowMode));
createdWindows.Add(hostedWindow);
wmManager->RegisterWindow(&hostedWindow->wmWindow);
callbackService.InvokeNativeWindowCreated(hostedWindow.Obj());
if (mainWindow)
{
hostedWindow->BecomeNonMainWindow();
}
return hostedWindow.Obj();
}
void GuiHostedController::DestroyNativeWindow(INativeWindow* window)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::GuiHostedController::DestroyNativeWindow(INativeWindow*)#"
auto hostedWindow = dynamic_cast<GuiHostedWindow*>(window);
CHECK_ERROR(hostedWindow, ERROR_MESSAGE_PREFIX L"The window is not created by GuiHostedController.");
vint index = createdWindows.IndexOf(hostedWindow);
CHECK_ERROR(index != -1, ERROR_MESSAGE_PREFIX L"The window has been destroyed.");
if (hostedWindow == enteringWindow) enteringWindow = nullptr;
if (hostedWindow == hoveringWindow) hoveringWindow = nullptr;
if (hostedWindow == lastFocusedWindow) enteringWindow = nullptr;
if (hostedWindow == capturingWindow)
{
capturingWindow->ReleaseCapture();
}
if (hostedWindow == wmWindow)
{
wmOperation = WindowManagerOperation::None;
wmWindow = nullptr;
nativeWindow->ReleaseCapture();
}
for (auto listener : hostedWindow->listeners)
{
listener->Destroying();
}
callbackService.InvokeNativeWindowDestroying(hostedWindow);
wmManager->UnregisterWindow(&hostedWindow->wmWindow);
createdWindows.RemoveAt(index);
UpdateHoveringWindow({});
#undef ERROR_MESSAGE_PREFIX
}
INativeWindow* GuiHostedController::GetMainWindow()
{
return mainWindow;
}
INativeWindow* GuiHostedController::GetWindow(NativePoint location)
{
auto wmWindow = wmManager->HitTest(location);
return wmWindow ? wmWindow->id : nullptr;
}
void GuiHostedController::SettingHostedWindowsBeforeRunning()
{
if (nativeWindow)
{
for (auto window : createdWindows)
{
if (window == mainWindow)
{
window->BecomeMainWindow();
}
else
{
window->BecomeNonMainWindow();
}
}
if (auto screen = nativeController->ScreenService()->GetScreen(nativeWindow))
{
auto screenBounds = screen->GetClientBounds();
auto windowSize = nativeWindow->GetBounds().GetSize();
nativeWindow->SetBounds({
{
screenBounds.Left() + (screenBounds.Width() - windowSize.x) / 2,
screenBounds.Top() + (screenBounds.Height() - windowSize.y) / 2
},
windowSize
});
}
wmManager->Start(&mainWindow->wmWindow);
}
}
void GuiHostedController::DestroyHostedWindowsAfterRunning()
{
if (nativeWindow)
{
if (wmManager->mainWindow)
{
wmManager->Stop();
}
// TODO: (enumerable) foreach:indexed(alterable(reversed))
for (vint i = createdWindows.Count() - 1; i >= 0; i--)
{
auto hostedWindow = createdWindows[i];
if (hostedWindow != mainWindow)
{
DestroyNativeWindow(hostedWindow.Obj());
}
}
if (mainWindow)
{
DestroyNativeWindow(mainWindow);
mainWindow = nullptr;
}
}
}
void GuiHostedController::Run(INativeWindow* window)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::GuiHostedController::Run(INativeWindow*)#"
CHECK_ERROR(!mainWindow, ERROR_MESSAGE_PREFIX L"This function has been called.");
auto hostedWindow = dynamic_cast<GuiHostedWindow*>(window);
CHECK_ERROR(hostedWindow, ERROR_MESSAGE_PREFIX L"The window is not created by GuiHostedController.");
mainWindow = hostedWindow;
SettingHostedWindowsBeforeRunning();
wmManager->needRefresh = true;
try
{
nativeController->WindowService()->Run(nativeWindow);
}
catch (const Exception& e)
{
(void)e;
DestroyHostedWindowsAfterRunning();
throw;
}
catch (const Error& e)
{
(void)e;
DestroyHostedWindowsAfterRunning();
throw;
}
catch (const unittest::UnitTestAssertError& e)
{
(void)e;
DestroyHostedWindowsAfterRunning();
throw;
}
catch (...)
{
DestroyHostedWindowsAfterRunning();
throw;
}
CHECK_ERROR((nativeWindow == nullptr) == (mainWindow == nullptr), ERROR_MESSAGE_PREFIX L"Hosted windows should have been destroyed if the native windows is destroyed.");
DestroyHostedWindowsAfterRunning();
#undef ERROR_MESSAGE_PREFIX
}
bool GuiHostedController::RunOneCycle()
{
return nativeController->WindowService()->RunOneCycle();
}
/***********************************************************************
GuiHostedController::IGuiHostedApplication
***********************************************************************/
INativeWindow* GuiHostedController::GetNativeWindowHost()
{
return nativeWindow;
}
/***********************************************************************
GuiHostedController
***********************************************************************/
GuiHostedController::GuiHostedController(INativeController* _nativeController)
: nativeController(_nativeController)
{
wmManager = this;
nativeController->CallbackService()->InstallListener(this);
}
GuiHostedController::~GuiHostedController()
{
}
IGuiHostedApplication* GuiHostedController::GetHostedApplication()
{
return this;
}
void GuiHostedController::Initialize()
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::GuiHostedController()::Initialize()#"
CHECK_ERROR(!nativeWindow, ERROR_MESSAGE_PREFIX L"Initialize() has been called");
CHECK_ERROR(!nativeWindowDestroyed, ERROR_MESSAGE_PREFIX L"Finalize() has been called.");
nativeController->CallbackService()->InstallListener(this);
nativeWindow = nativeController->WindowService()->CreateNativeWindow(INativeWindow::WindowMode::Normal);
nativeWindow->InstallListener(this);
#undef ERROR_MESSAGE_PREFIX
}
void GuiHostedController::Finalize()
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::GuiHostedController()::Finalize()#"
CHECK_ERROR(!nativeWindowDestroyed, ERROR_MESSAGE_PREFIX L"Finalize() has been called.");
if (nativeWindow)
{
nativeController->WindowService()->DestroyNativeWindow(nativeWindow);
}
nativeController->CallbackService()->UninstallListener(this);
nativeWindowDestroyed = true;
#undef ERROR_MESSAGE_PREFIX
}
void GuiHostedController::RequestRefresh()
{
wmManager->needRefresh = true;
}
/***********************************************************************
GuiHostedController::INativeController
***********************************************************************/
INativeCallbackService* GuiHostedController::CallbackService()
{
return &callbackService;
}
INativeResourceService* GuiHostedController::ResourceService()
{
return nativeController->ResourceService();
}
INativeAsyncService* GuiHostedController::AsyncService()
{
return this;
}
INativeClipboardService* GuiHostedController::ClipboardService()
{
return nativeController->ClipboardService();
}
INativeImageService* GuiHostedController::ImageService()
{
return nativeController->ImageService();
}
INativeInputService* GuiHostedController::InputService()
{
return nativeController->InputService();
}
INativeDialogService* GuiHostedController::DialogService()
{
// Use FakeDialogServiceBase
return nullptr;
}
WString GuiHostedController::GetExecutablePath()
{
return nativeController->GetExecutablePath();
}
INativeScreenService* GuiHostedController::ScreenService()
{
return this;
}
INativeWindowService* GuiHostedController::WindowService()
{
return this;
}
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\HOSTED\GUIHOSTEDGRAPHICS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace elements
{
/***********************************************************************
GuiHostedGraphicsResourceManager
***********************************************************************/
GuiHostedGraphicsResourceManager::GuiHostedGraphicsResourceManager(GuiHostedController* _hostedController, IGuiGraphicsResourceManager* _nativeManager)
: hostedController(_hostedController)
, nativeManager(_nativeManager)
{
CHECK_ERROR(
!hostedController->hostedResourceManager,
L"vl::presentation::elements::GuiHostedGraphicsResourceManager::GuiHostedGraphicsResourceManager(GuiHostedController*, IGuiGraphicsResourceManager*)#"
L"GuiHostedGraphicsResourceManager has been created for the same GuiHostedController");
hostedController->hostedResourceManager = this;
}
GuiHostedGraphicsResourceManager::~GuiHostedGraphicsResourceManager()
{
hostedController->hostedResourceManager = nullptr;
}
vint GuiHostedGraphicsResourceManager::RegisterElementType(const WString& elementTypeName)
{
return nativeManager->RegisterElementType(elementTypeName);
}
void GuiHostedGraphicsResourceManager::RegisterRendererFactory(vint elementType, Ptr<IGuiGraphicsRendererFactory> factory)
{
nativeManager->RegisterRendererFactory(elementType, factory);
}
IGuiGraphicsRendererFactory* GuiHostedGraphicsResourceManager::GetRendererFactory(vint elementType)
{
return nativeManager->GetRendererFactory(elementType);
}
IGuiGraphicsRenderTarget* GuiHostedGraphicsResourceManager::GetRenderTarget(INativeWindow* window)
{
return nativeManager->GetRenderTarget(hostedController->nativeWindow);
}
void GuiHostedGraphicsResourceManager::RecreateRenderTarget(INativeWindow* window)
{
}
void GuiHostedGraphicsResourceManager::ResizeRenderTarget(INativeWindow* window)
{
}
IGuiGraphicsLayoutProvider* GuiHostedGraphicsResourceManager::GetLayoutProvider()
{
return nativeManager->GetLayoutProvider();
}
}
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\HOSTED\GUIHOSTEDWINDOW.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
/***********************************************************************
GuiHostedWindow
***********************************************************************/
void GuiHostedWindow::BecomeMainWindow()
{
proxy = CreateMainHostedWindowProxy(this, controller->nativeWindow);
proxy->CheckAndSyncProperties();
}
void GuiHostedWindow::BecomeNonMainWindow()
{
proxy = CreateNonMainHostedWindowProxy(this, controller->nativeWindow);
proxy->CheckAndSyncProperties();
}
void GuiHostedWindow::BecomeFocusedWindow()
{
CHECK_ERROR(&wmWindow == controller->wmManager->activeWindow, L"vl::presentation::GuiHostedWindow::BecomeFocusedWindow()#Wrong timing to call this function.");
controller->nativeWindow->SetCaretPoint(windowCaretPoint + GetRenderingOffset());
}
void GuiHostedWindow::BecomeHoveringWindow()
{
CHECK_ERROR(this == controller->hoveringWindow, L"vl::presentation::GuiHostedWindow::BecomeFocusedWindow()#Wrong timing to call this function.");
controller->nativeWindow->SetWindowCursor(windowCursor);
}
GuiHostedWindow::GuiHostedWindow(GuiHostedController* _controller, INativeWindow::WindowMode _windowMode)
: GuiHostedWindowData(_controller, this, _windowMode)
{
wmWindow.bounds = { {0,0},{1,1} };
proxy = CreatePlaceholderHostedWindowProxy(this);
proxy->CheckAndSyncProperties();
}
GuiHostedWindow::~GuiHostedWindow()
{
for (auto listener : listeners)
{
listener->Destroyed();
}
}
bool GuiHostedWindow::IsActivelyRefreshing()
{
return false;
}
NativeSize GuiHostedWindow::GetRenderingOffset()
{
auto pos = wmWindow.bounds.LeftTop();
return { pos.x,pos.y };
}
Point GuiHostedWindow::Convert(NativePoint value)
{
return controller->nativeWindow->Convert(value);
}
NativePoint GuiHostedWindow::Convert(Point value)
{
return controller->nativeWindow->Convert(value);
}
Size GuiHostedWindow::Convert(NativeSize value)
{
return controller->nativeWindow->Convert(value);
}
NativeSize GuiHostedWindow::Convert(Size value)
{
return controller->nativeWindow->Convert(value);
}
Margin GuiHostedWindow::Convert(NativeMargin value)
{
return controller->nativeWindow->Convert(value);
}
NativeMargin GuiHostedWindow::Convert(Margin value)
{
return controller->nativeWindow->Convert(value);
}
NativeRect GuiHostedWindow::GetBounds()
{
return wmWindow.bounds;
}
void GuiHostedWindow::SetBounds(const NativeRect& bounds)
{
auto fixedBounds = proxy->FixBounds(bounds);
if (wmWindow.bounds == fixedBounds) return;
wmWindow.SetBounds(fixedBounds);
proxy->UpdateBounds();
}
NativeSize GuiHostedWindow::GetClientSize()
{
return GetBounds().GetSize();
}
void GuiHostedWindow::SetClientSize(NativeSize size)
{
SetBounds({ GetBounds().LeftTop(),size });
}
NativeRect GuiHostedWindow::GetClientBoundsInScreen()
{
return GetBounds();
}
WString GuiHostedWindow::GetTitle()
{
return windowTitle;
}
void GuiHostedWindow::SetTitle(const WString& title)
{
if (windowTitle == title) return;
windowTitle = title;
proxy->UpdateTitle();
}
INativeCursor* GuiHostedWindow::GetWindowCursor()
{
return windowCursor;
}
void GuiHostedWindow::SetWindowCursor(INativeCursor* cursor)
{
if (windowCursor == cursor) return;
windowCursor = cursor;
if (this == controller->hoveringWindow)
{
controller->nativeWindow->SetWindowCursor(windowCursor);
}
}
NativePoint GuiHostedWindow::GetCaretPoint()
{
return windowCaretPoint;
}
void GuiHostedWindow::SetCaretPoint(NativePoint point)
{
if (windowCaretPoint == point) return;
windowCaretPoint = point;
if (&wmWindow == controller->wmManager->activeWindow)
{
controller->nativeWindow->SetCaretPoint(windowCaretPoint + GetRenderingOffset());
}
}
INativeWindow* GuiHostedWindow::GetParent()
{
return wmWindow.parent ? wmWindow.parent->id : nullptr;
}
void GuiHostedWindow::SetParent(INativeWindow* parent)
{
auto hostedWindow = dynamic_cast<GuiHostedWindow*>(parent);
CHECK_ERROR(!parent || hostedWindow, L"vl::presentation::GuiHostedWindow::SetParent(INativeWindow*)#The window is not created by GuiHostedController.");
auto parentWindow = hostedWindow ? &hostedWindow->wmWindow : nullptr;
if (wmWindow.parent == parentWindow) return;
wmWindow.SetParent(parentWindow);
}
INativeWindow::WindowMode GuiHostedWindow::GetWindowMode()
{
return windowMode;
}
void GuiHostedWindow::EnableCustomFrameMode()
{
if (windowCustomFrameMode) return;
windowCustomFrameMode = true;
proxy->UpdateCustomFrameMode();
}
void GuiHostedWindow::DisableCustomFrameMode()
{
if (!windowCustomFrameMode) return;
windowCustomFrameMode = false;
proxy->UpdateCustomFrameMode();
}
bool GuiHostedWindow::IsCustomFrameModeEnabled()
{
return windowCustomFrameMode;
}
NativeMargin GuiHostedWindow::GetCustomFramePadding()
{
return controller->nativeWindow->GetCustomFramePadding();
}
Ptr<GuiImageData> GuiHostedWindow::GetIcon()
{
if (windowIcon) return windowIcon;
if (controller->nativeWindow)return controller->nativeWindow->GetIcon();
return nullptr;
}
void GuiHostedWindow::SetIcon(Ptr<GuiImageData> icon)
{
if (windowIcon == icon) return;
windowIcon = icon;
proxy->UpdateIcon();
}
INativeWindow::WindowSizeState GuiHostedWindow::GetSizeState()
{
return windowSizeState;
}
void GuiHostedWindow::Show()
{
EnableActivate();
proxy->Show();
}
void GuiHostedWindow::ShowDeactivated()
{
proxy->ShowDeactivated();
}
void GuiHostedWindow::ShowRestored()
{
proxy->ShowRestored();
}
void GuiHostedWindow::ShowMaximized()
{
proxy->ShowMaximized();
}
void GuiHostedWindow::ShowMinimized()
{
proxy->ShowMinimized();
}
void GuiHostedWindow::Hide(bool closeWindow)
{
if (!wmWindow.visible) return;
if (this != controller->mainWindow)
{
// when the main window is being closed
// the underlying INativeWindow will run the process
// so we don't need to worry about it here
bool cancel = false;
for (auto listener : listeners)
{
listener->BeforeClosing(cancel);
if (cancel) return;
}
for (auto listener : listeners)
{
listener->AfterClosing();
}
}
if (closeWindow)
{
proxy->Close();
}
else
{
proxy->Hide();
}
}
bool GuiHostedWindow::IsVisible()
{
return wmWindow.visible;
}
void GuiHostedWindow::Enable()
{
if (wmWindow.enabled) return;
wmWindow.SetEnabled(true);
proxy->UpdateEnabled();
}
void GuiHostedWindow::Disable()
{
if (!wmWindow.enabled) return;
wmWindow.SetEnabled(false);
proxy->UpdateEnabled();
}
bool GuiHostedWindow::IsEnabled()
{
return wmWindow.enabled;
}
void GuiHostedWindow::SetActivate()
{
EnableActivate();
proxy->SetFocus();
}
bool GuiHostedWindow::IsActivated()
{
return wmWindow.active;
}
bool GuiHostedWindow::IsRenderingAsActivated()
{
return wmWindow.renderedAsActive;
}
void GuiHostedWindow::ShowInTaskBar()
{
if (windowShowInTaskBar) return;
windowShowInTaskBar = true;
proxy->UpdateShowInTaskBar();
}
void GuiHostedWindow::HideInTaskBar()
{
if (!windowShowInTaskBar) return;
windowShowInTaskBar = false;
proxy->UpdateShowInTaskBar();
}
bool GuiHostedWindow::IsAppearedInTaskBar()
{
return windowShowInTaskBar;
}
void GuiHostedWindow::EnableActivate()
{
if (windowEnabledActivate) return;
windowEnabledActivate = true;
proxy->UpdateEnabledActivate();
}
void GuiHostedWindow::DisableActivate()
{
if (!windowEnabledActivate) return;
windowEnabledActivate = false;
proxy->UpdateEnabledActivate();
}
bool GuiHostedWindow::IsEnabledActivate()
{
return windowEnabledActivate;
}
bool GuiHostedWindow::RequireCapture()
{
if (controller->capturingWindow) return false;
controller->capturingWindow = this;
controller->nativeWindow->RequireCapture();
return true;
}
bool GuiHostedWindow::ReleaseCapture()
{
if (controller->capturingWindow != this) return false;
controller->capturingWindow = nullptr;
controller->nativeWindow->ReleaseCapture();
controller->UpdateEnteringWindow(controller->hoveringWindow);
return true;
}
bool GuiHostedWindow::IsCapturing()
{
return controller->capturingWindow == this;
}
bool GuiHostedWindow::GetMaximizedBox()
{
return windowMaximizedBox;
}
void GuiHostedWindow::SetMaximizedBox(bool visible)
{
if (windowMaximizedBox == visible) return;
windowMaximizedBox = visible;
proxy->UpdateMaximizedBox();
}
bool GuiHostedWindow::GetMinimizedBox()
{
return windowMinimizedBox;
}
void GuiHostedWindow::SetMinimizedBox(bool visible)
{
if (windowMinimizedBox == visible) return;
windowMinimizedBox = visible;
proxy->UpdateMinimizedBox();
}
bool GuiHostedWindow::GetBorder()
{
return windowBorder;
}
void GuiHostedWindow::SetBorder(bool visible)
{
if (windowBorder == visible) return;
windowBorder = visible;
proxy->UpdateBorderVisible();
}
bool GuiHostedWindow::GetSizeBox()
{
return windowSizeBox;
}
void GuiHostedWindow::SetSizeBox(bool visible)
{
if (windowSizeBox == visible) return;
windowSizeBox = visible;
proxy->UpdateSizeBox();
}
bool GuiHostedWindow::GetIconVisible()
{
return windowIconVisible;
}
void GuiHostedWindow::SetIconVisible(bool visible)
{
if (windowIconVisible == visible) return;
windowIconVisible = visible;
proxy->UpdateIconVisible();
}
bool GuiHostedWindow::GetTitleBar()
{
return windowTitleBar;
}
void GuiHostedWindow::SetTitleBar(bool visible)
{
if (windowTitleBar == visible) return;
windowTitleBar = visible;
proxy->UpdateTitleBar();
}
bool GuiHostedWindow::GetTopMost()
{
return wmWindow.topMost;
}
void GuiHostedWindow::SetTopMost(bool topmost)
{
if (wmWindow.topMost == topmost) return;
wmWindow.SetTopMost(topmost);
proxy->UpdateTopMost();
}
void GuiHostedWindow::SupressAlt()
{
controller->nativeWindow->SupressAlt();
}
bool GuiHostedWindow::InstallListener(INativeWindowListener* listener)
{
if (listeners.Contains(listener))
{
return false;
}
else
{
listeners.Add(listener);
return true;
}
}
bool GuiHostedWindow::UninstallListener(INativeWindowListener* listener)
{
if (listeners.Contains(listener))
{
listeners.Remove(listener);
return true;
}
else
{
return false;
}
}
void GuiHostedWindow::RedrawContent()
{
}
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\HOSTED\GUIHOSTEDWINDOWPROXY_MAIN.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
/***********************************************************************
GuiMainHostedWindowProxy
***********************************************************************/
class GuiMainHostedWindowProxy
: public Object
, public virtual IGuiHostedWindowProxy
{
protected:
GuiHostedWindowData* data = nullptr;
INativeWindow* nativeWindow = nullptr;
public:
GuiMainHostedWindowProxy(GuiHostedWindowData* _data, INativeWindow* _nativeWindow)
: data(_data)
, nativeWindow(_nativeWindow)
{
}
void CheckAndSyncProperties() override
{
for (auto listener : data->listeners)
{
listener->AssignFrameConfig(data->controller->WindowService()->GetMainWindowFrameConfig());
}
if (!data->wmWindow.visible)
{
data->wmWindow.Show();
}
data->wmWindow.SetBounds(FixBounds(data->wmWindow.bounds));
UpdateBounds();
UpdateTitle();
UpdateIcon();
UpdateEnabled();
UpdateTopMost();
UpdateMaximizedBox();
UpdateMinimizedBox();
UpdateBorderVisible();
UpdateSizeBox();
UpdateIconVisible();
UpdateTitleBar();
UpdateShowInTaskBar();
UpdateEnabledActivate();
UpdateCustomFrameMode();
}
/***********************************************************************
Visible Properties
***********************************************************************/
NativeRect FixBounds(const NativeRect& bounds) override
{
return { {},bounds.GetSize() };
}
void UpdateBounds() override
{
nativeWindow->SetClientSize(data->wmWindow.bounds.GetSize());
}
void UpdateTitle() override
{
nativeWindow->SetTitle(data->windowTitle);
}
void UpdateIcon() override
{
nativeWindow->SetIcon(data->windowIcon);
}
void UpdateEnabled() override
{
// Disabling the main window will not disable the native window
// otherwise the whole application is disabled
}
void UpdateTopMost() override
{
nativeWindow->SetTopMost(data->wmWindow.topMost);
}
/***********************************************************************
Border Properties
***********************************************************************/
void UpdateMaximizedBox() override
{
nativeWindow->SetMaximizedBox(data->windowMaximizedBox);
}
void UpdateMinimizedBox() override
{
nativeWindow->SetMinimizedBox(data->windowMinimizedBox);
}
void UpdateBorderVisible() override
{
nativeWindow->SetBorder(data->windowBorder);
}
void UpdateSizeBox() override
{
nativeWindow->SetSizeBox(data->windowSizeBox);
}
void UpdateIconVisible() override
{
nativeWindow->SetIconVisible(data->windowIconVisible);
}
void UpdateTitleBar() override
{
nativeWindow->SetTitleBar(data->windowTitleBar);
}
/***********************************************************************
Behavior Properties
***********************************************************************/
void UpdateShowInTaskBar() override
{
if (data->windowShowInTaskBar)
{
nativeWindow->ShowInTaskBar();
}
else
{
nativeWindow->HideInTaskBar();
}
}
void UpdateEnabledActivate() override
{
// In hosted mode, the native window is always activatable
}
void UpdateCustomFrameMode() override
{
if (data->windowCustomFrameMode)
{
nativeWindow->EnableCustomFrameMode();
}
else
{
nativeWindow->DisableCustomFrameMode();
}
}
/***********************************************************************
Show/Hide/Focus
In hosted mode, the main window is never closed.
Closing the main window causes the native window to be closed.
***********************************************************************/
void Show() override
{
data->wmWindow.Activate();
nativeWindow->Show();
}
void ShowDeactivated() override
{
data->wmWindow.Deactivate();
nativeWindow->ShowDeactivated();
}
void ShowRestored() override
{
nativeWindow->ShowRestored();
}
void ShowMaximized() override
{
nativeWindow->ShowMaximized();
}
void ShowMinimized() override
{
nativeWindow->ShowMinimized();
}
void Hide() override
{
nativeWindow->Hide(false);
}
void Close() override
{
nativeWindow->Hide(true);
}
void SetFocus() override
{
data->wmWindow.Activate();
nativeWindow->SetActivate();
}
};
/***********************************************************************
Helper
***********************************************************************/
Ptr<IGuiHostedWindowProxy> CreateMainHostedWindowProxy(GuiHostedWindowData* data, INativeWindow* nativeWindow)
{
return Ptr(new GuiMainHostedWindowProxy(data, nativeWindow));
}
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\HOSTED\GUIHOSTEDWINDOWPROXY_NONMAIN.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
/***********************************************************************
GuiNonMainHostedWindowProxy
***********************************************************************/
class GuiNonMainHostedWindowProxy
: public Object
, public virtual IGuiHostedWindowProxy
{
protected:
GuiHostedWindowData* data = nullptr;
INativeWindow* nativeWindow = nullptr;
bool calledAssignFrameConfig = false;
public:
GuiNonMainHostedWindowProxy(GuiHostedWindowData* _data, INativeWindow* _nativeWindow)
: data(_data)
, nativeWindow(_nativeWindow)
{
}
void EnsureNoSystemBorderWhenVisible()
{
if (!data->wmWindow.visible) return;
if (data->windowCustomFrameMode) return;
CHECK_ERROR(
!data->windowBorder && !data->windowSizeBox && !data->windowTitleBar,
L"vl::presentation::GuiNonMainHostedWindowProxy::EnsureNoSystemBorder()#"
L"For non main window in hosted mode, when custom frame mode is disabled"
L"the following window features should also be disabled: "
L"Border, SizeBox, TitleBar.");
}
void CallAssignFrameConfigIfNever()
{
if (calledAssignFrameConfig) return;
for (auto listener : data->listeners)
{
listener->AssignFrameConfig(data->controller->WindowService()->GetNonMainWindowFrameConfig());
calledAssignFrameConfig = true;
}
}
void CheckAndSyncProperties() override
{
data->windowMaximizedBox = false;
data->windowMinimizedBox = false;
CallAssignFrameConfigIfNever();
EnsureNoSystemBorderWhenVisible();
}
/***********************************************************************
Visible Properties
***********************************************************************/
NativeRect FixBounds(const NativeRect& bounds) override
{
auto w = bounds.Width().value;
auto h = bounds.Height().value;
if (w < 1) w = 1;
if (h < 1) h = 1;
return { bounds.LeftTop(),{{w},{h}} };
}
void UpdateBounds() override
{
}
void UpdateTitle() override
{
}
void UpdateIcon() override
{
}
void UpdateEnabled() override
{
}
void UpdateTopMost() override
{
}
/***********************************************************************
Border Properties
***********************************************************************/
void UpdateMaximizedBox() override
{
if (data->windowMaximizedBox)
{
data->windowMaximizedBox = false;
}
}
void UpdateMinimizedBox() override
{
if (data->windowMinimizedBox)
{
data->windowMinimizedBox = false;
}
}
void UpdateBorderVisible() override
{
EnsureNoSystemBorderWhenVisible();
}
void UpdateSizeBox() override
{
EnsureNoSystemBorderWhenVisible();
}
void UpdateIconVisible() override
{
}
void UpdateTitleBar() override
{
EnsureNoSystemBorderWhenVisible();
}
/***********************************************************************
Behavior Properties
***********************************************************************/
void UpdateShowInTaskBar() override
{
}
void UpdateEnabledActivate() override
{
}
void UpdateCustomFrameMode() override
{
EnsureNoSystemBorderWhenVisible();
}
/***********************************************************************
Show/Hide/Focus
Maximized and Minimized are not available
***********************************************************************/
void Show() override
{
CallAssignFrameConfigIfNever();
data->wmWindow.SetVisible(true);
data->wmWindow.Activate();
EnsureNoSystemBorderWhenVisible();
}
void ShowDeactivated() override
{
CallAssignFrameConfigIfNever();
data->wmWindow.SetVisible(true);
EnsureNoSystemBorderWhenVisible();
}
void ShowRestored() override
{
Show();
}
void ShowMaximized() override
{
Show();
}
void ShowMinimized() override
{
Show();
}
void Hide() override
{
data->wmWindow.SetVisible(false);
}
void Close() override
{
Hide();
}
void SetFocus() override
{
if (data->wmWindow.visible)
{
data->wmWindow.Activate();
nativeWindow->SetActivate();
}
}
};
/***********************************************************************
Helper
***********************************************************************/
Ptr<IGuiHostedWindowProxy> CreateNonMainHostedWindowProxy(GuiHostedWindowData* data, INativeWindow* nativeWindow)
{
return Ptr(new GuiNonMainHostedWindowProxy(data, nativeWindow));
}
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\HOSTED\GUIHOSTEDWINDOWPROXY_PLACEHOLDER.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
/***********************************************************************
GuiPlaceholderHostedWindowProxy
***********************************************************************/
class GuiPlaceholderHostedWindowProxy
: public Object
, public virtual IGuiHostedWindowProxy
{
protected:
GuiHostedWindowData* data = nullptr;
public:
GuiPlaceholderHostedWindowProxy(GuiHostedWindowData* _data)
: data(_data)
{
}
void CheckAndSyncProperties() override
{
}
/***********************************************************************
Visible Properties
***********************************************************************/
NativeRect FixBounds(const NativeRect& bounds) override
{
return bounds;
}
void UpdateBounds() override
{
}
void UpdateTitle() override
{
}
void UpdateIcon() override
{
}
void UpdateEnabled() override
{
}
void UpdateTopMost() override
{
}
/***********************************************************************
Border Properties
***********************************************************************/
void UpdateMaximizedBox() override
{
}
void UpdateMinimizedBox() override
{
}
void UpdateBorderVisible() override
{
}
void UpdateSizeBox() override
{
}
void UpdateIconVisible() override
{
}
void UpdateTitleBar() override
{
}
/***********************************************************************
Behavior Properties
***********************************************************************/
void UpdateShowInTaskBar() override
{
}
void UpdateEnabledActivate() override
{
}
void UpdateCustomFrameMode() override
{
}
/***********************************************************************
Show/Hide/Focus
***********************************************************************/
void Show() override
{
CHECK_FAIL(L"vl::presentation::GuiPlaceholderHostedWindowProxy::Show()#This function should not be called.");
}
void ShowDeactivated() override
{
CHECK_FAIL(L"vl::presentation::GuiPlaceholderHostedWindowProxy::ShowDeactivated()#This function should not be called.");
}
void ShowRestored() override
{
CHECK_FAIL(L"vl::presentation::GuiPlaceholderHostedWindowProxy::ShowRestored()#This function should not be called.");
}
void ShowMaximized() override
{
CHECK_FAIL(L"vl::presentation::GuiPlaceholderHostedWindowProxy::ShowMaximized()#This function should not be called.");
}
void ShowMinimized() override
{
CHECK_FAIL(L"vl::presentation::GuiPlaceholderHostedWindowProxy::ShowMinimized()#This function should not be called.");
}
void Hide() override
{
}
void Close() override
{
}
void SetFocus() override
{
}
};
/***********************************************************************
Helper
***********************************************************************/
Ptr<IGuiHostedWindowProxy> CreatePlaceholderHostedWindowProxy(GuiHostedWindowData* data)
{
return Ptr(new GuiPlaceholderHostedWindowProxy(data));
}
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\GUIREMOTECONTROLLER.CPP
***********************************************************************/
namespace vl::presentation
{
using namespace collections;
/***********************************************************************
GuiRemoteCursor
***********************************************************************/
class GuiRemoteCursor : public Object, public virtual INativeCursor
{
protected:
INativeCursor::SystemCursorType cursorType;
public:
GuiRemoteCursor(INativeCursor::SystemCursorType _cursorType) : cursorType(_cursorType) {}
bool IsSystemCursor() { return true; }
SystemCursorType GetSystemCursorType() { return cursorType; }
};
/***********************************************************************
GuiRemoteController::INativeResourceService
***********************************************************************/
INativeCursor* GuiRemoteController::GetSystemCursor(INativeCursor::SystemCursorType type)
{
vint index = cursors.Keys().IndexOf(type);
if (index == -1)
{
auto cursor = Ptr(new GuiRemoteCursor(type));
cursors.Add(type, cursor);
return cursor.Obj();
}
else
{
return cursors.Values()[index].Obj();
}
}
INativeCursor* GuiRemoteController::GetDefaultSystemCursor()
{
return GetSystemCursor(INativeCursor::SystemCursorType::Arrow);
}
FontProperties GuiRemoteController::GetDefaultFont()
{
return remoteFontConfig.defaultFont;
}
void GuiRemoteController::SetDefaultFont(const FontProperties& value)
{
remoteFontConfig.defaultFont = value;
}
void GuiRemoteController::EnumerateFonts(collections::List<WString>& fonts)
{
if (remoteFontConfig.supportedFonts)
{
CopyFrom(fonts, *remoteFontConfig.supportedFonts.Obj());
}
}
/***********************************************************************
GuiRemoteController::INativeInputService
***********************************************************************/
void GuiRemoteController::StartTimer()
{
timerEnabled = true;
}
void GuiRemoteController::StopTimer()
{
timerEnabled = false;
}
bool GuiRemoteController::IsTimerEnabled()
{
return timerEnabled;
}
bool GuiRemoteController::IsKeyPressing(VKEY code)
{
vint idIsKeyPressing = remoteMessages.RequestIOIsKeyPressing(code);
bool disconnected = false;
remoteMessages.Submit(disconnected);
if (disconnected) return false;
bool result = remoteMessages.RetrieveIOIsKeyPressing(idIsKeyPressing);
return result;
}
bool GuiRemoteController::IsKeyToggled(VKEY code)
{
vint idIsKeyToggled = remoteMessages.RequestIOIsKeyToggled(code);
bool disconnected = false;
remoteMessages.Submit(disconnected);
if (disconnected) return false;
bool result = remoteMessages.RetrieveIOIsKeyToggled(idIsKeyToggled);
return result;
}
void GuiRemoteController::EnsureKeyInitialized()
{
if (keyInitialized) return;
keyInitialized = true;
#define INITIALIZE_KEY_NAME(NAME, TEXT)\
keyNames.Add(VKEY::KEY_ ## NAME, WString::Unmanaged(TEXT));\
if (!keyCodes.Keys().Contains(WString::Unmanaged(TEXT))) keyCodes.Add(WString::Unmanaged(TEXT), VKEY::KEY_ ## NAME);\
GUI_DEFINE_KEYBOARD_WINDOWS_NAME(INITIALIZE_KEY_NAME)
#undef INITIALIZE_KEY_NAME
}
WString GuiRemoteController::GetKeyName(VKEY code)
{
EnsureKeyInitialized();
vint index = keyNames.Keys().IndexOf(code);
return index == -1 ? WString::Unmanaged(L"?") : keyNames.Values()[index];
}
VKEY GuiRemoteController::GetKey(const WString& name)
{
EnsureKeyInitialized();
vint index = keyCodes.Keys().IndexOf(name);
return index == -1 ? VKEY::KEY_UNKNOWN : keyCodes.Values()[index];
}
void GuiRemoteController::UpdateGlobalShortcutKey()
{
auto hotKeys = Ptr(new List<remoteprotocol::GlobalShortcutKey>);
for (auto [id, entry] : hotKeyIds)
{
remoteprotocol::GlobalShortcutKey key;
key.id = id;
key.ctrl = entry.get<0>();
key.shift = entry.get<1>();
key.alt = entry.get<2>();
key.code = entry.get<3>();
hotKeys->Add(key);
}
remoteMessages.RequestIOUpdateGlobalShortcutKey(hotKeys);
}
vint GuiRemoteController::RegisterGlobalShortcutKey(bool ctrl, bool shift, bool alt, VKEY key)
{
HotKeyEntry entry = { ctrl,shift,alt,key };
if (hotKeySet.Contains(entry)) return (vint)NativeGlobalShortcutKeyResult::Occupied;
vint id = ++usedHotKeys;
hotKeySet.Add(entry);
hotKeyIds.Add(id, entry);
UpdateGlobalShortcutKey();
bool disconnected = false;
remoteMessages.Submit(disconnected);
// there is no result from this request, assuming succeeded
return id;
}
bool GuiRemoteController::UnregisterGlobalShortcutKey(vint id)
{
vint index = hotKeyIds.Keys().IndexOf(id);
if (index == -1) return false;
auto entry = hotKeyIds.Values()[index];
hotKeyIds.Remove(id);
hotKeySet.Remove(entry);
UpdateGlobalShortcutKey();
bool disconnected = false;
remoteMessages.Submit(disconnected);
// there is no result from this request, assuming succeeded
return true;
}
/***********************************************************************
GuiRemoteController::INativeScreenService
***********************************************************************/
vint GuiRemoteController::GetScreenCount()
{
return 1;
}
INativeScreen* GuiRemoteController::GetScreen(vint index)
{
CHECK_ERROR(index == 0, L"vl::presentation::GuiRemoteController::GetScreen(vint)#Index out of range.");
return this;
}
INativeScreen* GuiRemoteController::GetScreen(INativeWindow* window)
{
return this;
}
/***********************************************************************
GuiHostedController::INativeScreen
***********************************************************************/
NativeRect GuiRemoteController::GetBounds()
{
return remoteScreenConfig.bounds;
}
NativeRect GuiRemoteController::GetClientBounds()
{
return remoteScreenConfig.clientBounds;
}
WString GuiRemoteController::GetName()
{
return WString::Unmanaged(L"GacUI Virtual Remote Screen");
}
bool GuiRemoteController::IsPrimary()
{
return true;
}
double GuiRemoteController::GetScalingX()
{
return remoteScreenConfig.scalingX;
}
double GuiRemoteController::GetScalingY()
{
return remoteScreenConfig.scalingY;
}
/***********************************************************************
GuiRemoteController::INativeWindowService
***********************************************************************/
const NativeWindowFrameConfig& GuiRemoteController::GetMainWindowFrameConfig()
{
return NativeWindowFrameConfig::Default;
}
const NativeWindowFrameConfig& GuiRemoteController::GetNonMainWindowFrameConfig()
{
return NativeWindowFrameConfig::Default;
}
INativeWindow* GuiRemoteController::CreateNativeWindow(INativeWindow::WindowMode windowMode)
{
CHECK_ERROR(!windowCreated, L"vl::presentation::GuiRemoteController::CreateNativeWindow(INativeWindow::WindowMode)#GuiHostedController is not supposed to call this function for twice.");
windowCreated = true;
remoteWindow.windowMode = windowMode;
callbackService.InvokeNativeWindowCreated(&remoteWindow);
return &remoteWindow;
}
void GuiRemoteController::DestroyNativeWindow(INativeWindow* window)
{
CHECK_ERROR(!windowDestroyed, L"vl::presentation::GuiRemoteController::CreateNativeWindow(INativeWindow::WindowMode)#GuiHostedController is not supposed to call this function for twice.");
windowDestroyed = true;
for (auto l : remoteWindow.listeners) l->Closed();
for (auto l : remoteWindow.listeners) l->Destroying();
callbackService.InvokeNativeWindowDestroying(&remoteWindow);
for (auto l : remoteWindow.listeners) l->Destroyed();
connectionStopped = true;
}
INativeWindow* GuiRemoteController::GetMainWindow()
{
return windowCreated && !windowDestroyed ? &remoteWindow : nullptr;
}
INativeWindow* GuiRemoteController::GetWindow(NativePoint location)
{
return GetMainWindow();
}
void GuiRemoteController::Run(INativeWindow* window)
{
CHECK_ERROR(window == &remoteWindow, L"vl::presentation::GuiRemoteController::Run(INativeWindow*)#GuiHostedController should call this function with the native window.");
applicationRunning = true;
window->Show();
while (RunOneCycle());
asyncService.ExecuteAsyncTasks();
applicationRunning = false;
}
bool GuiRemoteController::RunOneCycle()
{
if (!connectionStopped)
{
remoteProtocol->ProcessRemoteEvents();
bool disconnected = false;
remoteMessages.Submit(disconnected);
if (timerEnabled && !disconnected)
{
callbackService.InvokeGlobalTimer();
}
asyncService.ExecuteAsyncTasks();
}
return !connectionStopped;
}
/***********************************************************************
GuiRemoteController (events)
***********************************************************************/
void GuiRemoteController::OnControllerConnect()
{
UpdateGlobalShortcutKey();
vint idGetFontConfig = remoteMessages.RequestControllerGetFontConfig();
vint idGetScreenConfig = remoteMessages.RequestControllerGetScreenConfig();
bool disconnected = false;
remoteMessages.Submit(disconnected);
if (disconnected) return;
remoteFontConfig = remoteMessages.RetrieveControllerGetFontConfig(idGetFontConfig);
remoteScreenConfig = remoteMessages.RetrieveControllerGetScreenConfig(idGetScreenConfig);
remoteWindow.OnControllerConnect();
imageService.OnControllerConnect();
resourceManager->OnControllerConnect();
}
void GuiRemoteController::OnControllerDisconnect()
{
remoteWindow.OnControllerDisconnect();
imageService.OnControllerDisconnect();
resourceManager->OnControllerDisconnect();
}
void GuiRemoteController::OnControllerRequestExit()
{
remoteWindow.Hide(true);
}
void GuiRemoteController::OnControllerForceExit()
{
connectionForcedToStop = true;
remoteWindow.Hide(true);
}
void GuiRemoteController::OnControllerScreenUpdated(const remoteprotocol::ScreenConfig& arguments)
{
remoteScreenConfig = arguments;
remoteWindow.OnControllerScreenUpdated(arguments);
}
/***********************************************************************
GuiRemoteController
***********************************************************************/
GuiRemoteController::GuiRemoteController(IGuiRemoteProtocol* _remoteProtocol)
: remoteProtocol(_remoteProtocol)
, remoteMessages(this)
, remoteEvents(this)
, remoteWindow(this)
, imageService(this)
{
}
GuiRemoteController::~GuiRemoteController()
{
}
void GuiRemoteController::Initialize()
{
remoteProtocol->Initialize(&remoteEvents);
imageService.Initialize();
}
void GuiRemoteController::Finalize()
{
imageService.Finalize();
remoteMessages.RequestControllerConnectionStopped();
bool disconnected = false;
remoteMessages.Submit(disconnected);
// there is no result from this request, assuming succeeded
}
/***********************************************************************
GuiRemoteController (INativeController)
***********************************************************************/
INativeCallbackService* GuiRemoteController::CallbackService()
{
return &callbackService;
}
INativeResourceService* GuiRemoteController::ResourceService()
{
return this;
}
INativeAsyncService* GuiRemoteController::AsyncService()
{
return &asyncService;
}
INativeClipboardService* GuiRemoteController::ClipboardService()
{
CHECK_FAIL(L"Not Implemented!");
}
INativeImageService* GuiRemoteController::ImageService()
{
return &imageService;
}
INativeInputService* GuiRemoteController::InputService()
{
return this;
}
INativeDialogService* GuiRemoteController::DialogService()
{
// Use FakeDialogServiceBase
return nullptr;
}
WString GuiRemoteController::GetExecutablePath()
{
return remoteProtocol->GetExecutablePath();
}
INativeScreenService* GuiRemoteController::ScreenService()
{
return this;
}
INativeWindowService* GuiRemoteController::WindowService()
{
return this;
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\GUIREMOTECONTROLLERSETUP.CPP
***********************************************************************/
using namespace vl;
using namespace vl::presentation;
using namespace vl::presentation::elements;
/***********************************************************************
SetupRemoteNativeController
***********************************************************************/
extern void GuiApplicationMain();
int SetupRemoteNativeController(vl::presentation::IGuiRemoteProtocol* protocol)
{
GuiRemoteController remoteController(protocol);
GuiHostedController hostedController(&remoteController);
GuiRemoteGraphicsResourceManager remoteResourceManager(&remoteController, &hostedController);
GuiHostedGraphicsResourceManager hostedResourceManager(&hostedController, &remoteResourceManager);
SetNativeController(&hostedController);
SetGuiGraphicsResourceManager(&hostedResourceManager);
SetHostedApplication(hostedController.GetHostedApplication());
remoteController.Initialize();
remoteResourceManager.Initialize();
hostedController.Initialize();
GuiApplicationMain();
hostedController.Finalize();
remoteResourceManager.Finalize();
remoteController.Finalize();
SetHostedApplication(nullptr);
SetGuiGraphicsResourceManager(nullptr);
SetNativeController(nullptr);
return 0;
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\GUIREMOTEEVENTS.CPP
***********************************************************************/
namespace vl::presentation
{
/***********************************************************************
GuiRemoteMessages
***********************************************************************/
GuiRemoteMessages::GuiRemoteMessages(GuiRemoteController* _remote)
: remote(_remote)
{
}
GuiRemoteMessages::~GuiRemoteMessages()
{
}
void GuiRemoteMessages::Submit(bool& disconnected)
{
remote->remoteProtocol->Submit(disconnected);
}
/***********************************************************************
GuiRemoteMessages (messages)
***********************************************************************/
#define MESSAGE_NOREQ_NORES(NAME, REQUEST, RESPONSE)\
void GuiRemoteMessages::Request ## NAME()\
{\
remote->remoteProtocol->Request ## NAME();\
}\
#define MESSAGE_NOREQ_RES(NAME, REQUEST, RESPONSE)\
vint GuiRemoteMessages::Request ## NAME()\
{\
vint requestId = ++id;\
remote->remoteProtocol->Request ## NAME(requestId);\
return requestId;\
}\
#define MESSAGE_REQ_NORES(NAME, REQUEST, RESPONSE)\
void GuiRemoteMessages::Request ## NAME(const REQUEST& arguments)\
{\
remote->remoteProtocol->Request ## NAME(arguments);\
}\
#define MESSAGE_REQ_RES(NAME, REQUEST, RESPONSE)\
vint GuiRemoteMessages::Request ## NAME(const REQUEST& arguments)\
{\
vint requestId = ++id;\
remote->remoteProtocol->Request ## NAME(requestId, arguments);\
return requestId;\
}\
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, ...) MESSAGE_ ## REQTAG ## _ ## RESTAG(NAME, REQUEST, RESPONSE)
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
#undef MESSAGE_HANDLER
#undef MESSAGE_REQ_RES
#undef MESSAGE_REQ_NORES
#undef MESSAGE_NOREQ_RES
#undef MESSAGE_NOREQ_NORES
#define MESSAGE_NORES(NAME, RESPONSE)
#define MESSAGE_RES(NAME, RESPONSE)\
void GuiRemoteMessages::Respond ## NAME(vint id, const RESPONSE& arguments)\
{\
response ## NAME.Add(id, arguments);\
}\
RESPONSE GuiRemoteMessages::Retrieve ## NAME(vint id)\
{\
RESPONSE response = response ## NAME[id];\
response ## NAME.Remove(id);\
return response;\
}\
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, ...) MESSAGE_ ## RESTAG(NAME, RESPONSE)
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
#undef MESSAGE_HANDLER
#undef MESSAGE_RES
#undef MESSAGE_NORES
/***********************************************************************
GuiRemoteEvents
***********************************************************************/
GuiRemoteEvents::GuiRemoteEvents(GuiRemoteController* _remote)
: remote(_remote)
{
}
GuiRemoteEvents::~GuiRemoteEvents()
{
}
/***********************************************************************
GuiRemoteEvents (messages)
***********************************************************************/
#define MESSAGE_NORES(NAME, RESPONSE)
#define MESSAGE_RES(NAME, RESPONSE)\
void GuiRemoteEvents::Respond ## NAME(vint id, const RESPONSE& arguments)\
{\
remote->remoteMessages.Respond ## NAME(id, arguments);\
}\
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, ...) MESSAGE_ ## RESTAG(NAME, RESPONSE)
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
#undef MESSAGE_HANDLER
#undef MESSAGE_RES
#undef MESSAGE_NORES
/***********************************************************************
GuiRemoteEvents (events)
***********************************************************************/
void GuiRemoteEvents::OnControllerConnect()
{
remote->remoteMessages.RequestControllerConnectionEstablished();
remote->OnControllerConnect();
bool disconnected = false;
remote->remoteMessages.Submit(disconnected);
// there is no result from this request, assuming succeeded
// if disconnected, OnControllerDisconnect will be called
}
void GuiRemoteEvents::OnControllerDisconnect()
{
remote->OnControllerDisconnect();
}
void GuiRemoteEvents::OnControllerRequestExit()
{
remote->OnControllerRequestExit();
}
void GuiRemoteEvents::OnControllerForceExit()
{
remote->OnControllerForceExit();
}
void GuiRemoteEvents::OnControllerScreenUpdated(const remoteprotocol::ScreenConfig& arguments)
{
remote->OnControllerScreenUpdated(arguments);
}
void GuiRemoteEvents::OnWindowBoundsUpdated(const remoteprotocol::WindowSizingConfig& arguments)
{
remote->remoteWindow.OnWindowBoundsUpdated(arguments);
}
void GuiRemoteEvents::OnWindowActivatedUpdated(const bool& arguments)
{
remote->remoteWindow.OnWindowActivatedUpdated(arguments);
}
void GuiRemoteEvents::OnIOGlobalShortcutKey(const vint& arguments)
{
remote->callbackService.InvokeGlobalShortcutKeyActivated(arguments);
}
void GuiRemoteEvents::OnIOButtonDown(const remoteprotocol::IOMouseInfoWithButton& arguments)
{
switch (arguments.button)
{
case remoteprotocol::IOMouseButton::Left:
for (auto l : remote->remoteWindow.listeners) l->LeftButtonDown(arguments.info);
break;
case remoteprotocol::IOMouseButton::Middle:
for (auto l : remote->remoteWindow.listeners) l->MiddleButtonDown(arguments.info);
break;
case remoteprotocol::IOMouseButton::Right:
for (auto l : remote->remoteWindow.listeners) l->RightButtonDown(arguments.info);
break;
default:
CHECK_FAIL(L"vl::presentation::GuiRemoteEvents::OnIOButtonDown(const IOMouseInfoWithButton&)#Unrecognized button.");
}
}
void GuiRemoteEvents::OnIOButtonDoubleClick(const remoteprotocol::IOMouseInfoWithButton& arguments)
{
switch (arguments.button)
{
case remoteprotocol::IOMouseButton::Left:
for (auto l : remote->remoteWindow.listeners) l->LeftButtonDoubleClick(arguments.info);
break;
case remoteprotocol::IOMouseButton::Middle:
for (auto l : remote->remoteWindow.listeners) l->MiddleButtonDoubleClick(arguments.info);
break;
case remoteprotocol::IOMouseButton::Right:
for (auto l : remote->remoteWindow.listeners) l->RightButtonDoubleClick(arguments.info);
break;
default:
CHECK_FAIL(L"vl::presentation::GuiRemoteEvents::OnIOButtonDoubleClick(const IOMouseInfoWithButton&)#Unrecognized button.");
}
}
void GuiRemoteEvents::OnIOButtonUp(const remoteprotocol::IOMouseInfoWithButton& arguments)
{
switch (arguments.button)
{
case remoteprotocol::IOMouseButton::Left:
for (auto l : remote->remoteWindow.listeners) l->LeftButtonUp(arguments.info);
break;
case remoteprotocol::IOMouseButton::Middle:
for (auto l : remote->remoteWindow.listeners) l->MiddleButtonUp(arguments.info);
break;
case remoteprotocol::IOMouseButton::Right:
for (auto l : remote->remoteWindow.listeners) l->RightButtonUp(arguments.info);
break;
default:
CHECK_FAIL(L"vl::presentation::GuiRemoteEvents::OnIOButtonUp(const IOMouseInfoWithButton&)#Unrecognized button.");
}
}
void GuiRemoteEvents::OnIOHWheel(const NativeWindowMouseInfo& arguments)
{
for (auto l : remote->remoteWindow.listeners) l->HorizontalWheel(arguments);
}
void GuiRemoteEvents::OnIOVWheel(const NativeWindowMouseInfo& arguments)
{
for (auto l : remote->remoteWindow.listeners) l->VerticalWheel(arguments);
}
void GuiRemoteEvents::OnIOMouseMoving(const NativeWindowMouseInfo& arguments)
{
for (auto l : remote->remoteWindow.listeners) l->MouseMoving(arguments);
}
void GuiRemoteEvents::OnIOMouseEntered()
{
for (auto l : remote->remoteWindow.listeners) l->MouseEntered();
}
void GuiRemoteEvents::OnIOMouseLeaved()
{
for (auto l : remote->remoteWindow.listeners) l->MouseLeaved();
}
void GuiRemoteEvents::OnIOKeyDown(const NativeWindowKeyInfo& arguments)
{
for (auto l : remote->remoteWindow.listeners) l->KeyDown(arguments);
}
void GuiRemoteEvents::OnIOKeyUp(const NativeWindowKeyInfo& arguments)
{
for (auto l : remote->remoteWindow.listeners) l->KeyUp(arguments);
}
void GuiRemoteEvents::OnIOChar(const NativeWindowCharInfo& arguments)
{
for (auto l : remote->remoteWindow.listeners) l->Char(arguments);
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\GUIREMOTEGRAPHICS.CPP
***********************************************************************/
namespace vl::presentation::elements
{
using namespace collections;
using namespace compositions;
/***********************************************************************
GuiRemoteGraphicsRenderTarget
***********************************************************************/
GuiRemoteGraphicsRenderTarget::HitTestResult GuiRemoteGraphicsRenderTarget::GetHitTestResultFromGenerator(reflection::DescriptableObject* generator)
{
if (auto composition = dynamic_cast<GuiGraphicsComposition*>(generator))
{
auto hitTestResult = composition->GetAssociatedHitTestResult();
if (hitTestResult != INativeWindowListener::NoDecision)
{
if (auto graphicsHost = composition->GetRelatedGraphicsHost())
{
if (auto nativeWindow = graphicsHost->GetNativeWindow())
{
if (nativeWindow == GetCurrentController()->WindowService()->GetMainWindow())
{
return hitTestResult;
}
}
}
}
}
return INativeWindowListener::NoDecision;
}
Nullable<GuiRemoteGraphicsRenderTarget::SystemCursorType> GuiRemoteGraphicsRenderTarget::GetCursorFromGenerator(reflection::DescriptableObject* generator)
{
if (auto composition = dynamic_cast<GuiGraphicsComposition*>(generator))
{
if (auto cursor = composition->GetAssociatedCursor())
{
if (auto graphicsHost = composition->GetRelatedGraphicsHost())
{
if (auto nativeWindow = graphicsHost->GetNativeWindow())
{
if (nativeWindow == GetCurrentController()->WindowService()->GetMainWindow())
{
return cursor->GetSystemCursorType();
}
}
}
}
}
return {};
}
void GuiRemoteGraphicsRenderTarget::StartRenderingOnNativeWindow()
{
CHECK_ERROR(hitTestResults.Count() == 0, L"vl::presentation::elements::GuiRemoteGraphicsRenderTarget::StartRenderingOnNativeWindow()#Internal error: hit test result stack is not cleared.");
canvasSize = remote->remoteWindow.GetClientSize();
clipperValidArea = GetClipper();
renderingBatchId++;
if (destroyedRenderers.Count() > 0)
{
auto ids = Ptr(new List<vint>);
CopyFrom(*ids.Obj(), destroyedRenderers);
destroyedRenderers.Clear();
remote->remoteMessages.RequestRendererDestroyed(ids);
}
if (createdRenderers.Count() > 0)
{
auto ids = Ptr(new List<remoteprotocol::RendererCreation>);
for (auto id : createdRenderers)
{
ids->Add({ id,renderers[id]->GetRendererType() });
}
createdRenderers.Clear();
remote->remoteMessages.RequestRendererCreated(ids);
}
for (auto [id, renderer] : renderers)
{
if (renderer->IsUpdated())
{
renderer->SendUpdateElementMessages(false);
if (renderer->NeedUpdateMinSizeFromCache())
{
if (!renderersAskingForCache.Contains(renderer))
{
renderersAskingForCache.Add(renderer);
}
}
renderer->ResetUpdated();
}
}
{
remoteprotocol::ElementBeginRendering arguments;
arguments.frameId = ++usedFrameIds;
remote->remoteMessages.RequestRendererBeginRendering(arguments);
}
}
RenderTargetFailure GuiRemoteGraphicsRenderTarget::StopRenderingOnNativeWindow()
{
CHECK_ERROR(hitTestResults.Count() == 0, L"vl::presentation::elements::GuiRemoteGraphicsRenderTarget::StartRenderingOnNativeWindow()#Internal error: hit test result stack is not cleared.");
vint idRendering = remote->remoteMessages.RequestRendererEndRendering();
bool disconnected = false;
remote->remoteMessages.Submit(disconnected);
if (disconnected) return RenderTargetFailure::None;
auto measuring = remote->remoteMessages.RetrieveRendererEndRendering(idRendering);
bool minSizeChanged = false;
if (measuring.fontHeights)
{
for (auto&& fontHeight : *measuring.fontHeights.Obj())
{
auto key = Tuple(fontHeight.fontFamily, fontHeight.fontSize);
if (!fontHeights.Keys().Contains(key))
{
fontHeights.Add(key, fontHeight.height);
}
}
// TODO: (enumerable) foreach:indexed(alterable(reversed))
for (vint i = renderersAskingForCache.Count() - 1; i >= 0; i--)
{
auto renderer = renderersAskingForCache[i];
auto oldMinSize = renderer->GetRenderer()->GetMinSize();
renderer->TryFetchMinSizeFromCache();
if (renderer->IsRenderedInLastBatch() && oldMinSize != renderer->GetRenderer()->GetMinSize())
{
minSizeChanged = true;
}
if (!renderer->NeedUpdateMinSizeFromCache())
{
renderersAskingForCache.RemoveAt(i);
}
}
}
if (measuring.createdImages)
{
for (auto&& imageMetadata : *measuring.createdImages.Obj())
{
auto image = remote->imageService.GetImage(imageMetadata.id);
image->UpdateFromImageMetadata(imageMetadata);
}
}
if (measuring.minSizes)
{
for (auto&& minSize : *measuring.minSizes.Obj())
{
vint index = renderers.Keys().IndexOf(minSize.id);
if (index != -1)
{
auto renderer = renderers.Values()[index];
auto oldMinSize = renderer->GetRenderer()->GetMinSize();
renderer->UpdateMinSize(minSize.minSize);
if (renderer->IsRenderedInLastBatch() && oldMinSize != renderer->GetRenderer()->GetMinSize())
{
minSizeChanged = true;
}
}
}
}
if (minSizeChanged)
{
hostedController->RequestRefresh();
}
if (canvasSize == remote->remoteWindow.GetClientSize())
{
return RenderTargetFailure::None;
}
else
{
return RenderTargetFailure::ResizeWhileRendering;
}
}
Size GuiRemoteGraphicsRenderTarget::GetCanvasSize()
{
return remote->remoteWindow.Convert(canvasSize);
}
void GuiRemoteGraphicsRenderTarget::AfterPushedClipper(Rect clipper, Rect validArea, reflection::DescriptableObject* generator)
{
clipperValidArea = validArea;
auto hitTestResult = GetHitTestResultFromGenerator(generator);
auto cursor = GetCursorFromGenerator(generator);
remoteprotocol::ElementBoundary arguments;
if (hitTestResult != INativeWindowListener::NoDecision)
{
if (hitTestResults.Count() == 0 || hitTestResults[hitTestResults.Count() - 1] != hitTestResult)
{
arguments.hitTestResult = hitTestResult;
}
hitTestResults.Add(hitTestResult);
}
if (cursor)
{
if (cursors.Count() == 0 || cursors[cursors.Count() - 1] != cursor.Value())
{
arguments.cursor = cursor.Value();
}
cursors.Add(cursor.Value());
}
if (arguments.hitTestResult || arguments.cursor)
{
// GetHitTestResultFromGenerator or GetCursorFromGenerator ensures generator must be a composition
auto composition = dynamic_cast<GuiGraphicsComposition*>(generator);
if (composition->remoteId == -1)
{
composition->remoteId = ++usedCompositionIds;
}
arguments.id = composition->remoteId;
arguments.bounds = clipper;
arguments.areaClippedBySelf = validArea;
remote->remoteMessages.RequestRendererBeginBoundary(arguments);
}
}
void GuiRemoteGraphicsRenderTarget::AfterPushedClipperAndBecameInvalid(Rect clipper, reflection::DescriptableObject* generator)
{
clipperValidArea.Reset();
}
void GuiRemoteGraphicsRenderTarget::AfterPoppedClipperAndBecameValid(Rect validArea, bool clipperExists, reflection::DescriptableObject* generator)
{
clipperValidArea = validArea;
}
void GuiRemoteGraphicsRenderTarget::AfterPoppedClipper(Rect validArea, bool clipperExists, reflection::DescriptableObject* generator)
{
clipperValidArea = validArea;
auto hitTestResult = GetHitTestResultFromGenerator(generator);
auto cursor = GetCursorFromGenerator(generator);
bool needEndBoundary = false;
if (hitTestResult != INativeWindowListener::NoDecision)
{
hitTestResults.RemoveAt(hitTestResults.Count() - 1);
if (hitTestResults.Count() == 0 || hitTestResults[hitTestResults.Count() - 1] != hitTestResult)
{
needEndBoundary = true;
}
}
if (cursor)
{
cursors.RemoveAt(cursors.Count() - 1);
if (cursors.Count() == 0 || cursors[cursors.Count() - 1] != cursor.Value())
{
needEndBoundary = true;
}
}
if (needEndBoundary)
{
remote->remoteMessages.RequestRendererEndBoundary();
}
}
GuiRemoteGraphicsRenderTarget::GuiRemoteGraphicsRenderTarget(GuiRemoteController* _remote, GuiHostedController* _hostedController)
: remote(_remote)
, hostedController(_hostedController)
{
}
GuiRemoteGraphicsRenderTarget::~GuiRemoteGraphicsRenderTarget()
{
}
void GuiRemoteGraphicsRenderTarget::OnControllerConnect()
{
fontHeights.Clear();
renderersAskingForCache.Clear();
if (renderers.Count() > 0)
{
{
auto ids = Ptr(new List<remoteprotocol::RendererCreation>);
for (auto renderer : renderers.Values())
{
ids->Add({ renderer->GetID(),renderer->GetRendererType() });
renderer->NotifyMinSizeCacheInvalidated();
}
createdRenderers.Clear();
remote->remoteMessages.RequestRendererCreated(ids);
}
for (auto renderer : renderers.Values())
{
renderer->SendUpdateElementMessages(true);
if (renderer->NeedUpdateMinSizeFromCache())
{
renderersAskingForCache.Add(renderer);
}
renderer->ResetUpdated();
}
}
}
void GuiRemoteGraphicsRenderTarget::OnControllerDisconnect()
{
}
GuiRemoteMessages& GuiRemoteGraphicsRenderTarget::GetRemoteMessages()
{
return remote->remoteMessages;
}
vint GuiRemoteGraphicsRenderTarget::AllocateNewElementId()
{
return ++usedElementIds;
}
void GuiRemoteGraphicsRenderTarget::RegisterRenderer(elements_remoteprotocol::IGuiRemoteProtocolElementRender* renderer)
{
vint id = renderer->GetID();
if (!createdRenderers.Contains(id))
{
renderers.Add(id, renderer);
createdRenderers.Add(id);
}
}
void GuiRemoteGraphicsRenderTarget::UnregisterRenderer(elements_remoteprotocol::IGuiRemoteProtocolElementRender* renderer)
{
vint id = renderer->GetID();
renderers.Remove(id);
renderersAskingForCache.Remove(renderer);
{
vint index = createdRenderers.IndexOf(id);
if (index == -1)
{
if (!destroyedRenderers.Contains(id))
{
destroyedRenderers.Add(id);
}
}
else
{
createdRenderers.RemoveAt(index);
}
}
}
Rect GuiRemoteGraphicsRenderTarget::GetClipperValidArea()
{
return clipperValidArea.Value();
}
/***********************************************************************
GuiRemoteGraphicsResourceManager
***********************************************************************/
GuiRemoteGraphicsResourceManager::GuiRemoteGraphicsResourceManager(GuiRemoteController* _remote, GuiHostedController* _hostedController)
: remote(_remote)
, renderTarget(_remote, _hostedController)
, hostedController(_hostedController)
{
remote->resourceManager = this;
}
GuiRemoteGraphicsResourceManager::~GuiRemoteGraphicsResourceManager()
{
}
void GuiRemoteGraphicsResourceManager::Initialize()
{
elements_remoteprotocol::GuiFocusRectangleElementRenderer::Register();
elements_remoteprotocol::GuiSolidBorderElementRenderer::Register();
elements_remoteprotocol::Gui3DBorderElementRenderer::Register();
elements_remoteprotocol::Gui3DSplitterElementRenderer::Register();
elements_remoteprotocol::GuiSolidBackgroundElementRenderer::Register();
elements_remoteprotocol::GuiGradientBackgroundElementRenderer::Register();
elements_remoteprotocol::GuiInnerShadowElementRenderer::Register();
elements_remoteprotocol::GuiSolidLabelElementRenderer::Register();
elements_remoteprotocol::GuiImageFrameElementRenderer::Register();
elements_remoteprotocol::GuiPolygonElementRenderer::Register();
elements_remoteprotocol::GuiColorizedTextElementRenderer::Register();
elements::GuiDocumentElement::GuiDocumentElementRenderer::Register();
}
void GuiRemoteGraphicsResourceManager::Finalize()
{
}
void GuiRemoteGraphicsResourceManager::OnControllerConnect()
{
renderTarget.OnControllerConnect();
hostedController->RequestRefresh();
}
void GuiRemoteGraphicsResourceManager::OnControllerDisconnect()
{
renderTarget.OnControllerDisconnect();
}
IGuiGraphicsRenderTarget* GuiRemoteGraphicsResourceManager::GetRenderTarget(INativeWindow* window)
{
CHECK_ERROR(window == &remote->remoteWindow, L"vl::presentation::elements::GuiRemoteGraphicsResourceManager::GetRenderTarget(INativeWindow*)#GuiHostedController should call this function with the native window.");
return &renderTarget;
}
void GuiRemoteGraphicsResourceManager::RecreateRenderTarget(INativeWindow* window)
{
}
void GuiRemoteGraphicsResourceManager::ResizeRenderTarget(INativeWindow* window)
{
}
IGuiGraphicsLayoutProvider* GuiRemoteGraphicsResourceManager::GetLayoutProvider()
{
CHECK_FAIL(L"Not Implemented!");
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\GUIREMOTEGRAPHICS_BASICELEMENTS.CPP
***********************************************************************/
namespace vl::presentation::elements_remoteprotocol
{
using namespace collections;
using namespace remoteprotocol;
/***********************************************************************
GuiSolidBorderElementRenderer
***********************************************************************/
#define RENDERER_TEMPLATE_HEADER template<typename TElement, typename TRenderer, remoteprotocol::RendererType _RendererType>
#define RENDERER_CLASS_TYPE GuiRemoteProtocolElementRenderer<TElement, TRenderer, _RendererType>
RENDERER_TEMPLATE_HEADER
void RENDERER_CLASS_TYPE::InitializeInternal()
{
}
RENDERER_TEMPLATE_HEADER
void RENDERER_CLASS_TYPE::FinalizeInternal()
{
if (this->renderTarget && id != -1)
{
this->renderTarget->UnregisterRenderer(this);
id = -1;
}
}
RENDERER_TEMPLATE_HEADER
void RENDERER_CLASS_TYPE::RenderTargetChangedInternal(GuiRemoteGraphicsRenderTarget* oldRenderTarget, GuiRemoteGraphicsRenderTarget* newRenderTarget)
{
if (oldRenderTarget == newRenderTarget) return;
if (oldRenderTarget && id != -1)
{
oldRenderTarget->UnregisterRenderer(this);
id = -1;
}
if (newRenderTarget)
{
id = newRenderTarget->AllocateNewElementId();
newRenderTarget->RegisterRenderer(this);
updated = true;
renderTargetChanged = true;
}
}
RENDERER_TEMPLATE_HEADER
IGuiGraphicsRenderer* RENDERER_CLASS_TYPE::GetRenderer()
{
return this;
}
RENDERER_TEMPLATE_HEADER
vint RENDERER_CLASS_TYPE::GetID()
{
return id;
}
RENDERER_TEMPLATE_HEADER
remoteprotocol::RendererType RENDERER_CLASS_TYPE::GetRendererType()
{
return _RendererType;
}
RENDERER_TEMPLATE_HEADER
bool RENDERER_CLASS_TYPE::IsUpdated()
{
return updated;
}
RENDERER_TEMPLATE_HEADER
void RENDERER_CLASS_TYPE::ResetUpdated()
{
updated = false;
renderTargetChanged = false;
}
RENDERER_TEMPLATE_HEADER
bool RENDERER_CLASS_TYPE::IsRenderedInLastBatch()
{
return this->renderTarget && this->renderTarget->renderingBatchId == renderingBatchId;
}
RENDERER_TEMPLATE_HEADER
bool RENDERER_CLASS_TYPE::NeedUpdateMinSizeFromCache()
{
return false;
}
RENDERER_TEMPLATE_HEADER
void RENDERER_CLASS_TYPE::TryFetchMinSizeFromCache()
{
CHECK_FAIL(L"vl::presentation::elements_remoteprotocol::GuiRemoteProtocolElementRenderer<TElement, TRenderer, RendererType>::TryUpdateFromCache()#This function should not be called.");
}
RENDERER_TEMPLATE_HEADER
void RENDERER_CLASS_TYPE::UpdateMinSize(Size size)
{
CHECK_FAIL(L"vl::presentation::elements_remoteprotocol::GuiRemoteProtocolElementRenderer<TElement, TRenderer, RendererType>::UpdateMinSize(Size)#This function should not be called.");
}
RENDERER_TEMPLATE_HEADER
void RENDERER_CLASS_TYPE::NotifyMinSizeCacheInvalidated()
{
}
RENDERER_TEMPLATE_HEADER
void RENDERER_CLASS_TYPE::Render(Rect bounds)
{
remoteprotocol::ElementRendering arguments;
arguments.id = id;
arguments.bounds = bounds;
arguments.areaClippedByParent = this->renderTarget->GetClipperValidArea();
this->renderTarget->GetRemoteMessages().RequestRendererRenderElement(arguments);
renderingBatchId = this->renderTarget->renderingBatchId;
}
RENDERER_TEMPLATE_HEADER
void RENDERER_CLASS_TYPE::OnElementStateChanged()
{
updated = true;
}
#undef RENDERER_CLASS_TYPE
#undef RENDERER_TEMPLATE_HEADER
/***********************************************************************
GuiSolidBorderElementRenderer
***********************************************************************/
GuiFocusRectangleElementRenderer::GuiFocusRectangleElementRenderer()
{
}
bool GuiFocusRectangleElementRenderer::IsUpdated()
{
// there is no properties for this element
return false;
}
void GuiFocusRectangleElementRenderer::ResetUpdated()
{
// nothing to update
}
void GuiFocusRectangleElementRenderer::OnElementStateChanged()
{
// nothing to update
}
void GuiFocusRectangleElementRenderer::SendUpdateElementMessages(bool fullContent)
{
// nothing to update
}
/***********************************************************************
GuiSolidBorderElementRenderer
***********************************************************************/
GuiSolidBorderElementRenderer::GuiSolidBorderElementRenderer()
{
}
void GuiSolidBorderElementRenderer::SendUpdateElementMessages(bool fullContent)
{
ElementDesc_SolidBorder arguments;
arguments.id = id;
arguments.borderColor = element->GetColor();
arguments.shape = element->GetShape();
renderTarget->GetRemoteMessages().RequestRendererUpdateElement_SolidBorder(arguments);
}
/***********************************************************************
Gui3DBorderElementRenderer
***********************************************************************/
Gui3DBorderElementRenderer::Gui3DBorderElementRenderer()
{
}
void Gui3DBorderElementRenderer::SendUpdateElementMessages(bool fullContent)
{
ElementDesc_SinkBorder arguments;
arguments.id = id;
arguments.leftTopColor = element->GetColor1();
arguments.rightBottomColor = element->GetColor2();
renderTarget->GetRemoteMessages().RequestRendererUpdateElement_SinkBorder(arguments);
}
/***********************************************************************
Gui3DSplitterElementRenderer
***********************************************************************/
Gui3DSplitterElementRenderer::Gui3DSplitterElementRenderer()
{
}
void Gui3DSplitterElementRenderer::SendUpdateElementMessages(bool fullContent)
{
ElementDesc_SinkSplitter arguments;
arguments.id = id;
arguments.leftTopColor = element->GetColor1();
arguments.rightBottomColor = element->GetColor2();
arguments.direction = element->GetDirection();
renderTarget->GetRemoteMessages().RequestRendererUpdateElement_SinkSplitter(arguments);
}
/***********************************************************************
GuiSolidBackgroundElementRenderer
***********************************************************************/
GuiSolidBackgroundElementRenderer::GuiSolidBackgroundElementRenderer()
{
}
void GuiSolidBackgroundElementRenderer::SendUpdateElementMessages(bool fullContent)
{
ElementDesc_SolidBackground arguments;
arguments.id = id;
arguments.backgroundColor = element->GetColor();
arguments.shape = element->GetShape();
renderTarget->GetRemoteMessages().RequestRendererUpdateElement_SolidBackground(arguments);
}
/***********************************************************************
GuiGradientBackgroundElementRenderer
***********************************************************************/
GuiGradientBackgroundElementRenderer::GuiGradientBackgroundElementRenderer()
{
}
void GuiGradientBackgroundElementRenderer::SendUpdateElementMessages(bool fullContent)
{
ElementDesc_GradientBackground arguments;
arguments.id = id;
arguments.leftTopColor = element->GetColor1();
arguments.rightBottomColor = element->GetColor2();
arguments.direction = element->GetDirection();
arguments.shape = element->GetShape();
renderTarget->GetRemoteMessages().RequestRendererUpdateElement_GradientBackground(arguments);
}
/***********************************************************************
GuiInnerShadowElementRenderer
***********************************************************************/
GuiInnerShadowElementRenderer::GuiInnerShadowElementRenderer()
{
}
void GuiInnerShadowElementRenderer::SendUpdateElementMessages(bool fullContent)
{
ElementDesc_InnerShadow arguments;
arguments.id = id;
arguments.shadowColor = element->GetColor();
arguments.thickness = element->GetThickness();
renderTarget->GetRemoteMessages().RequestRendererUpdateElement_InnerShadow(arguments);
}
/***********************************************************************
GuiSolidLabelElementRenderer
***********************************************************************/
GuiSolidLabelElementRenderer::MeasuringRequest GuiSolidLabelElementRenderer::GetMeasuringRequest()
{
if (element->GetEllipse())
{
return ElementSolidLabelMeasuringRequest::FontHeight;
}
else if (element->GetWrapLine() && !element->GetWrapLineHeightCalculation())
{
return {};
}
else
{
return ElementSolidLabelMeasuringRequest::TotalSize;
}
}
bool GuiSolidLabelElementRenderer::IsNeedFontHeight(MeasuringRequest request)
{
return request && request.Value() == ElementSolidLabelMeasuringRequest::FontHeight;
}
GuiSolidLabelElementRenderer::GuiSolidLabelElementRenderer()
{
minSize = { 1,1 };
}
bool GuiSolidLabelElementRenderer::NeedUpdateMinSizeFromCache()
{
return needFontHeight;
}
void GuiSolidLabelElementRenderer::TryFetchMinSizeFromCache()
{
if (needFontHeight)
{
vint index = renderTarget->fontHeights.Keys().IndexOf({ lastFont.fontFamily,lastFont.size });
if (index != -1)
{
needFontHeight = false;
vint size = renderTarget->fontHeights.Values()[index];
UpdateMinSize({ size,size });
}
}
}
void GuiSolidLabelElementRenderer::UpdateMinSize(Size size)
{
minSize = size;
if (minSize.x < 1)minSize.x = 1;
if (minSize.y < 1)minSize.y = 1;
}
void GuiSolidLabelElementRenderer::NotifyMinSizeCacheInvalidated()
{
OnElementStateChanged();
auto request = GetMeasuringRequest();
needFontHeight = IsNeedFontHeight(request);
}
void GuiSolidLabelElementRenderer::SendUpdateElementMessages(bool fullContent)
{
ElementDesc_SolidLabel arguments;
arguments.id = id;
arguments.textColor = element->GetColor();
arguments.wrapLine = element->GetWrapLine();
arguments.wrapLineHeightCalculation = element->GetWrapLineHeightCalculation();
arguments.ellipse = element->GetEllipse();
arguments.multiline = element->GetMultiline();
switch (element->GetHorizontalAlignment())
{
case Alignment::Left:
arguments.horizontalAlignment = ElementHorizontalAlignment::Left;
break;
case Alignment::Right:
arguments.horizontalAlignment = ElementHorizontalAlignment::Right;
break;
default:
arguments.horizontalAlignment = ElementHorizontalAlignment::Center;
}
switch (element->GetVerticalAlignment())
{
case Alignment::Top:
arguments.verticalAlignment = ElementVerticalAlignment::Top;
break;
case Alignment::Bottom:
arguments.verticalAlignment = ElementVerticalAlignment::Bottom;
break;
default:
arguments.verticalAlignment = ElementVerticalAlignment::Center;
}
auto elementFont = element->GetFont();
auto elementText = element->GetText();
if (elementFont.fontFamily == WString::Empty)
{
elementFont = GetCurrentController()->ResourceService()->GetDefaultFont();
}
if (renderTargetChanged || fullContent || lastFont != elementFont)
{
arguments.font = elementFont;
}
if (renderTargetChanged || fullContent || lastText != elementText)
{
arguments.text = elementText;
}
lastFont = elementFont;
lastText = elementText;
arguments.measuringRequest = GetMeasuringRequest();
if ((needFontHeight = IsNeedFontHeight(arguments.measuringRequest)))
{
TryFetchMinSizeFromCache();
if (!needFontHeight)
{
arguments.measuringRequest.Reset();
}
}
renderTarget->GetRemoteMessages().RequestRendererUpdateElement_SolidLabel(arguments);
}
/***********************************************************************
GuiImageFrameElementRenderer
***********************************************************************/
GuiRemoteGraphicsImage* GuiImageFrameElementRenderer::GetRemoteImage()
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::elements_remoteprotocol::GuiImageFrameElementRenderer::GetRemoteImage()#"
if (element && element->GetImage())
{
auto image = dynamic_cast<GuiRemoteGraphicsImage*>(element->GetImage().Obj());
CHECK_ERROR(image, ERROR_MESSAGE_PREFIX L"Only INativeImage that created from GetCurrentController()->ImageService() is supported.");
return image;
}
return nullptr;
#undef ERROR_MESSAGE_PREFIX
}
void GuiImageFrameElementRenderer::UpdateMinSizeFromImage(GuiRemoteGraphicsImage* image)
{
needUpdateSize = true;
if (!image || element->GetStretch())
{
minSize = { 0,0 };
needUpdateSize = false;
}
else if (image->status == GuiRemoteGraphicsImage::MetadataStatus::Retrived)
{
if (0 <= element->GetFrameIndex() && element->GetFrameIndex() < image->GetFrameCount())
{
minSize = image->GetFrame(element->GetFrameIndex())->GetSize();
}
else
{
minSize = { 0,0 };
}
needUpdateSize = false;
}
}
GuiImageFrameElementRenderer::GuiImageFrameElementRenderer()
{
}
bool GuiImageFrameElementRenderer::NeedUpdateMinSizeFromCache()
{
return needUpdateSize;
}
void GuiImageFrameElementRenderer::TryFetchMinSizeFromCache()
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::elements_remoteprotocol::GuiImageFrameElementRenderer::TryFetchMinSizeFromCache()#"
auto image = GetRemoteImage();
if (!image || image->status != GuiRemoteGraphicsImage::MetadataStatus::Retrived)
{
return;
}
UpdateMinSizeFromImage(image);
needUpdateSize = false;
#undef ERROR_MESSAGE_PREFIX
}
void GuiImageFrameElementRenderer::SendUpdateElementMessages(bool fullContent)
{
auto image = GetRemoteImage();
if (image)
{
needUpdateSize = true;
if (fullContent)
{
if (fullContent && image->status == GuiRemoteGraphicsImage::MetadataStatus::Retrived)
{
image->status = GuiRemoteGraphicsImage::MetadataStatus::Uninitialized;
}
}
else
{
if (image->status == GuiRemoteGraphicsImage::MetadataStatus::Uninitialized)
{
image->EnsureMetadata();
}
}
if (image->status == GuiRemoteGraphicsImage::MetadataStatus::Retrived)
{
UpdateMinSizeFromImage(image);
renderTargetChanged = false;
}
}
remoteprotocol::ElementDesc_ImageFrame arguments;
arguments.id = id;
if (image) arguments.imageId = image->id;
arguments.imageFrame = element->GetFrameIndex();
arguments.stretch = element->GetStretch();
arguments.enabled = element->GetEnabled();
switch (element->GetHorizontalAlignment())
{
case Alignment::Left:
arguments.horizontalAlignment = ElementHorizontalAlignment::Left;
break;
case Alignment::Right:
arguments.horizontalAlignment = ElementHorizontalAlignment::Right;
break;
default:
arguments.horizontalAlignment = ElementHorizontalAlignment::Center;
}
switch (element->GetVerticalAlignment())
{
case Alignment::Top:
arguments.verticalAlignment = ElementVerticalAlignment::Top;
break;
case Alignment::Bottom:
arguments.verticalAlignment = ElementVerticalAlignment::Bottom;
break;
default:
arguments.verticalAlignment = ElementVerticalAlignment::Center;
}
if ((renderTargetChanged || needUpdateSize) && image)
{
arguments.imageCreation = image->GenerateImageCreation();
}
renderTarget->GetRemoteMessages().RequestRendererUpdateElement_ImageFrame(arguments);
}
/***********************************************************************
GuiPolygonElementRenderer
***********************************************************************/
GuiPolygonElementRenderer::GuiPolygonElementRenderer()
{
}
void GuiPolygonElementRenderer::SendUpdateElementMessages(bool fullContent)
{
minSize = element->GetSize();
ElementDesc_Polygon arguments;
arguments.id = id;
arguments.size = element->GetSize();
arguments.borderColor = element->GetBorderColor();
arguments.backgroundColor = element->GetBackgroundColor();
arguments.points = Ptr(new List<Point>);
CopyFrom(*arguments.points.Obj(), element->GetPointsArray());
renderTarget->GetRemoteMessages().RequestRendererUpdateElement_Polygon(arguments);
}
/***********************************************************************
GuiColorizedTextElementRenderer
***********************************************************************/
void GuiColorizedTextElementRenderer::ColorChanged()
{
}
void GuiColorizedTextElementRenderer::FontChanged()
{
}
void GuiColorizedTextElementRenderer::InitializeInternal()
{
TBase::InitializeInternal();
element->SetCallback(this);
}
void GuiColorizedTextElementRenderer::FinalizeInternal()
{
element->SetCallback(nullptr);
TBase::FinalizeInternal();
}
GuiColorizedTextElementRenderer::GuiColorizedTextElementRenderer()
{
}
void GuiColorizedTextElementRenderer::OnElementStateChanged()
{
TBase::OnElementStateChanged();
}
void GuiColorizedTextElementRenderer::SendUpdateElementMessages(bool fullContent)
{
// Lines
// Colors
// Font
// PasswordChar
// ViewPosition
// VisuallyEnabled
// Focused
// CaretBegin
// CaretEnd
// CaretVisible
// CaretColor
CHECK_FAIL(L"Not Implemented!");
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\GUIREMOTEGRAPHICS_IMAGESERVICE.CPP
***********************************************************************/
namespace vl::presentation
{
/***********************************************************************
GuiRemoteGraphicsImageFrame
***********************************************************************/
GuiRemoteGraphicsImageFrame::GuiRemoteGraphicsImageFrame(GuiRemoteGraphicsImage* _image)
: image(_image)
{
}
GuiRemoteGraphicsImageFrame::~GuiRemoteGraphicsImageFrame()
{
}
INativeImage* GuiRemoteGraphicsImageFrame::GetImage()
{
return image;
}
Size GuiRemoteGraphicsImageFrame::GetSize()
{
return size;
}
/***********************************************************************
GuiRemoteGraphicsImage
***********************************************************************/
void GuiRemoteGraphicsImage::EnsureMetadata()
{
if (status == MetadataStatus::Retrived) return;
auto arguments = GenerateImageCreation();
vint idImageCreated = remote->remoteMessages.RequestImageCreated(arguments);
bool disconnected = false;
remote->remoteMessages.Submit(disconnected);
if (disconnected) return;
auto imageMetadata = remote->remoteMessages.RetrieveImageCreated(idImageCreated);
UpdateFromImageMetadata(imageMetadata);
}
GuiRemoteGraphicsImage::GuiRemoteGraphicsImage(GuiRemoteController* _remote, vint _id, Ptr<stream::MemoryStream> _binary)
: remote(_remote)
, id(_id)
, binary(_binary)
{
remote->imageService.images.Add(id, this);
}
GuiRemoteGraphicsImage::~GuiRemoteGraphicsImage()
{
if (remote)
{
if (status == MetadataStatus::Retrived)
{
remote->remoteMessages.RequestImageDestroyed(id);
}
remote->imageService.images.Remove(id);
}
}
stream::IStream& GuiRemoteGraphicsImage::GetBinaryData()
{
return *binary.Obj();
}
remoteprotocol::ImageCreation GuiRemoteGraphicsImage::GenerateImageCreation()
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::GuiRemoteGraphicsImage::GenerateImageCreation()#"
CHECK_ERROR(status != MetadataStatus::Retrived, L"Cannot call this function when status is Retrived.");
remoteprotocol::ImageCreation arguments;
arguments.id = id;
if (status == MetadataStatus::Uninitialized)
{
arguments.imageData = binary;
arguments.imageDataOmitted = false;
status = MetadataStatus::Requested;
}
else
{
arguments.imageDataOmitted = true;
}
return arguments;
#undef ERROR_MESSAGE_PREFIX
}
void GuiRemoteGraphicsImage::UpdateFromImageMetadata(const remoteprotocol::ImageMetadata& imageMetadata)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::GuiRemoteGraphicsImage::UpdateFromImageMetadata(const remoteprotocol::ImageMetadata&)#"
CHECK_ERROR(id == imageMetadata.id, L"Wrong image metadata id specified.");
format = imageMetadata.format;
if (imageMetadata.frames)
{
if (frames.Count() > 0)
{
CHECK_ERROR(frames.Count() == imageMetadata.frames, L"New metadata should be identical to the last one.");
for (auto [imageFrameMetadata, index] : indexed(*imageMetadata.frames.Obj()))
{
CHECK_ERROR(frames[index]->size == imageFrameMetadata.size, L"New metadata should be identical to the last one.");
}
}
else
{
for (auto imageFrameMetadata : *imageMetadata.frames.Obj())
{
auto frame = Ptr(new GuiRemoteGraphicsImageFrame(this));
frame->size = imageFrameMetadata.size;
frames.Add(frame);
}
}
}
else
{
CHECK_ERROR(frames.Count() == 0, L"New metadata should be identical to the last one.");
}
status = MetadataStatus::Retrived;
#undef ERROR_MESSAGE_PREFIX
}
INativeImageService* GuiRemoteGraphicsImage::GetImageService()
{
return remote->ImageService();
}
INativeImage::FormatType GuiRemoteGraphicsImage::GetFormat()
{
EnsureMetadata();
return format;
}
vint GuiRemoteGraphicsImage::GetFrameCount()
{
EnsureMetadata();
return frames.Count();
}
INativeImageFrame* GuiRemoteGraphicsImage::GetFrame(vint index)
{
EnsureMetadata();
return frames[index].Obj();
}
void GuiRemoteGraphicsImage::SaveToStream(stream::IStream& imageStream, FormatType formatType)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::GuiRemoteGraphicsImage::SaveToStream(IStream&, INativeImage::FormatType)#"
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"This function should not be called.");
#undef ERROR_MESSAGE_PREFIX
}
/***********************************************************************
GuiRemoteGraphicsImageService
***********************************************************************/
Ptr<GuiRemoteGraphicsImage> GuiRemoteGraphicsImageService::CreateImage(Ptr<stream::MemoryStream> binary)
{
return Ptr(new GuiRemoteGraphicsImage(remote, ++usedImageIds, binary));
}
GuiRemoteGraphicsImageService::GuiRemoteGraphicsImageService(GuiRemoteController* _remote)
: remote(_remote)
{
}
GuiRemoteGraphicsImageService::~GuiRemoteGraphicsImageService()
{
}
void GuiRemoteGraphicsImageService::ResetImageMetadata()
{
for (auto image : images.Values())
{
image->status = GuiRemoteGraphicsImage::MetadataStatus::Uninitialized;
}
}
void GuiRemoteGraphicsImageService::OnControllerConnect()
{
ResetImageMetadata();
}
void GuiRemoteGraphicsImageService::OnControllerDisconnect()
{
}
void GuiRemoteGraphicsImageService::Initialize()
{
}
void GuiRemoteGraphicsImageService::Finalize()
{
// TODO: (enumerable) foreach:reversed
for (vint i = images.Count() - 1; i >= 0; i--)
{
images.Values()[i]->remote = nullptr;
}
images.Clear();
}
GuiRemoteGraphicsImage* GuiRemoteGraphicsImageService::GetImage(vint id)
{
return images[id];
}
Ptr<INativeImage> GuiRemoteGraphicsImageService::CreateImageFromFile(const WString& path)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::GuiRemoteGraphicsImageService::CreateImageFromFile(const WString&)#"
CHECK_ERROR(remote, ERROR_MESSAGE_PREFIX L"This function cannot be called when GuiRemoteController is shut down.");
stream::FileStream fileStream(path, stream::FileStream::ReadOnly);
CHECK_ERROR(fileStream.IsAvailable(), ERROR_MESSAGE_PREFIX L"Unable to open file.");
auto memoryStream = Ptr(new stream::MemoryStream((vint)fileStream.Size()));
CopyStream(fileStream, *memoryStream.Obj());
return CreateImage(memoryStream);
#undef ERROR_MESSAGE_PREFIX
}
Ptr<INativeImage> GuiRemoteGraphicsImageService::CreateImageFromMemory(void* buffer, vint length)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::GuiRemoteGraphicsImageService::CreateImageFromMemory(void*, vint)#"
CHECK_ERROR(remote, ERROR_MESSAGE_PREFIX L"This function cannot be called when GuiRemoteController is shut down.");
auto memoryStream = Ptr(new stream::MemoryStream(length));
memoryStream->Write(buffer, length);
return CreateImage(memoryStream);
#undef ERROR_MESSAGE_PREFIX
}
Ptr<INativeImage> GuiRemoteGraphicsImageService::CreateImageFromStream(stream::IStream& imageStream)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::GuiRemoteGraphicsImageService::CreateImageFromStream(IStream&)#"
CHECK_ERROR(remote, ERROR_MESSAGE_PREFIX L"This function cannot be called when GuiRemoteController is shut down.");
auto memoryStream = Ptr(new stream::MemoryStream(imageStream.IsLimited() ? (vint)imageStream.Size() : 65536));
imageStream.SeekFromBegin(0);
CopyStream(imageStream, *memoryStream.Obj());
return CreateImage(memoryStream);
#undef ERROR_MESSAGE_PREFIX
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\GUIREMOTEPROTOCOLSCHEMASHARED.CPP
***********************************************************************/
namespace vl::presentation::remoteprotocol
{
template<> Ptr<glr::json::JsonNode> ConvertCustomTypeToJson<bool>(const bool& value)
{
auto node = Ptr(new glr::json::JsonLiteral);
node->value = value ? glr::json::JsonLiteralValue::True : glr::json::JsonLiteralValue::False;
return node;
}
template<> Ptr<glr::json::JsonNode> ConvertCustomTypeToJson<vint>(const vint& value)
{
auto node = Ptr(new glr::json::JsonNumber);
reflection::description::TypedValueSerializerProvider<vint>::Serialize(value, node->content.value);
return node;
}
template<> Ptr<glr::json::JsonNode> ConvertCustomTypeToJson<float>(const float& value)
{
auto node = Ptr(new glr::json::JsonNumber);
reflection::description::TypedValueSerializerProvider<float>::Serialize(value, node->content.value);
return node;
}
template<> Ptr<glr::json::JsonNode> ConvertCustomTypeToJson<double>(const double& value)
{
auto node = Ptr(new glr::json::JsonNumber);
reflection::description::TypedValueSerializerProvider<double>::Serialize(value, node->content.value);
return node;
}
template<> Ptr<glr::json::JsonNode> ConvertCustomTypeToJson<WString>(const WString& value)
{
auto node = Ptr(new glr::json::JsonString);
node->content.value = value;
return node;
}
template<> Ptr<glr::json::JsonNode> ConvertCustomTypeToJson<wchar_t>(const wchar_t& value)
{
return ConvertCustomTypeToJson(WString::FromChar(value));
}
template<> Ptr<glr::json::JsonNode> ConvertCustomTypeToJson<VKEY>(const VKEY& value)
{
return ConvertCustomTypeToJson((vint)value);
}
template<> Ptr<glr::json::JsonNode> ConvertCustomTypeToJson<Color>(const Color& value)
{
return ConvertCustomTypeToJson(value.ToString());
}
template<> Ptr<glr::json::JsonNode> ConvertCustomTypeToJson<Ptr<stream::MemoryStream>>(const Ptr<stream::MemoryStream>& value)
{
if (!value)
{
auto node = Ptr(new glr::json::JsonLiteral);
node->value = glr::json::JsonLiteralValue::Null;
return node;
}
stream::MemoryStream base64WStringStream;
{
stream::UtfGeneralEncoder<wchar_t, char8_t> utf8ToWCharEncoder;
stream::EncoderStream utf8ToWCharStream(base64WStringStream, utf8ToWCharEncoder);
stream::Utf8Base64Encoder binaryToBase64Utf8Encoder;
stream::EncoderStream binaryToBase64Utf8Stream(utf8ToWCharStream, binaryToBase64Utf8Encoder);
value->SeekFromBegin(0);
stream::CopyStream(*value.Obj(), binaryToBase64Utf8Stream);
}
{
base64WStringStream.SeekFromBegin(0);
stream::StreamReader reader(base64WStringStream);
return ConvertCustomTypeToJson(reader.ReadToEnd());
}
}
template<> void ConvertJsonToCustomType<bool>(Ptr<glr::json::JsonNode> node, bool& value)
{
#define ERROR_MESSAGE_PREFIX L"presentation::remoteprotocol::ConvertJsonToCustomType<bool>(Ptr<JsonNode>, bool&)#"
auto jsonNode = node.Cast<glr::json::JsonLiteral>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"JSON node does not match the expected type.");
switch (jsonNode->value)
{
case glr::json::JsonLiteralValue::True: value = true; break;
case glr::json::JsonLiteralValue::False: value = false; break;
default: CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported json literal.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<vint>(Ptr<glr::json::JsonNode> node, vint& value)
{
#define ERROR_MESSAGE_PREFIX L"presentation::remoteprotocol::ConvertJsonToCustomType<vint>(Ptr<JsonNode>, vint&)#"
auto jsonNode = node.Cast<glr::json::JsonNumber>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"JSON node does not match the expected type.");
CHECK_ERROR(reflection::description::TypedValueSerializerProvider<vint>::Deserialize(jsonNode->content.value, value), ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<float>(Ptr<glr::json::JsonNode> node, float& value)
{
#define ERROR_MESSAGE_PREFIX L"presentation::remoteprotocol::ConvertJsonToCustomType<float>(Ptr<JsonNode>, float&)#"
auto jsonNode = node.Cast<glr::json::JsonNumber>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"JSON node does not match the expected type.");
CHECK_ERROR(reflection::description::TypedValueSerializerProvider<float>::Deserialize(jsonNode->content.value, value), ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<double>(Ptr<glr::json::JsonNode> node, double& value)
{
#define ERROR_MESSAGE_PREFIX L"presentation::remoteprotocol::ConvertJsonToCustomType<double>(Ptr<JsonNode>, double&)#"
auto jsonNode = node.Cast<glr::json::JsonNumber>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"JSON node does not match the expected type.");
CHECK_ERROR(reflection::description::TypedValueSerializerProvider<double>::Deserialize(jsonNode->content.value, value), ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<WString>(Ptr<glr::json::JsonNode> node, WString& value)
{
#define ERROR_MESSAGE_PREFIX L"presentation::remoteprotocol::ConvertJsonToCustomType<WString>(Ptr<JsonNode>, WString&)#"
auto jsonNode = node.Cast<glr::json::JsonString>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"JSON node does not match the expected type.");
value = jsonNode->content.value;
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<wchar_t>(Ptr<glr::json::JsonNode> node, wchar_t& value)
{
#define ERROR_MESSAGE_PREFIX L"presentation::remoteprotocol::ConvertJsonToCustomType<wchar_t>(Ptr<JsonNode>, wchar_t&)#"
WString strValue;
ConvertJsonToCustomType(node, strValue);
CHECK_ERROR(strValue.Length() == 1, ERROR_MESSAGE_PREFIX L"Char in JSON should be a string with one char.");
value = strValue[0];
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<VKEY>(Ptr<glr::json::JsonNode> node, VKEY& value)
{
vint intValue;
ConvertJsonToCustomType(node, intValue);
value = (VKEY)intValue;
}
template<> void ConvertJsonToCustomType<Color>(Ptr<glr::json::JsonNode> node, Color& value)
{
WString strValue;
ConvertJsonToCustomType(node, strValue);
value = Color::Parse(strValue);
}
template<> void ConvertJsonToCustomType<Ptr<stream::MemoryStream>>(Ptr<glr::json::JsonNode> node, Ptr<stream::MemoryStream>& value)
{
if (auto jsonLiteral = node.Cast<glr::json::JsonLiteral>())
{
if (jsonLiteral->value == glr::json::JsonLiteralValue::Null)
{
value = {};
return;
}
}
else
{
WString base64;
ConvertJsonToCustomType(node, base64);
value = Ptr(new stream::MemoryStream);
stream::MemoryWrapperStream base64WStringStream((void*)base64.Buffer(), base64.Length() * sizeof(wchar_t));
stream::UtfGeneralDecoder<wchar_t, char8_t> wcharToUtf8Decoder;
stream::DecoderStream wcharToUtf8Stream(base64WStringStream, wcharToUtf8Decoder);
stream::Utf8Base64Decoder base64Utf8ToBinaryDecoder;
stream::DecoderStream base64Utf8ToBinaryStream(wcharToUtf8Stream, base64Utf8ToBinaryDecoder);
stream::CopyStream(base64Utf8ToBinaryStream, *value.Obj());
}
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\GUIREMOTEPROTOCOL_CHANNEL_ASYNC.CPP
***********************************************************************/
namespace vl::presentation::remoteprotocol::channeling
{
using namespace vl::collections;
/***********************************************************************
GuiRemoteProtocolAsyncChannelSerializerBase
***********************************************************************/
void GuiRemoteProtocolAsyncChannelSerializerBase::QueueTask(SpinLock& lock, collections::List<TTaskProc>& tasks, TTaskProc task, EventObject* signalAfterQueue)
{
SPIN_LOCK(lock)
{
tasks.Add(task);
}
if (signalAfterQueue)
{
signalAfterQueue->Signal();
}
}
void GuiRemoteProtocolAsyncChannelSerializerBase::QueueTaskAndWait(SpinLock& lock, collections::List<TTaskProc>& tasks, TTaskProc task, EventObject* signalAfterQueue)
{
auto taskEvent = Ptr(new vl::EventObject);
taskEvent->CreateAutoUnsignal(false);
auto taskWithEvent = [=]()
{
task();
taskEvent->Signal();
};
QueueTask(lock, tasks, taskWithEvent, signalAfterQueue);
taskEvent->Wait();
}
void GuiRemoteProtocolAsyncChannelSerializerBase::FetchTasks(SpinLock& lock, collections::List<TTaskProc>& tasks, collections::List<TTaskProc>& results)
{
SPIN_LOCK(lock)
{
results = std::move(tasks);
}
}
void GuiRemoteProtocolAsyncChannelSerializerBase::FetchAndExecuteTasks(SpinLock& lock, collections::List<TTaskProc>& tasks)
{
List<TTaskProc> results;
FetchTasks(lock, tasks, results);
for (auto&& task : results)
{
task();
}
}
void GuiRemoteProtocolAsyncChannelSerializerBase::FetchAndExecuteChannelTasks()
{
FetchAndExecuteTasks(channelThreadLock, channelThreadTasks);
}
void GuiRemoteProtocolAsyncChannelSerializerBase::FetchAndExecuteUITasks()
{
FetchAndExecuteTasks(uiThreadLock, uiThreadTasks);
}
GuiRemoteProtocolAsyncChannelSerializerBase::GuiRemoteProtocolAsyncChannelSerializerBase()
{
}
GuiRemoteProtocolAsyncChannelSerializerBase::~GuiRemoteProtocolAsyncChannelSerializerBase()
{
}
void GuiRemoteProtocolAsyncChannelSerializerBase::QueueToChannelThread(TTaskProc task, EventObject* signalAfterQueue)
{
QueueTask(channelThreadLock, channelThreadTasks, task, signalAfterQueue);
}
void GuiRemoteProtocolAsyncChannelSerializerBase::QueueToChannelThreadAndWait(TTaskProc task, EventObject* signalAfterQueue)
{
QueueTaskAndWait(channelThreadLock, channelThreadTasks, task, signalAfterQueue);
}
void GuiRemoteProtocolAsyncChannelSerializerBase::QueueToUIThread(TTaskProc task, EventObject* signalAfterQueue)
{
QueueTask(uiThreadLock, uiThreadTasks, task, signalAfterQueue);
}
void GuiRemoteProtocolAsyncChannelSerializerBase::QueueToUIThreadAndWait(TTaskProc task, EventObject* signalAfterQueue)
{
QueueTaskAndWait(uiThreadLock, uiThreadTasks, task, signalAfterQueue);
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\GUIREMOTEPROTOCOL_CHANNEL_JSON.CPP
***********************************************************************/
namespace vl::presentation::remoteprotocol::channeling
{
/***********************************************************************
ChannelPackageSemantic
***********************************************************************/
void JsonChannelPack(ChannelPackageSemantic semantic, vint id, const WString& name, Ptr<glr::json::JsonNode> arguments, Ptr<glr::json::JsonObject>& package)
{
package = Ptr(new glr::json::JsonObject);
{
auto value = Ptr(new glr::json::JsonString);
switch (semantic)
{
case ChannelPackageSemantic::Message:
value->content.value = WString::Unmanaged(L"Message");
break;
case ChannelPackageSemantic::Request:
value->content.value = WString::Unmanaged(L"Request");
break;
case ChannelPackageSemantic::Response:
value->content.value = WString::Unmanaged(L"Response");
break;
case ChannelPackageSemantic::Event:
value->content.value = WString::Unmanaged(L"Event");
break;
default:
value->content.value = WString::Unmanaged(L"Unknown");
}
auto field = Ptr(new glr::json::JsonObjectField);
field->name.value = WString::Unmanaged(L"semantic");
field->value = value;
package->fields.Add(field);
}
if (id != -1)
{
auto value = Ptr(new glr::json::JsonNumber);
value->content.value = itow(id);
auto field = Ptr(new glr::json::JsonObjectField);
field->name.value = WString::Unmanaged(L"id");
field->value = value;
package->fields.Add(field);
}
{
auto value = Ptr(new glr::json::JsonString);
value->content.value = name;
auto field = Ptr(new glr::json::JsonObjectField);
field->name.value = WString::Unmanaged(L"name");
field->value = value;
package->fields.Add(field);
}
if (arguments)
{
auto field = Ptr(new glr::json::JsonObjectField);
field->name.value = WString::Unmanaged(L"arguments");
field->value = arguments;
package->fields.Add(field);
}
}
void JsonChannelUnpack(Ptr<glr::json::JsonObject> package, ChannelPackageSemantic& semantic, vint& id, WString& name, Ptr<glr::json::JsonNode>& arguments)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::channeling::JsonChannelPack(Ptr<JsonObject>, ProtocolSemantic&, vint&, WString&, Ptr<JsonNode>&)#"
for (auto&& field : package->fields)
{
if (field->name.value == L"semantic")
{
auto value = field->value.Cast<glr::json::JsonString>();
CHECK_ERROR(value, ERROR_MESSAGE_PREFIX L"The semantic field should be a string.");
if (value->content.value == L"Message")
{
semantic = ChannelPackageSemantic::Message;
}
else if (value->content.value == L"Request")
{
semantic = ChannelPackageSemantic::Request;
}
else if (value->content.value == L"Response")
{
semantic = ChannelPackageSemantic::Response;
}
else if (value->content.value == L"Event")
{
semantic = ChannelPackageSemantic::Event;
}
}
else if (field->name.value == L"id")
{
auto value = field->value.Cast<glr::json::JsonNumber>();
CHECK_ERROR(value, ERROR_MESSAGE_PREFIX L"The id field should be a number.");
id = wtoi(value->content.value);
}
else if (field->name.value == L"name")
{
auto value = field->value.Cast<glr::json::JsonString>();
CHECK_ERROR(value, ERROR_MESSAGE_PREFIX L"The name field should be a string.");
name = value->content.value;
}
else if (field->name.value == L"arguments")
{
arguments = field->value;
}
}
#undef ERROR_MESSAGE_PREFIX
}
void ChannelPackageSemanticUnpack(Ptr<glr::json::JsonObject> package, ChannelPackageSemantic& semantic, vint& id, WString& name)
{
Ptr<glr::json::JsonNode> arguments;
JsonChannelUnpack(package, semantic, id, name, arguments);
}
/***********************************************************************
GuiRemoteProtocolFromJsonChannel
***********************************************************************/
#define EVENT_NOREQ(NAME, REQUEST)\
void GuiRemoteProtocolFromJsonChannel::OnReceive_Event_ ## NAME (Ptr<glr::json::JsonNode> jsonArguments)\
{\
events->On ## NAME();\
}\
#define EVENT_REQ(NAME, REQUEST)\
void GuiRemoteProtocolFromJsonChannel::OnReceive_Event_ ## NAME (Ptr<glr::json::JsonNode> jsonArguments)\
{\
REQUEST arguments;\
ConvertJsonToCustomType(jsonArguments, arguments);\
events->On ## NAME(arguments);\
}\
#define EVENT_HANDLER(NAME, REQUEST, REQTAG, ...) EVENT_ ## REQTAG(NAME, REQUEST)
GACUI_REMOTEPROTOCOL_EVENTS(EVENT_HANDLER)
#undef EVENT_HANDLER
#undef EVENT_REQ
#undef EVENT_NOREQ
#define MESSAGE_NORES(NAME, RESPONSE)
#define MESSAGE_RES(NAME, RESPONSE)\
void GuiRemoteProtocolFromJsonChannel::OnReceive_Response_ ## NAME (vint id, Ptr<glr::json::JsonNode> jsonArguments)\
{\
RESPONSE arguments;\
ConvertJsonToCustomType(jsonArguments, arguments);\
events->Respond ## NAME(id, arguments);\
}\
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, ...) MESSAGE_ ## RESTAG(NAME, RESPONSE)
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
#undef MESSAGE_HANDLER
#undef MESSAGE_RES
#undef MESSAGE_NORES
void GuiRemoteProtocolFromJsonChannel::OnReceive(const Ptr<glr::json::JsonObject>& package)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::channeling::GuiRemoteProtocolFromJsonChannel::OnReceive(const Ptr<JsonNode>&)#"
auto semantic = ChannelPackageSemantic::Unknown;
vint id = -1;
WString name;
Ptr<glr::json::JsonNode> jsonArguments;
JsonChannelUnpack(package, semantic, id, name, jsonArguments);
if (semantic == ChannelPackageSemantic::Event)
{
vint index = onReceiveEventHandlers.Keys().IndexOf(name);
if (index == -1)
{
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unrecognized event name");
}
else
{
(this->*onReceiveEventHandlers.Values()[index])(jsonArguments);
}
}
else if (semantic == ChannelPackageSemantic::Response)
{
vint index = onReceiveResponseHandlers.Keys().IndexOf(name);
if (index == -1)
{
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unrecognized response name");
}
else
{
(this->*onReceiveResponseHandlers.Values()[index])(id, jsonArguments);
}
}
else
{
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unrecognized category name");
}
#undef ERROR_MESSAGE_PREFIX
}
#define MESSAGE_NOREQ_NORES(NAME, REQUEST, RESPONSE)\
void GuiRemoteProtocolFromJsonChannel::Request ## NAME()\
{\
Ptr<glr::json::JsonObject> package;\
JsonChannelPack(ChannelPackageSemantic::Message, -1, WString::Unmanaged(L ## #NAME), {}, package);\
channel->Write(package);\
}\
#define MESSAGE_NOREQ_RES(NAME, REQUEST, RESPONSE)\
void GuiRemoteProtocolFromJsonChannel::Request ## NAME(vint id)\
{\
Ptr<glr::json::JsonObject> package;\
JsonChannelPack(ChannelPackageSemantic::Request, id, WString::Unmanaged(L ## #NAME), {}, package);\
channel->Write(package);\
}\
#define MESSAGE_REQ_NORES(NAME, REQUEST, RESPONSE)\
void GuiRemoteProtocolFromJsonChannel::Request ## NAME(const REQUEST& arguments)\
{\
Ptr<glr::json::JsonObject> package;\
JsonChannelPack(ChannelPackageSemantic::Message, -1, WString::Unmanaged(L ## #NAME), ConvertCustomTypeToJson(arguments), package);\
channel->Write(package);\
}\
#define MESSAGE_REQ_RES(NAME, REQUEST, RESPONSE)\
void GuiRemoteProtocolFromJsonChannel::Request ## NAME(vint id, const REQUEST& arguments)\
{\
Ptr<glr::json::JsonObject> package;\
JsonChannelPack(ChannelPackageSemantic::Request, id, WString::Unmanaged(L ## #NAME), ConvertCustomTypeToJson(arguments), package);\
channel->Write(package);\
}\
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, ...) MESSAGE_ ## REQTAG ## _ ## RESTAG(NAME, REQUEST, RESPONSE)
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
#undef MESSAGE_HANDLER
#undef MESSAGE_REQ_RES
#undef MESSAGE_REQ_NORES
#undef MESSAGE_NOREQ_RES
#undef MESSAGE_NOREQ_NORES
GuiRemoteProtocolFromJsonChannel::GuiRemoteProtocolFromJsonChannel(IJsonChannel* _channel)
: channel(_channel)
{
#define EVENT_NOREQ(NAME, REQUEST) onReceiveEventHandlers.Add(WString::Unmanaged(L ## #NAME), &GuiRemoteProtocolFromJsonChannel::OnReceive_Event_ ## NAME);
#define EVENT_REQ(NAME, REQUEST) onReceiveEventHandlers.Add(WString::Unmanaged(L ## #NAME), &GuiRemoteProtocolFromJsonChannel::OnReceive_Event_ ## NAME);
#define EVENT_HANDLER(NAME, REQUEST, REQTAG, ...) EVENT_ ## REQTAG(NAME, REQUEST)
GACUI_REMOTEPROTOCOL_EVENTS(EVENT_HANDLER)
#undef EVENT_HANDLER
#undef EVENT_REQ
#undef EVENT_NOREQ
#define MESSAGE_NORES(NAME, RESPONSE)
#define MESSAGE_RES(NAME, RESPONSE) onReceiveResponseHandlers.Add(WString::Unmanaged(L ## #NAME), &GuiRemoteProtocolFromJsonChannel::OnReceive_Response_ ## NAME);
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, ...) MESSAGE_ ## RESTAG(NAME, RESPONSE)
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
#undef MESSAGE_HANDLER
#undef MESSAGE_RES
#undef MESSAGE_NORES
}
GuiRemoteProtocolFromJsonChannel::~GuiRemoteProtocolFromJsonChannel()
{
}
void GuiRemoteProtocolFromJsonChannel::Initialize(IGuiRemoteProtocolEvents* _events)
{
events = _events;
channel->Initialize(this);
}
WString GuiRemoteProtocolFromJsonChannel::GetExecutablePath()
{
return channel->GetExecutablePath();
}
void GuiRemoteProtocolFromJsonChannel::Submit(bool& disconnected)
{
channel->Submit(disconnected);
}
void GuiRemoteProtocolFromJsonChannel::ProcessRemoteEvents()
{
channel->ProcessRemoteEvents();
}
/***********************************************************************
GuiRemoteJsonChannelFromProtocol
***********************************************************************/
#define EVENT_NOREQ(NAME, REQUEST)\
void GuiRemoteJsonChannelFromProtocol::On ## NAME()\
{\
Ptr<glr::json::JsonObject> package;\
JsonChannelPack(ChannelPackageSemantic::Event, -1, WString::Unmanaged(L ## #NAME), {}, package);\
receiver->OnReceive(package);\
}\
#define EVENT_REQ(NAME, REQUEST)\
void GuiRemoteJsonChannelFromProtocol::On ## NAME(const REQUEST& arguments)\
{\
Ptr<glr::json::JsonObject> package;\
JsonChannelPack(ChannelPackageSemantic::Event, -1, WString::Unmanaged(L ## #NAME), ConvertCustomTypeToJson(arguments), package);\
receiver->OnReceive(package);\
}\
#define EVENT_HANDLER(NAME, REQUEST, REQTAG, ...) EVENT_ ## REQTAG(NAME, REQUEST)
GACUI_REMOTEPROTOCOL_EVENTS(EVENT_HANDLER)
#undef EVENT_HANDLER
#undef EVENT_REQ
#undef EVENT_NOREQ
#define MESSAGE_NORES(NAME, RESPONSE)
#define MESSAGE_RES(NAME, RESPONSE)\
void GuiRemoteJsonChannelFromProtocol::Respond ## NAME(vint id, const RESPONSE& arguments)\
{\
Ptr<glr::json::JsonObject> package;\
JsonChannelPack(ChannelPackageSemantic::Response, id, WString::Unmanaged(L ## #NAME), ConvertCustomTypeToJson(arguments), package);\
receiver->OnReceive(package);\
}\
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, ...) MESSAGE_ ## RESTAG(NAME, RESPONSE)
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
#undef MESSAGE_HANDLER
#undef MESSAGE_RES
#undef MESSAGE_NORES
#define MESSAGE_NOREQ_NORES(NAME, REQUEST, RESPONSE)\
void GuiRemoteJsonChannelFromProtocol::Write_ ## NAME(vint id, Ptr<glr::json::JsonNode> jsonArguments)\
{\
protocol->Request ## NAME();\
}\
#define MESSAGE_NOREQ_RES(NAME, REQUEST, RESPONSE)\
void GuiRemoteJsonChannelFromProtocol::Write_ ## NAME(vint id, Ptr<glr::json::JsonNode> jsonArguments)\
{\
protocol->Request ## NAME(id);\
}\
#define MESSAGE_REQ_NORES(NAME, REQUEST, RESPONSE)\
void GuiRemoteJsonChannelFromProtocol::Write_ ## NAME(vint id, Ptr<glr::json::JsonNode> jsonArguments)\
{\
REQUEST arguments;\
ConvertJsonToCustomType(jsonArguments, arguments);\
protocol->Request ## NAME(arguments);\
}\
#define MESSAGE_REQ_RES(NAME, REQUEST, RESPONSE)\
void GuiRemoteJsonChannelFromProtocol::Write_ ## NAME(vint id, Ptr<glr::json::JsonNode> jsonArguments)\
{\
REQUEST arguments;\
ConvertJsonToCustomType(jsonArguments, arguments);\
protocol->Request ## NAME(id, arguments);\
}\
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, ...) MESSAGE_ ## REQTAG ## _ ## RESTAG(NAME, REQUEST, RESPONSE)
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
#undef MESSAGE_HANDLER
#undef MESSAGE_REQ_RES
#undef MESSAGE_REQ_NORES
#undef MESSAGE_NOREQ_RES
#undef MESSAGE_NOREQ_NORES
GuiRemoteJsonChannelFromProtocol::GuiRemoteJsonChannelFromProtocol(IGuiRemoteProtocol* _protocol)
: protocol(_protocol)
{
#define MESSAGE_NOREQ_NORES(NAME, REQUEST, RESPONSE) writeHandlers.Add(WString::Unmanaged(L ## #NAME), &GuiRemoteJsonChannelFromProtocol::Write_ ## NAME);;
#define MESSAGE_NOREQ_RES(NAME, REQUEST, RESPONSE) writeHandlers.Add(WString::Unmanaged(L ## #NAME), &GuiRemoteJsonChannelFromProtocol::Write_ ## NAME);;
#define MESSAGE_REQ_NORES(NAME, REQUEST, RESPONSE) writeHandlers.Add(WString::Unmanaged(L ## #NAME), &GuiRemoteJsonChannelFromProtocol::Write_ ## NAME);;
#define MESSAGE_REQ_RES(NAME, REQUEST, RESPONSE) writeHandlers.Add(WString::Unmanaged(L ## #NAME), &GuiRemoteJsonChannelFromProtocol::Write_ ## NAME);;
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, ...) MESSAGE_ ## REQTAG ## _ ## RESTAG(NAME, REQUEST, RESPONSE)
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
#undef MESSAGE_HANDLER
#undef MESSAGE_REQ_RES
#undef MESSAGE_REQ_NORES
#undef MESSAGE_NOREQ_RES
#undef MESSAGE_NOREQ_NORES
}
GuiRemoteJsonChannelFromProtocol::~GuiRemoteJsonChannelFromProtocol()
{
}
void GuiRemoteJsonChannelFromProtocol::Initialize(IJsonChannelReceiver* _receiver)
{
receiver = _receiver;
protocol->Initialize(this);
}
IJsonChannelReceiver* GuiRemoteJsonChannelFromProtocol::GetReceiver()
{
return receiver;
}
void GuiRemoteJsonChannelFromProtocol::Write(const Ptr<glr::json::JsonObject>& package)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::channeling::GuiRemoteJsonChannelFromProtocol::Write(const Ptr<JsonNode>&)#"
auto semantic = ChannelPackageSemantic::Unknown;
vint id = -1;
WString name;
Ptr<glr::json::JsonNode> jsonArguments;
JsonChannelUnpack(package, semantic, id, name, jsonArguments);
vint index = writeHandlers.Keys().IndexOf(name);
if (index == -1)
{
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unrecognized request name");
}
else
{
(this->*writeHandlers.Values()[index])(id, jsonArguments);
}
#undef ERROR_MESSAGE_PREFIX
}
WString GuiRemoteJsonChannelFromProtocol::GetExecutablePath()
{
return protocol->GetExecutablePath();
}
void GuiRemoteJsonChannelFromProtocol::Submit(bool& disconnected)
{
protocol->Submit(disconnected);
}
void GuiRemoteJsonChannelFromProtocol::ProcessRemoteEvents()
{
protocol->ProcessRemoteEvents();
}
/***********************************************************************
JsonToStringSerializer
***********************************************************************/
void JsonToStringSerializer::Serialize(Ptr<glr::json::Parser> parser, const SourceType& source, DestType& dest)
{
glr::json::JsonFormatting formatting;
formatting.spaceAfterColon = false;
formatting.spaceAfterComma = false;
formatting.crlf = false;
formatting.compact = true;
dest = glr::json::JsonToString(source, formatting);
}
void JsonToStringSerializer::Deserialize(Ptr<glr::json::Parser> parser, const DestType& source, SourceType& dest)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::channeling::GuiRemoteJsonChannelFromProtocol::Write(const Ptr<JsonNode>&)#"
auto value = glr::json::JsonParse(source, *parser.Obj());
dest = value.Cast<glr::json::JsonObject>();
CHECK_ERROR(dest, ERROR_MESSAGE_PREFIX L"JSON parssing between the channel should be JsonObject.");
#undef ERROR_MESSAGE_PREFIX
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\GUIREMOTEPROTOCOL_DOMDIFF.CPP
***********************************************************************/
namespace vl::presentation::remoteprotocol
{
/***********************************************************************
GuiRemoteEventDomDiffConverter
***********************************************************************/
GuiRemoteEventDomDiffConverter::GuiRemoteEventDomDiffConverter()
{
}
GuiRemoteEventDomDiffConverter::~GuiRemoteEventDomDiffConverter()
{
}
void GuiRemoteEventDomDiffConverter::OnControllerConnect()
{
lastDom = {};
TBase::OnControllerConnect();
}
/***********************************************************************
GuiRemoteProtocolDomDiffConverter
***********************************************************************/
GuiRemoteProtocolDomDiffConverter::GuiRemoteProtocolDomDiffConverter(IGuiRemoteProtocol* _protocol)
: TBase(_protocol)
{
}
GuiRemoteProtocolDomDiffConverter::~GuiRemoteProtocolDomDiffConverter()
{
}
void GuiRemoteProtocolDomDiffConverter::RequestRendererBeginRendering(const remoteprotocol::ElementBeginRendering& arguments)
{
renderingDomBuilder.RequestRendererBeginRendering();
TBase::RequestRendererBeginRendering(arguments);
}
void GuiRemoteProtocolDomDiffConverter::RequestRendererEndRendering(vint id)
{
auto dom = renderingDomBuilder.RequestRendererEndRendering();
DomIndex domIndex;
BuildDomIndex(dom, domIndex);
if (eventCombinator.lastDom)
{
RenderingDom_DiffsInOrder diffs;
DiffDom(eventCombinator.lastDom, eventCombinator.lastDomIndex, dom, domIndex, diffs);
targetProtocol->RequestRendererRenderDomDiff(diffs);
}
else
{
targetProtocol->RequestRendererRenderDom(dom);
}
eventCombinator.lastDom = dom;
eventCombinator.lastDomIndex = std::move(domIndex);
TBase::RequestRendererEndRendering(id);
}
void GuiRemoteProtocolDomDiffConverter::RequestRendererBeginBoundary(const remoteprotocol::ElementBoundary& arguments)
{
renderingDomBuilder.RequestRendererBeginBoundary(arguments);
}
void GuiRemoteProtocolDomDiffConverter::RequestRendererEndBoundary()
{
renderingDomBuilder.RequestRendererEndBoundary();
}
void GuiRemoteProtocolDomDiffConverter::RequestRendererRenderElement(const remoteprotocol::ElementRendering& arguments)
{
renderingDomBuilder.RequestRendererRenderElement(arguments);
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\GUIREMOTEPROTOCOL_FILTER.CPP
***********************************************************************/
namespace vl::presentation::remoteprotocol::repeatfiltering
{
/***********************************************************************
GuiRemoteEventFilter
***********************************************************************/
GuiRemoteEventFilter::GuiRemoteEventFilter()
{
}
GuiRemoteEventFilter::~GuiRemoteEventFilter()
{
}
void GuiRemoteEventFilter::ProcessResponses()
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::repeatfiltering::GuiRemoteProtocolFilter::ProcessResponses()#"
for (auto&& response : filteredResponses)
{
#define MESSAGE_NORES(NAME, RESPONSE)
#define MESSAGE_RES(NAME, RESPONSE)\
case FilteredResponseNames::NAME:\
targetEvents->Respond ## NAME(response.id, response.arguments.Get<RESPONSE>());\
break;\
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, ...) MESSAGE_ ## RESTAG(NAME, RESPONSE)
switch (response.name)
{
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
default:
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unrecognized response.");
}
#undef MESSAGE_HANDLER
#undef MESSAGE_RES
#undef MESSAGE_NORES
}
CHECK_ERROR(responseIds.Count() == 0, ERROR_MESSAGE_PREFIX L"Messages sending to IGuiRemoteProtocol should be all responded.");
filteredResponses.Clear();
#undef ERROR_MESSAGE_PREFIX
}
void GuiRemoteEventFilter::ProcessEvents()
{
#define EVENT_NODROP(NAME)
#define EVENT_DROPREP(NAME) lastDropRepeatEvent ## NAME = -1;
#define EVENT_DROPCON(NAME) lastDropConsecutiveEvent ## NAME = -1;
#define EVENT_HANDLER(NAME, REQUEST, REQTAG, DROPTAG, ...) EVENT_ ## DROPTAG(NAME)
GACUI_REMOTEPROTOCOL_EVENTS(EVENT_HANDLER)
#undef EVENT_HANDLER
#undef EVENT_DROPCON
#undef EVENT_DROPREP
#undef EVENT_NODROP
collections::List<FilteredEvent> events(std::move(filteredEvents));
for (auto&& event : events)
{
if (event.dropped)
{
continue;
}
#define EVENT_NOREQ(NAME, REQUEST)\
case FilteredEventNames::NAME:\
targetEvents->On ## NAME();\
break;\
#define EVENT_REQ(NAME, REQUEST)\
case FilteredEventNames::NAME:\
targetEvents->On ## NAME(event.arguments.Get<REQUEST>());\
break;\
#define EVENT_HANDLER(NAME, REQUEST, REQTAG, ...) EVENT_ ## REQTAG(NAME, REQUEST)
switch (event.name)
{
GACUI_REMOTEPROTOCOL_EVENTS(EVENT_HANDLER)
default:
CHECK_FAIL(L"vl::presentation::remoteprotocol::GuiRemoteEventFilter::ProcessEvents()#Unrecognized event.");
}
#undef EVENT_HANDLER
#undef EVENT_REQ
#undef EVENT_NOREQ
}
}
// responses
#define MESSAGE_NORES(NAME, RESPONSE)
#define MESSAGE_RES(NAME, RESPONSE)\
void GuiRemoteEventFilter::Respond ## NAME(vint id, const RESPONSE& arguments)\
{\
CHECK_ERROR(\
responseIds[id] == FilteredResponseNames::NAME,\
L"vl::presentation::remoteprotocol::GuiRemoteEventFilter::"\
L"Respond" L ## #NAME L"()#"\
L"Messages sending to IGuiRemoteProtocol should be responded by calling the correct function.");\
responseIds.Remove(id);\
FilteredResponse response;\
response.id = id;\
response.name = FilteredResponseNames::NAME;\
response.arguments = arguments;\
filteredResponses.Add(response);\
}\
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, ...) MESSAGE_ ## RESTAG(NAME, RESPONSE)
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
#undef MESSAGE_HANDLER
#undef MESSAGE_RES
#undef MESSAGE_NORES
// events
#define EVENT_NODROP(NAME)
#define EVENT_DROPREP(NAME)\
if (lastDropRepeatEvent ## NAME != -1)\
{\
filteredEvents[lastDropRepeatEvent ## NAME].dropped = true;\
}\
lastDropRepeatEvent ## NAME = filteredEvents.Count() - 1\
#define EVENT_DROPCON(NAME)\
if (lastDropConsecutiveEvent ## NAME != -1 && lastDropConsecutiveEvent ## NAME == filteredEvents.Count() - 1)\
{\
filteredEvents[lastDropConsecutiveEvent ## NAME].dropped = true;\
}\
lastDropConsecutiveEvent ## NAME = filteredEvents.Count() - 1\
#define EVENT_NOREQ(NAME, REQUEST, DROPTAG)\
void GuiRemoteEventFilter::On ## NAME()\
{\
if (submitting)\
{\
EVENT_ ## DROPTAG(NAME);\
FilteredEvent event;\
event.name = FilteredEventNames::NAME;\
filteredEvents.Add(event);\
}\
else\
{\
targetEvents->On ## NAME();\
}\
}\
#define EVENT_REQ(NAME, REQUEST, DROPTAG)\
void GuiRemoteEventFilter::On ## NAME(const REQUEST& arguments)\
{\
if (submitting)\
{\
EVENT_ ## DROPTAG(NAME);\
FilteredEvent event;\
event.name = FilteredEventNames::NAME;\
event.arguments = arguments;\
filteredEvents.Add(event);\
}\
else\
{\
targetEvents->On ## NAME(arguments);\
}\
}\
#define EVENT_HANDLER(NAME, REQUEST, REQTAG, DROPTAG, ...) EVENT_ ## REQTAG(NAME, REQUEST, DROPTAG)
GACUI_REMOTEPROTOCOL_EVENTS(EVENT_HANDLER)
#undef EVENT_HANDLER
#undef EVENT_REQ
#undef EVENT_NOREQ
#undef EVENT_DROPCON
#undef EVENT_DROPREP
#undef EVENT_NOREP
/***********************************************************************
GuiRemoteProtocolFilter
***********************************************************************/
void GuiRemoteProtocolFilter::ProcessRequests()
{
#define MESSAGE_NODROP(NAME)
#define MESSAGE_DROPREP(NAME) lastDropRepeatRequest ## NAME = -1;
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, DROPTAG) MESSAGE_ ## DROPTAG(NAME)
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
#undef MESSAGE_HANDLER
#undef MESSAGE_DROPREP
#undef MESSAGE_NODROP
for (auto&& request : filteredRequests)
{
CHECK_ERROR(\
!request.dropped || request.id == -1,\
L"vl::presentation::remoteprotocol::GuiRemoteProtocolFilter::ProcessRequests()#"\
L"Messages with id cannot be dropped.");\
if (request.dropped)
{
continue;
}
#define MESSAGE_NOREQ_NORES(NAME, REQUEST, RESPONSE)\
case FilteredRequestNames::NAME:\
targetProtocol->Request ## NAME();\
break;\
#define MESSAGE_NOREQ_RES(NAME, REQUEST, RESPONSE)\
case FilteredRequestNames::NAME:\
targetProtocol->Request ## NAME(request.id);\
break;\
#define MESSAGE_REQ_NORES(NAME, REQUEST, RESPONSE)\
case FilteredRequestNames::NAME:\
targetProtocol->Request ## NAME(request.arguments.Get<REQUEST>());\
break;\
#define MESSAGE_REQ_RES(NAME, REQUEST, RESPONSE)\
case FilteredRequestNames::NAME:\
targetProtocol->Request ## NAME(request.id, request.arguments.Get<REQUEST>());\
break;\
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, ...) MESSAGE_ ## REQTAG ## _ ## RESTAG(NAME, REQUEST, RESPONSE)
switch (request.name)
{
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
default:
CHECK_FAIL(L"vl::presentation::remoteprotocol::GuiRemoteProtocolFilter::ProcessRequests()#Unrecognized request.");
}
#undef MESSAGE_HANDLER
#undef MESSAGE_REQ_RES
#undef MESSAGE_REQ_NORES
#undef MESSAGE_NOREQ_RES
#undef MESSAGE_NOREQ_NORES
}
filteredRequests.Clear();
}
GuiRemoteProtocolFilter::GuiRemoteProtocolFilter(IGuiRemoteProtocol* _protocol)
: GuiRemoteProtocolCombinator<GuiRemoteEventFilter>(_protocol)
{
}
GuiRemoteProtocolFilter::~GuiRemoteProtocolFilter()
{
}
// messages
#define MESSAGE_NODROP(NAME)
#define MESSAGE_DROPREP(NAME)\
if (lastDropRepeatRequest ## NAME != -1)\
{\
filteredRequests[lastDropRepeatRequest ## NAME].dropped = true;\
}\
lastDropRepeatRequest ## NAME = filteredRequests.Count()\
#define MESSAGE_NOREQ_NORES(NAME, REQUEST, RESPONSE, DROPTAG)\
void GuiRemoteProtocolFilter::Request ## NAME()\
{\
MESSAGE_ ## DROPTAG(NAME);\
FilteredRequest request;\
request.name = FilteredRequestNames::NAME;\
filteredRequests.Add(request);\
}\
#define MESSAGE_NOREQ_RES(NAME, REQUEST, RESPONSE, DROPTAG)\
void GuiRemoteProtocolFilter::Request ## NAME(vint id)\
{\
MESSAGE_ ## DROPTAG(NAME);\
CHECK_ERROR(\
lastRequestId < id,\
L"vl::presentation::remoteprotocol::GuiRemoteProtocolFilter::"\
L"Request" L ## #NAME L"()#"\
L"Id of a message sending to IGuiRemoteProtocol should be increasing.");\
lastRequestId = id;\
FilteredRequest request;\
request.id = id;\
request.name = FilteredRequestNames::NAME;\
filteredRequests.Add(request);\
eventCombinator.responseIds.Add(id, FilteredResponseNames::NAME);\
}\
#define MESSAGE_REQ_NORES(NAME, REQUEST, RESPONSE, DROPTAG)\
void GuiRemoteProtocolFilter::Request ## NAME(const REQUEST& arguments)\
{\
MESSAGE_ ## DROPTAG(NAME);\
FilteredRequest request;\
request.name = FilteredRequestNames::NAME;\
request.arguments = arguments;\
filteredRequests.Add(request);\
}\
#define MESSAGE_REQ_RES(NAME, REQUEST, RESPONSE, DROPTAG)\
void GuiRemoteProtocolFilter::Request ## NAME(vint id, const REQUEST& arguments)\
{\
MESSAGE_ ## DROPTAG(NAME);\
CHECK_ERROR(\
lastRequestId < id,\
L"vl::presentation::remoteprotocol::GuiRemoteProtocolFilter::"\
L"Request" L ## #NAME L"()#"\
L"Id of a message sending to IGuiRemoteProtocol should be increasing.");\
lastRequestId = id;\
FilteredRequest request;\
request.id = id;\
request.name = FilteredRequestNames::NAME;\
request.arguments = arguments;\
filteredRequests.Add(request);\
eventCombinator.responseIds.Add(id, FilteredResponseNames::NAME);\
}\
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, DROPTAG, ...) MESSAGE_ ## REQTAG ## _ ## RESTAG(NAME, REQUEST, RESPONSE, DROPTAG)
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
#undef MESSAGE_HANDLER
#undef MESSAGE_REQ_RES
#undef MESSAGE_REQ_NORES
#undef MESSAGE_NOREQ_RES
#undef MESSAGE_NOREQ_NORES
#undef MESSAGE_DROPREP
#undef MESSAGE_NODROP
// protocol
void GuiRemoteProtocolFilter::Initialize(IGuiRemoteProtocolEvents* _events)
{
if (auto verifierProtocol = dynamic_cast<GuiRemoteProtocolFilterVerifier*>(targetProtocol))
{
verifierProtocol->targetProtocol->Initialize(&eventCombinator);
eventCombinator.targetEvents = &verifierProtocol->eventCombinator;
verifierProtocol->eventCombinator.targetEvents = _events;
}
else
{
GuiRemoteProtocolCombinator<GuiRemoteEventFilter>::Initialize(_events);
}
}
void GuiRemoteProtocolFilter::Submit(bool& disconnected)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::repeatfiltering::GuiRemoteProtocolFilter::Submit()#"
CHECK_ERROR(!eventCombinator.submitting, ERROR_MESSAGE_PREFIX L"This function is not allowed to be called recursively.");
eventCombinator.submitting = true;
ProcessRequests();
GuiRemoteProtocolCombinator<GuiRemoteEventFilter>::Submit(disconnected);
if (disconnected)
{
eventCombinator.responseIds.Clear();
}
else
{
eventCombinator.ProcessResponses();
}
eventCombinator.submitting = false;
eventCombinator.ProcessEvents();
#undef ERROR_MESSAGE_PREFIX
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\GUIREMOTEPROTOCOL_FILTERVERIFIER.CPP
***********************************************************************/
namespace vl::presentation::remoteprotocol::repeatfiltering
{
/***********************************************************************
GuiRemoteEventFilterVerifier
***********************************************************************/
GuiRemoteEventFilterVerifier::GuiRemoteEventFilterVerifier()
{
}
GuiRemoteEventFilterVerifier::~GuiRemoteEventFilterVerifier()
{
}
void GuiRemoteEventFilterVerifier::ClearDropRepeatMasks()
{
#define EVENT_NODROP(NAME)
#define EVENT_DROPREP(NAME) lastDropRepeatEvent ## NAME = false;
#define EVENT_DROPCON(NAME)
#define EVENT_HANDLER(NAME, REQUEST, REQTAG, DROPTAG, ...) EVENT_ ## DROPTAG(NAME)
GACUI_REMOTEPROTOCOL_EVENTS(EVENT_HANDLER)
#undef EVENT_HANDLER
#undef EVENT_DROPCON
#undef EVENT_DROPREP
#undef EVENT_NODROP
}
void GuiRemoteEventFilterVerifier::ClearDropConsecutiveMasks()
{
#define EVENT_NODROP(NAME)
#define EVENT_DROPREP(NAME)
#define EVENT_DROPCON(NAME) lastDropConsecutiveEvent ## NAME = false;
#define EVENT_HANDLER(NAME, REQUEST, REQTAG, DROPTAG, ...) EVENT_ ## DROPTAG(NAME)
GACUI_REMOTEPROTOCOL_EVENTS(EVENT_HANDLER)
#undef EVENT_HANDLER
#undef EVENT_DROPCON
#undef EVENT_DROPREP
#undef EVENT_NODROP
}
// responses
#define MESSAGE_NORES(NAME, RESPONSE)
#define MESSAGE_RES(NAME, RESPONSE)\
void GuiRemoteEventFilterVerifier::Respond ## NAME(vint id, const RESPONSE& arguments)\
{\
targetEvents->Respond ## NAME(id, arguments);\
}\
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, ...) MESSAGE_ ## RESTAG(NAME, RESPONSE)
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
#undef MESSAGE_HANDLER
#undef MESSAGE_RES
#undef MESSAGE_NORES
// events
#define EVENT_NODROP(NAME)
#define EVENT_DROPREP(NAME)\
CHECK_ERROR(!lastDropRepeatEvent ## NAME, L"vl::presentation::remoteprotocol::GuiRemoteEventFilterVerifier::On" L ## #NAME L"(...)#[@DropRepeat] event repeated.");\
lastDropRepeatEvent ## NAME = true;\
#define EVENT_DROPCON(NAME)\
CHECK_ERROR(!lastDropConsecutiveEvent ## NAME, L"vl::presentation::remoteprotocol::GuiRemoteEventFilterVerifier::On" L ## #NAME L"(...)#[@DropConsecutive] event repeated.");\
ClearDropConsecutiveMasks();\
lastDropConsecutiveEvent ## NAME = true;\
#define EVENT_NOREQ(NAME, REQUEST, DROPTAG)\
void GuiRemoteEventFilterVerifier::On ## NAME()\
{\
if (submitting)\
{\
EVENT_ ## DROPTAG(NAME);\
targetEvents->On ## NAME();\
}\
else\
{\
targetEvents->On ## NAME();\
}\
}\
#define EVENT_REQ(NAME, REQUEST, DROPTAG)\
void GuiRemoteEventFilterVerifier::On ## NAME(const REQUEST& arguments)\
{\
if (submitting)\
{\
EVENT_ ## DROPTAG(NAME);\
targetEvents->On ## NAME(arguments);\
}\
else\
{\
targetEvents->On ## NAME(arguments);\
}\
}\
#define EVENT_HANDLER(NAME, REQUEST, REQTAG, DROPTAG, ...) EVENT_ ## REQTAG(NAME, REQUEST, DROPTAG)
GACUI_REMOTEPROTOCOL_EVENTS(EVENT_HANDLER)
#undef EVENT_HANDLER
#undef EVENT_REQ
#undef EVENT_NOREQ
#undef EVENT_DROPCON
#undef EVENT_DROPREP
#undef EVENT_NOREP
/***********************************************************************
GuiRemoteProtocolFilterVerifier
***********************************************************************/
void GuiRemoteProtocolFilterVerifier::ClearDropRepeatMasks()
{
#define MESSAGE_NODROP(NAME)
#define MESSAGE_DROPREP(NAME) lastDropRepeatRequest ## NAME = false;
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, DROPTAG) MESSAGE_ ## DROPTAG(NAME)
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
#undef MESSAGE_HANDLER
#undef MESSAGE_DROPREP
#undef MESSAGE_NODROP
}
GuiRemoteProtocolFilterVerifier::GuiRemoteProtocolFilterVerifier(IGuiRemoteProtocol* _protocol)
: GuiRemoteProtocolCombinator<GuiRemoteEventFilterVerifier>(_protocol)
{
}
GuiRemoteProtocolFilterVerifier::~GuiRemoteProtocolFilterVerifier()
{
}
// messages
#define MESSAGE_NODROP(NAME)
#define MESSAGE_DROPREP(NAME)\
CHECK_ERROR(!lastDropRepeatRequest ## NAME, L"vl::presentation::remoteprotocol::GuiRemoteProtocolFilterVerifier::Request" L ## #NAME L"(...)#[@DropRepeat] message repeated.");\
lastDropRepeatRequest ## NAME = true;\
#define MESSAGE_NOREQ_NORES(NAME, REQUEST, RESPONSE, DROPTAG)\
void GuiRemoteProtocolFilterVerifier::Request ## NAME()\
{\
MESSAGE_ ## DROPTAG(NAME);\
targetProtocol->Request ## NAME();\
}\
#define MESSAGE_NOREQ_RES(NAME, REQUEST, RESPONSE, DROPTAG)\
void GuiRemoteProtocolFilterVerifier::Request ## NAME(vint id)\
{\
MESSAGE_ ## DROPTAG(NAME);\
targetProtocol->Request ## NAME(id);\
}\
#define MESSAGE_REQ_NORES(NAME, REQUEST, RESPONSE, DROPTAG)\
void GuiRemoteProtocolFilterVerifier::Request ## NAME(const REQUEST& arguments)\
{\
MESSAGE_ ## DROPTAG(NAME);\
targetProtocol->Request ## NAME(arguments);\
}\
#define MESSAGE_REQ_RES(NAME, REQUEST, RESPONSE, DROPTAG)\
void GuiRemoteProtocolFilterVerifier::Request ## NAME(vint id, const REQUEST& arguments)\
{\
MESSAGE_ ## DROPTAG(NAME);\
targetProtocol->Request ## NAME(id, arguments);\
}\
#define MESSAGE_HANDLER(NAME, REQUEST, RESPONSE, REQTAG, RESTAG, DROPTAG, ...) MESSAGE_ ## REQTAG ## _ ## RESTAG(NAME, REQUEST, RESPONSE, DROPTAG)
GACUI_REMOTEPROTOCOL_MESSAGES(MESSAGE_HANDLER)
#undef MESSAGE_HANDLER
#undef MESSAGE_REQ_RES
#undef MESSAGE_REQ_NORES
#undef MESSAGE_NOREQ_RES
#undef MESSAGE_NOREQ_NORES
#undef MESSAGE_DROPREP
#undef MESSAGE_NODROP
// protocol
void GuiRemoteProtocolFilterVerifier::Submit(bool& disconnected)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::repeatfiltering::GuiRemoteProtocolFilterVerifier::Submit()#"
CHECK_ERROR(!eventCombinator.submitting, ERROR_MESSAGE_PREFIX L"This function is not allowed to be called recursively.");
eventCombinator.submitting = true;
GuiRemoteProtocolCombinator<GuiRemoteEventFilterVerifier>::Submit(disconnected);
ClearDropRepeatMasks();
eventCombinator.ClearDropRepeatMasks();
eventCombinator.ClearDropConsecutiveMasks();
eventCombinator.submitting = false;
#undef ERROR_MESSAGE_PREFIX
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\GUIREMOTEWINDOW.CPP
***********************************************************************/
namespace vl::presentation
{
/***********************************************************************
GuiRemoteWindow
***********************************************************************/
#define SET_REMOTE_WINDOW_STYLE(STYLE, VALUE)\
if (style ## STYLE != VALUE)\
{\
style ## STYLE = VALUE;\
remoteMessages.RequestWindowNotifySet ## STYLE(VALUE);\
}\
#define SET_REMOTE_WINDOW_STYLE_INVALIDATE(STYLE, VALUE)\
if (style ## STYLE != VALUE)\
{\
style ## STYLE = VALUE;\
sizingConfigInvalidated = true;\
remoteMessages.RequestWindowNotifySet ## STYLE(VALUE);\
}\
void GuiRemoteWindow::RequestGetBounds()
{
vint idGetBounds = remoteMessages.RequestWindowGetBounds();
bool disconnected = false;
remoteMessages.Submit(disconnected);
if (disconnected) return;
sizingConfigInvalidated = false;
OnWindowBoundsUpdated(remoteMessages.RetrieveWindowGetBounds(idGetBounds));
}
void GuiRemoteWindow::Opened()
{
if (!statusVisible)
{
statusVisible = true;
for (auto l : listeners)l->Opened();
}
}
void GuiRemoteWindow::SetActivated(bool activated)
{
if (statusActivated != activated)
{
statusActivated = activated;
if (statusActivated)
{
for (auto l : listeners)l->GotFocus();
for (auto l : listeners)l->RenderingAsActivated();
}
else
{
for (auto l : listeners)l->LostFocus();
for (auto l : listeners)l->RenderingAsDeactivated();
}
}
}
void GuiRemoteWindow::ShowWithSizeState(bool activate, INativeWindow::WindowSizeState sizeState)
{
if (!statusVisible || remoteWindowSizingConfig.sizeState != sizeState)
{
remoteprotocol::WindowShowing windowShowing;
windowShowing.activate = activate;
windowShowing.sizeState = sizeState;
remoteMessages.RequestWindowNotifyShow(windowShowing);
bool disconnected = false;
remoteMessages.Submit(disconnected);
// there is no result from this request, assuming succeeded
remoteWindowSizingConfig.sizeState = sizeState;
Opened();
SetActivated(activate);
}
else if (!statusActivated && activate)
{
SetActivate();
}
}
/***********************************************************************
GuiRemoteWindow (events)
***********************************************************************/
void GuiRemoteWindow::OnControllerConnect()
{
if (disconnected)
{
disconnected = false;
}
sizingConfigInvalidated = true;
remoteMessages.RequestWindowNotifySetBounds(remoteWindowSizingConfig.bounds);
RequestGetBounds();
// TODO:
// This is a workaround to call GuiWindow::UpdateCustomFramePadding
// Refactor to make it more elegant.
for (auto l : listeners) l->DpiChanged(true);
for (auto l : listeners) l->DpiChanged(false);
if (remote->applicationRunning)
{
remoteMessages.RequestWindowNotifySetTitle(styleTitle);
remoteMessages.RequestWindowNotifySetEnabled(styleEnabled);
remoteMessages.RequestWindowNotifySetTopMost(styleTopMost);
remoteMessages.RequestWindowNotifySetShowInTaskBar(styleShowInTaskBar);
remoteMessages.RequestWindowNotifySetCustomFrameMode(styleCustomFrameMode);
remoteMessages.RequestWindowNotifySetMaximizedBox(styleMaximizedBox);
remoteMessages.RequestWindowNotifySetMinimizedBox(styleMinimizedBox);
remoteMessages.RequestWindowNotifySetBorder(styleBorder);
remoteMessages.RequestWindowNotifySetSizeBox(styleSizeBox);
remoteMessages.RequestWindowNotifySetIconVisible(styleIconVisible);
remoteMessages.RequestWindowNotifySetTitleBar(styleTitleBar);
if (statusCapturing)
{
remoteMessages.RequestIORequireCapture();
}
else
{
remoteMessages.RequestIOReleaseCapture();
}
bool disconnected = false;
remoteMessages.Submit(disconnected);
// there is no result from this request, assuming succeeded
}
}
void GuiRemoteWindow::OnControllerDisconnect()
{
disconnected = true;
}
void GuiRemoteWindow::OnControllerScreenUpdated(const remoteprotocol::ScreenConfig& arguments)
{
if (scalingX != arguments.scalingX || scalingY != arguments.scalingY)
{
scalingX = arguments.scalingX;
scalingY = arguments.scalingY;
for (auto l : listeners) l->DpiChanged(true);
for (auto l : listeners) l->DpiChanged(false);
}
}
void GuiRemoteWindow::OnWindowBoundsUpdated(const remoteprotocol::WindowSizingConfig& arguments)
{
bool callMoved = false;
if (remoteWindowSizingConfig.bounds != arguments.bounds ||
remoteWindowSizingConfig.clientBounds != arguments.clientBounds)
{
callMoved = true;
}
remoteWindowSizingConfig = arguments;
if(callMoved)
{
for (auto l : listeners) l->Moved();
}
}
void GuiRemoteWindow::OnWindowActivatedUpdated(bool activated)
{
SetActivated(activated);
}
/***********************************************************************
GuiRemoteWindow
***********************************************************************/
GuiRemoteWindow::GuiRemoteWindow(GuiRemoteController* _remote)
: remote(_remote)
, remoteMessages(_remote->remoteMessages)
, remoteEvents(_remote->remoteEvents)
{
remoteWindowSizingConfig.sizeState = INativeWindow::Restored;
}
GuiRemoteWindow::~GuiRemoteWindow()
{
}
/***********************************************************************
GuiRemoteWindow (INativeWindow)
***********************************************************************/
bool GuiRemoteWindow::IsActivelyRefreshing()
{
return true;
}
NativeSize GuiRemoteWindow::GetRenderingOffset()
{
return { 0,0 };
}
Point GuiRemoteWindow::Convert(NativePoint value)
{
return Point((vint)(value.x.value / scalingX), (vint)(value.y.value / scalingY));
}
NativePoint GuiRemoteWindow::Convert(Point value)
{
return NativePoint((vint)(value.x * scalingX), (vint)(value.y * scalingY));
}
Size GuiRemoteWindow::Convert(NativeSize value)
{
return Size((vint)(value.x.value / scalingX), (vint)(value.y.value / scalingY));
}
NativeSize GuiRemoteWindow::Convert(Size value)
{
return NativeSize((vint)(value.x * scalingX), (vint)(value.y * scalingY));
}
Margin GuiRemoteWindow::Convert(NativeMargin value)
{
return Margin(
(vint)(value.left.value / scalingX),
(vint)(value.top.value / scalingY),
(vint)(value.right.value / scalingX),
(vint)(value.bottom.value / scalingY)
);
}
NativeMargin GuiRemoteWindow::Convert(Margin value)
{
return NativeMargin(
(vint)(value.left * scalingX),
(vint)(value.top * scalingY),
(vint)(value.right * scalingX),
(vint)(value.bottom * scalingY)
);
}
NativeRect GuiRemoteWindow::GetBounds()
{
if (sizingConfigInvalidated) RequestGetBounds();
return remoteWindowSizingConfig.bounds;
}
void GuiRemoteWindow::SetBounds(const NativeRect& bounds)
{
if (remoteWindowSizingConfig.bounds != bounds)
{
auto x1 = remoteWindowSizingConfig.clientBounds.x1 - remoteWindowSizingConfig.bounds.x1;
auto y1 = remoteWindowSizingConfig.clientBounds.y1 - remoteWindowSizingConfig.bounds.y1;
auto x2 = remoteWindowSizingConfig.clientBounds.x2 - remoteWindowSizingConfig.bounds.x2;
auto y2 = remoteWindowSizingConfig.clientBounds.y2 - remoteWindowSizingConfig.bounds.y2;
remoteWindowSizingConfig.bounds = bounds;
remoteWindowSizingConfig.clientBounds = {
x1 + remoteWindowSizingConfig.bounds.x1,
y1 + remoteWindowSizingConfig.bounds.y1,
x2 + remoteWindowSizingConfig.bounds.x2,
y2 + remoteWindowSizingConfig.bounds.y2
};
remoteMessages.RequestWindowNotifySetBounds(bounds);
sizingConfigInvalidated = true;
}
}
NativeSize GuiRemoteWindow::GetClientSize()
{
if (sizingConfigInvalidated) RequestGetBounds();
return remoteWindowSizingConfig.clientBounds.GetSize();
}
void GuiRemoteWindow::SetClientSize(NativeSize size)
{
if (remoteWindowSizingConfig.clientBounds.GetSize() != size)
{
auto x1 = remoteWindowSizingConfig.bounds.x1 - remoteWindowSizingConfig.clientBounds.x1;
auto y1 = remoteWindowSizingConfig.bounds.y1 - remoteWindowSizingConfig.clientBounds.y1;
auto x2 = remoteWindowSizingConfig.bounds.x2 - remoteWindowSizingConfig.clientBounds.x2;
auto y2 = remoteWindowSizingConfig.bounds.y2 - remoteWindowSizingConfig.clientBounds.y2;
remoteWindowSizingConfig.clientBounds = { remoteWindowSizingConfig.clientBounds.LeftTop(),size };
remoteWindowSizingConfig.bounds = {
x1 + remoteWindowSizingConfig.clientBounds.x1,
y1 + remoteWindowSizingConfig.clientBounds.y1,
x2 + remoteWindowSizingConfig.clientBounds.x2,
y2 + remoteWindowSizingConfig.clientBounds.y2
};
remoteMessages.RequestWindowNotifySetClientSize(size);
sizingConfigInvalidated = true;
}
}
NativeRect GuiRemoteWindow::GetClientBoundsInScreen()
{
auto bounds = remoteWindowSizingConfig.clientBounds;
bounds.x1.value += remoteWindowSizingConfig.bounds.x1.value;
bounds.y1.value += remoteWindowSizingConfig.bounds.y1.value;
bounds.x2.value += remoteWindowSizingConfig.bounds.x1.value;
bounds.y2.value += remoteWindowSizingConfig.bounds.y1.value;
return bounds;
}
WString GuiRemoteWindow::GetTitle()
{
return styleTitle;
}
void GuiRemoteWindow::SetTitle(const WString& title)
{
SET_REMOTE_WINDOW_STYLE(Title, title);
}
INativeCursor* GuiRemoteWindow::GetWindowCursor()
{
if (!styleCursor)
{
styleCursor = remote->ResourceService()->GetDefaultSystemCursor();
}
return styleCursor;
}
void GuiRemoteWindow::SetWindowCursor(INativeCursor* cursor)
{
styleCursor = cursor;
}
NativePoint GuiRemoteWindow::GetCaretPoint()
{
return styleCaret;
}
void GuiRemoteWindow::SetCaretPoint(NativePoint point)
{
styleCaret = point;
}
INativeWindow* GuiRemoteWindow::GetParent()
{
return nullptr;
}
void GuiRemoteWindow::SetParent(INativeWindow* parent)
{
CHECK_FAIL(L"vl::presentation::GuiRemoteWindow::SetParent(INativeWindow*)#GuiHostedController is not supposed to call this.");
}
INativeWindow::WindowMode GuiRemoteWindow::GetWindowMode()
{
return windowMode;
}
void GuiRemoteWindow::EnableCustomFrameMode()
{
SET_REMOTE_WINDOW_STYLE_INVALIDATE(CustomFrameMode, true);
}
void GuiRemoteWindow::DisableCustomFrameMode()
{
SET_REMOTE_WINDOW_STYLE_INVALIDATE(CustomFrameMode, false);
}
bool GuiRemoteWindow::IsCustomFrameModeEnabled()
{
return styleCustomFrameMode;
}
NativeMargin GuiRemoteWindow::GetCustomFramePadding()
{
return remoteWindowSizingConfig.customFramePadding;
}
Ptr<GuiImageData> GuiRemoteWindow::GetIcon()
{
return styleIcon;
}
void GuiRemoteWindow::SetIcon(Ptr<GuiImageData> icon)
{
styleIcon = icon;
}
INativeWindow::WindowSizeState GuiRemoteWindow::GetSizeState()
{
return remoteWindowSizingConfig.sizeState;
}
void GuiRemoteWindow::Show()
{
ShowWithSizeState(true, remoteWindowSizingConfig.sizeState);
}
void GuiRemoteWindow::ShowDeactivated()
{
ShowWithSizeState(false, remoteWindowSizingConfig.sizeState);
}
void GuiRemoteWindow::ShowRestored()
{
ShowWithSizeState(true, INativeWindow::Restored);
}
void GuiRemoteWindow::ShowMaximized()
{
ShowWithSizeState(true, INativeWindow::Maximized);
}
void GuiRemoteWindow::ShowMinimized()
{
ShowWithSizeState(true, INativeWindow::Minimized);
}
void GuiRemoteWindow::Hide(bool closeWindow)
{
if (!remote->connectionForcedToStop)
{
bool cancel = false;
for (auto l : listeners)
{
l->BeforeClosing(cancel);
if (cancel) return;
}
for (auto l : listeners) l->AfterClosing();
}
remote->AsyncService()->InvokeInMainThread(this, [this]()
{
remote->DestroyNativeWindow(this);
});
}
bool GuiRemoteWindow::IsVisible()
{
return statusVisible;
}
void GuiRemoteWindow::Enable()
{
if (styleEnabled != true)
{
styleEnabled = true;
remoteMessages.RequestWindowNotifySetEnabled(true);
for (auto l : listeners) l->Enabled();
}
}
void GuiRemoteWindow::Disable()
{
if (styleEnabled != false)
{
styleEnabled = false;
remoteMessages.RequestWindowNotifySetEnabled(false);
for (auto l : listeners) l->Disabled();
}
}
bool GuiRemoteWindow::IsEnabled()
{
return styleEnabled;
}
void GuiRemoteWindow::SetActivate()
{
if (statusActivated != true)
{
SetActivated(true);
remoteMessages.RequestWindowNotifyActivate();
}
}
bool GuiRemoteWindow::IsActivated()
{
return statusActivated;
}
bool GuiRemoteWindow::IsRenderingAsActivated()
{
return statusActivated;
}
void GuiRemoteWindow::ShowInTaskBar()
{
SET_REMOTE_WINDOW_STYLE(ShowInTaskBar, true);
}
void GuiRemoteWindow::HideInTaskBar()
{
SET_REMOTE_WINDOW_STYLE(ShowInTaskBar, false);
}
bool GuiRemoteWindow::IsAppearedInTaskBar()
{
return styleShowInTaskBar;
}
void GuiRemoteWindow::EnableActivate()
{
CHECK_FAIL(L"vl::presentation::GuiRemoteWindow::EnableActivate()#GuiHostedController is not supposed to call this.");
}
void GuiRemoteWindow::DisableActivate()
{
CHECK_FAIL(L"vl::presentation::GuiRemoteWindow::EnableActivate()#GuiHostedController is not supposed to call this.");
}
bool GuiRemoteWindow::IsEnabledActivate()
{
return true;
}
bool GuiRemoteWindow::RequireCapture()
{
if (!statusCapturing)
{
statusCapturing = true;
remoteMessages.RequestIORequireCapture();
bool disconnected = false;
remoteMessages.Submit(disconnected);
// there is no result from this request, assuming succeeded
}
return true;
}
bool GuiRemoteWindow::ReleaseCapture()
{
if (statusCapturing)
{
statusCapturing = false;
remoteMessages.RequestIOReleaseCapture();
bool disconnected = false;
remoteMessages.Submit(disconnected);
// there is no result from this request, assuming succeeded
}
return true;
}
bool GuiRemoteWindow::IsCapturing()
{
return statusCapturing;
}
bool GuiRemoteWindow::GetMaximizedBox()
{
return styleMaximizedBox;
}
void GuiRemoteWindow::SetMaximizedBox(bool visible)
{
SET_REMOTE_WINDOW_STYLE_INVALIDATE(MaximizedBox, visible);
}
bool GuiRemoteWindow::GetMinimizedBox()
{
return styleMinimizedBox;
}
void GuiRemoteWindow::SetMinimizedBox(bool visible)
{
SET_REMOTE_WINDOW_STYLE_INVALIDATE(MinimizedBox, visible);
}
bool GuiRemoteWindow::GetBorder()
{
return styleBorder;
}
void GuiRemoteWindow::SetBorder(bool visible)
{
SET_REMOTE_WINDOW_STYLE_INVALIDATE(Border, visible);
}
bool GuiRemoteWindow::GetSizeBox()
{
return styleSizeBox;
}
void GuiRemoteWindow::SetSizeBox(bool visible)
{
SET_REMOTE_WINDOW_STYLE_INVALIDATE(SizeBox, visible);
}
bool GuiRemoteWindow::GetIconVisible()
{
return styleIconVisible;
}
void GuiRemoteWindow::SetIconVisible(bool visible)
{
SET_REMOTE_WINDOW_STYLE_INVALIDATE(IconVisible, visible);
}
bool GuiRemoteWindow::GetTitleBar()
{
return styleTitleBar;
}
void GuiRemoteWindow::SetTitleBar(bool visible)
{
SET_REMOTE_WINDOW_STYLE_INVALIDATE(TitleBar, visible);
}
bool GuiRemoteWindow::GetTopMost()
{
return styleTopMost;
}
void GuiRemoteWindow::SetTopMost(bool topmost)
{
SET_REMOTE_WINDOW_STYLE(TopMost, topmost);
}
void GuiRemoteWindow::SupressAlt()
{
}
bool GuiRemoteWindow::InstallListener(INativeWindowListener* listener)
{
if (listeners.Contains(listener))
{
return false;
}
else
{
listeners.Add(listener);
return true;
}
}
bool GuiRemoteWindow::UninstallListener(INativeWindowListener* listener)
{
if (listeners.Contains(listener))
{
listeners.Remove(listener);
return true;
}
else
{
return false;
}
}
void GuiRemoteWindow::RedrawContent()
{
}
#undef SET_REMOTE_WINDOW_STYLE_INVALIDATE
#undef SET_REMOTE_WINDOW_STYLE
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\PROTOCOL\FRAMEOPERATIONS\GUIREMOTEPROTOCOLSCHEMA_BUILDFRAME.CPP
***********************************************************************/
namespace vl::presentation::remoteprotocol
{
vint RenderingDomBuilder::GetCurrentBoundary()
{
if (domBoundaries.Count() > 0)
{
return domBoundaries[domBoundaries.Count() - 1];
}
else
{
return 0;
}
}
vint RenderingDomBuilder::Push(RenderingResultRef ref)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::RenderingDomBuilder::Push(RenderingResultRef)#"
CHECK_ERROR(ref, ERROR_MESSAGE_PREFIX L"Cannot push a null dom object.");
vint index = domStack.Add(ref);
if (!domCurrent->children) domCurrent->children = Ptr(new RenderingResultRefList);
domCurrent->children->Add(ref);
domCurrent = ref;
return index;
#undef ERROR_MESSAGE_PREFIX
}
void RenderingDomBuilder::PopTo(vint index)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::RenderingDomBuilder::PopTo(vint)#"
if (index == domStack.Count() - 1) return;
CHECK_ERROR(0 <= index && index < domStack.Count(), ERROR_MESSAGE_PREFIX L"Cannot pop to an invalid position.");
CHECK_ERROR(index >= GetCurrentBoundary(), ERROR_MESSAGE_PREFIX L"Cannot pop across a boundary.");
while (domStack.Count() - 1 > index)
{
domStack.RemoveAt(domStack.Count() - 1);
}
domCurrent = domStack[index];
#undef ERROR_MESSAGE_PREFIX
}
void RenderingDomBuilder::Pop()
{
PopTo(domStack.Count() - 2);
}
void RenderingDomBuilder::PopBoundary()
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::RenderingDomBuilder::PopBoundary()#"
CHECK_ERROR(domBoundaries.Count() > 0, ERROR_MESSAGE_PREFIX L"Cannot pop a boundary when none is in the stack.");
auto boundaryIndex = domBoundaries.Count() - 1;
auto boundary = domBoundaries[boundaryIndex];
domBoundaries.RemoveAt(boundaryIndex);
PopTo(boundary - 1);
#undef ERROR_MESSAGE_PREFIX
}
template<typename TCallback>
void RenderingDomBuilder::PrepareParentFromCommand(Rect commandBounds, Rect commandValidArea, vint newDomId, TCallback&& calculateValidAreaFromDom)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::RenderingDomBuilder::PrepareParentFromCommand(Rect, Rect, vint, auto&&)#"
vint min = GetCurrentBoundary();
bool found = false;
if (commandValidArea.Contains(commandBounds))
{
// if the command is not clipped
for (vint i = domStack.Count() - 1; i >= min; i--)
{
if (domStack[i]->content.validArea.Contains(commandBounds) || i == 0)
{
// find the deepest node that could contain the command
PopTo(i);
found = true;
break;
}
}
}
else
{
// otherwise, a parent node causing such clipping should be found or created
for (vint i = domStack.Count() - 1; i >= min; i--)
{
auto domValidArea = calculateValidAreaFromDom(domStack[i]);
if (domValidArea == commandValidArea)
{
// if there is a node who clips command's bound to its valid area
// that is the parent node of the command
PopTo(i);
found = true;
break;
}
else if (domValidArea.Contains(commandValidArea) || i == 0)
{
// otherwise find a deepest node who could visually contain the command
// create a virtual node to satisfy the clipper
PopTo(i);
auto parent = Ptr(new RenderingDom);
parent->id = newDomId;
parent->content.bounds = commandValidArea;
parent->content.validArea = commandValidArea;
Push(parent);
found = true;
break;
}
}
}
// if the new boundary could not fit in the current boundary
// there must be something wrong
CHECK_ERROR(found, ERROR_MESSAGE_PREFIX L"Incorrect valid area of dom.");
#undef ERROR_MESSAGE_PREFIX
}
void RenderingDomBuilder::RequestRendererBeginRendering()
{
domStack.Clear();
domBoundaries.Clear();
domRoot = Ptr(new RenderingDom);
domRoot->id = -1;
domCurrent = domRoot;
domStack.Add(domRoot);
}
void RenderingDomBuilder::RequestRendererBeginBoundary(const remoteprotocol::ElementBoundary& arguments)
{
// a new boundary should be a new node covering existing nodes
// the valid area of boundary is clipped by its bounds
// so the valid area to compare from its potential parent dom needs to clipped by its bounds
PrepareParentFromCommand(
arguments.bounds,
arguments.areaClippedBySelf,
(arguments.id << 2) + 3,
[&](auto&& dom) { return dom->content.validArea.Intersect(arguments.bounds); }
);
auto dom = Ptr(new RenderingDom);
dom->id = (arguments.id << 2) + 2;
dom->content.hitTestResult = arguments.hitTestResult;
dom->content.cursor = arguments.cursor;
dom->content.bounds = arguments.bounds;
dom->content.validArea = arguments.areaClippedBySelf;
domBoundaries.Add(Push(dom));
}
void RenderingDomBuilder::RequestRendererEndBoundary()
{
PopBoundary();
}
void RenderingDomBuilder::RequestRendererRenderElement(const remoteprotocol::ElementRendering& arguments)
{
// a new element should be a new node covering existing nodes
// the valid area of boundary is clipped by its parent
// so the valid area to compare from its potential parent dom is its valid area
PrepareParentFromCommand(
arguments.bounds,
arguments.areaClippedByParent,
(arguments.id << 2) + 1,
[&](auto&& dom) { return dom->content.validArea; }
);
auto dom = Ptr(new RenderingDom);
dom->id = (arguments.id << 2) + 0;
dom->content.element = arguments.id;
dom->content.bounds = arguments.bounds;
dom->content.validArea = arguments.bounds.Intersect(arguments.areaClippedByParent);
Push(dom);
}
Ptr<RenderingDom> RenderingDomBuilder::RequestRendererEndRendering()
{
return domRoot;
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\PROTOCOL\FRAMEOPERATIONS\GUIREMOTEPROTOCOLSCHEMA_COPYDOM.CPP
***********************************************************************/
namespace vl::presentation::remoteprotocol
{
using namespace collections;
Ptr<RenderingDom> CopyDom(Ptr<RenderingDom> root)
{
auto newRoot = Ptr(new RenderingDom);
newRoot->id = root->id;
newRoot->content = root->content;
if (root->children)
{
newRoot->children = Ptr(new List<Ptr<RenderingDom>>);
for (auto child : *root->children.Obj())
{
newRoot->children->Add(CopyDom(child));
}
}
return newRoot;
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\PROTOCOL\FRAMEOPERATIONS\GUIREMOTEPROTOCOLSCHEMA_DIFFFRAME.CPP
***********************************************************************/
namespace vl::presentation::remoteprotocol
{
using namespace collections;
vint CountDomIndex(Ptr<RenderingDom> root)
{
vint counter = 1;
if (root->children)
{
for (auto child : *root->children.Obj())
{
counter += CountDomIndex(child);
}
}
return counter;
}
void BuildDomIndexInternal(Ptr<RenderingDom> dom, vint parentId, DomIndex& index, vint& writing)
{
index[writing++] = { dom->id,parentId,dom };
if (dom->children)
{
for (auto child : *dom->children.Obj())
{
BuildDomIndexInternal(child, dom->id, index, writing);
}
}
}
void SortDomIndex(DomIndex& index)
{
if (index.Count() > 0)
{
SortLambda(&index[0], index.Count(), [](const DomIndexItem& a, const DomIndexItem& b)
{
return a.id <=> b.id;
});
}
}
void BuildDomIndex(Ptr<RenderingDom> root, DomIndex& index)
{
vint count = CountDomIndex(root);
vint writing = 0;
index.Resize(count);
if (count > 0)
{
BuildDomIndexInternal(root, -1, index, writing);
SortDomIndex(index);
}
}
void UpdateDomInplace(Ptr<RenderingDom> root, DomIndex& index, const RenderingDom_DiffsInOrder& diffs)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::UpdateDomInplace(Ptr<RenderingDom>, DomIndex&, const RenderingDom_DiffsInOrder&)#"
CHECK_ERROR(root && root->id == -1, ERROR_MESSAGE_PREFIX L"Roots of a DOM must have ID -1.");
vint createdCount = 0;
// creating
{
vint readingFrom = 0;
vint readingTo = 0;
auto markCreated = [&]()
{
auto&& to = diffs.diffsInOrder->Get(readingTo++);
CHECK_ERROR(to.diffType == RenderingDom_DiffType::Created, ERROR_MESSAGE_PREFIX L"Diff of unexisting node must have diffType == Created.");
createdCount++;
};
while (diffs.diffsInOrder && readingTo < diffs.diffsInOrder->Count())
{
if (readingFrom < index.Count())
{
auto&& from = index[readingFrom];
auto&& to = diffs.diffsInOrder->Get(readingTo);
if (from.id < to.id)
{
// Nothing happened to this DOM node
readingFrom++;
}
else if (from.id > to.id)
{
markCreated();
}
else
{
// Modified will be delayed and processed together with Created
readingFrom++;
readingTo++;
CHECK_ERROR(to.diffType != RenderingDom_DiffType::Created, ERROR_MESSAGE_PREFIX L"Diff of existing node must have diffType != Created.");
}
}
else
{
markCreated();
}
}
}
{
vint writing = index.Count();
index.Resize(index.Count() + createdCount);
if (diffs.diffsInOrder)
{
for (auto&& to : *diffs.diffsInOrder.Obj())
{
if (to.diffType == RenderingDom_DiffType::Created)
{
// parentId will be filled later
auto dom = Ptr(new RenderingDom);
dom->id = to.id;
index[writing++] = { to.id,-1,dom };
}
}
}
SortDomIndex(index);
}
// modifying
{
vint readingFrom = 0;
vint readingTo = 0;
while (readingFrom < index.Count() && (diffs.diffsInOrder && readingTo < diffs.diffsInOrder->Count()))
{
bool hasFrom = readingFrom < index.Count();
bool hasTo = diffs.diffsInOrder && readingTo < diffs.diffsInOrder->Count();
auto&& from = index[readingFrom];
auto&& to = diffs.diffsInOrder->Get(readingTo);
if (from.id < to.id)
{
readingFrom++;
}
else if (from.id > to.id)
{
readingTo++;
}
else
{
readingFrom++;
readingTo++;
if (to.diffType != RenderingDom_DiffType::Deleted)
{
if (to.content)
{
from.dom->content = to.content.Value();
}
if (to.children)
{
if (to.children->Count() == 0)
{
from.dom->children = nullptr;
}
else
{
from.dom->children = Ptr(new List<Ptr<RenderingDom>>);
for (vint childId : *to.children.Obj())
{
vint indexToInsert = 0;
vint indexOfChild = BinarySearchLambda(
&index[0],
index.Count(),
childId,
indexToInsert,
[](const DomIndexItem& item, vint id) { return item.id <=> id; }
);
CHECK_ERROR(indexOfChild != -1, ERROR_MESSAGE_PREFIX L"Unknown DOM id in diff.");
index[indexOfChild].parentId = from.id;
from.dom->children->Add(index[indexOfChild].dom);
}
}
}
}
}
}
}
// deleting
{
vint readingFrom = 0;
vint readingTo = 0;
List<vint> deleteIndices;
while (diffs.diffsInOrder && readingTo < diffs.diffsInOrder->Count())
{
if (readingFrom < index.Count())
{
auto&& from = index[readingFrom];
auto&& to = diffs.diffsInOrder->Get(readingTo);
if (from.id < to.id)
{
readingFrom++;
}
else if (from.id > to.id)
{
readingTo++;
}
else
{
if (to.diffType == RenderingDom_DiffType::Deleted)
{
deleteIndices.Add(readingFrom);
}
readingFrom++;
readingTo++;
}
}
else
{
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Nodes to be deleted must should appear in the index before modification");
}
}
vint reading = 0;
vint writing = 0;
vint testing = 0;
while (reading < index.Count())
{
if (testing < deleteIndices.Count() && deleteIndices[testing] == reading)
{
// A node to delete is found, mark and skip
testing++;
reading++;
}
else
{
if (reading != writing)
{
// Compact index by removing deleted entries
index[writing] = index[reading];
}
reading++;
writing++;
}
}
index.Resize(index.Count() - deleteIndices.Count());
}
#undef ERROR_MESSAGE_PREFIX
}
void DiffDom(Ptr<RenderingDom> domFrom, DomIndex& indexFrom, Ptr<RenderingDom> domTo, DomIndex& indexTo, RenderingDom_DiffsInOrder& diffs)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::DiffDom(Ptr<RenderingDom>, DomIndex&, Ptr<RenderingDom>, DomIndex&, RenderingDom_DiffsInOrder&)#"
CHECK_ERROR(domFrom && domTo && domFrom->id == domTo->id, ERROR_MESSAGE_PREFIX L"Roots of two DOMs tree must have the same ID.");
diffs.diffsInOrder = Ptr(new List<RenderingDom_Diff>);
vint readingFrom = 0;
vint readingTo = 0;
auto pushDeleted = [&]()
{
auto&& dom = indexFrom[readingFrom++].dom;
RenderingDom_Diff diff;
diff.id = dom->id;
diff.diffType = RenderingDom_DiffType::Deleted;
diffs.diffsInOrder->Add(diff);
};
auto pushCreated = [&]()
{
auto&& dom = indexTo[readingTo++].dom;
RenderingDom_Diff diff;
diff.id = dom->id;
diff.diffType = RenderingDom_DiffType::Created;
diff.content = dom->content;
if (dom->children && dom->children->Count() > 0)
{
diff.children = Ptr(new List<vint>);
CopyFrom(
*diff.children.Obj(),
From(*dom->children.Obj())
.Select([](Ptr<RenderingDom> child) { return child->id; })
);
}
diffs.diffsInOrder->Add(diff);
};
auto pushModified = [&]()
{
auto&& domFrom = indexFrom[readingFrom++].dom;
auto&& domTo = indexTo[readingTo++].dom;
RenderingDom_Diff diff;
diff.id = domFrom->id;
diff.diffType = RenderingDom_DiffType::Modified;
if (
domFrom->content.hitTestResult != domTo->content.hitTestResult ||
domFrom->content.cursor != domTo->content.cursor ||
domFrom->content.element != domTo->content.element ||
domFrom->content.bounds != domTo->content.bounds ||
domFrom->content.validArea != domTo->content.validArea
)
{
diff.content = domTo->content;
}
bool fromHasChild = domFrom->children && domFrom->children->Count() > 0;
bool toHasChild = domTo->children && domTo->children->Count() > 0;
bool childDifferent = false;
if (fromHasChild != toHasChild)
{
childDifferent = true;
}
else if (fromHasChild && toHasChild)
{
auto fromIds = From(*domFrom->children.Obj())
.Select([](Ptr<RenderingDom> child) { return child->id; });
auto toIds = From(*domTo->children.Obj())
.Select([](Ptr<RenderingDom> child) { return child->id; });
childDifferent = CompareEnumerable(fromIds, toIds) != 0;
}
if (childDifferent)
{
diff.children = Ptr(new List<vint>);
if (toHasChild)
{
CopyFrom(
*diff.children.Obj(),
From(*domTo->children.Obj())
.Select([](Ptr<RenderingDom> child) { return child->id; })
);
}
}
if (diff.content || diff.children)
{
diffs.diffsInOrder->Add(diff);
}
};
while (true)
{
if (readingFrom < indexFrom.Count() && readingTo < indexTo.Count())
{
if (indexFrom[readingFrom].id < indexTo[readingTo].id)
{
pushDeleted();
}
else if (indexFrom[readingFrom].id > indexTo[readingTo].id)
{
pushCreated();
}
else
{
pushModified();
}
}
else if (readingFrom < indexFrom.Count())
{
pushDeleted();
}
else if (readingTo < indexTo.Count())
{
pushCreated();
}
else
{
break;
}
}
#undef ERROR_MESSAGE_PREFIX
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTE\PROTOCOL\GENERATED\GUIREMOTEPROTOCOLSCHEMA.CPP
***********************************************************************/
/***********************************************************************
This file is generated by : Vczh GacUI Remote Protocol Generator
Licensed under https ://github.com/vczh-libraries/License
***********************************************************************/
namespace vl::presentation::remoteprotocol
{
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::INativeWindowListener::HitTestResult>(const ::vl::presentation::INativeWindowListener::HitTestResult & value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertCustomTypeToJson<::vl::presentation::INativeWindowListener::HitTestResult>(const ::vl::presentation::INativeWindowListener::HitTestResult&)#"
auto node = Ptr(new glr::json::JsonString);
switch (value)
{
case ::vl::presentation::INativeWindowListener::BorderNoSizing: node->content.value = WString::Unmanaged(L"BorderNoSizing"); break;
case ::vl::presentation::INativeWindowListener::BorderLeft: node->content.value = WString::Unmanaged(L"BorderLeft"); break;
case ::vl::presentation::INativeWindowListener::BorderRight: node->content.value = WString::Unmanaged(L"BorderRight"); break;
case ::vl::presentation::INativeWindowListener::BorderTop: node->content.value = WString::Unmanaged(L"BorderTop"); break;
case ::vl::presentation::INativeWindowListener::BorderBottom: node->content.value = WString::Unmanaged(L"BorderBottom"); break;
case ::vl::presentation::INativeWindowListener::BorderLeftTop: node->content.value = WString::Unmanaged(L"BorderLeftTop"); break;
case ::vl::presentation::INativeWindowListener::BorderRightTop: node->content.value = WString::Unmanaged(L"BorderRightTop"); break;
case ::vl::presentation::INativeWindowListener::BorderLeftBottom: node->content.value = WString::Unmanaged(L"BorderLeftBottom"); break;
case ::vl::presentation::INativeWindowListener::BorderRightBottom: node->content.value = WString::Unmanaged(L"BorderRightBottom"); break;
case ::vl::presentation::INativeWindowListener::Title: node->content.value = WString::Unmanaged(L"Title"); break;
case ::vl::presentation::INativeWindowListener::ButtonMinimum: node->content.value = WString::Unmanaged(L"ButtonMinimum"); break;
case ::vl::presentation::INativeWindowListener::ButtonMaximum: node->content.value = WString::Unmanaged(L"ButtonMaximum"); break;
case ::vl::presentation::INativeWindowListener::ButtonClose: node->content.value = WString::Unmanaged(L"ButtonClose"); break;
case ::vl::presentation::INativeWindowListener::Client: node->content.value = WString::Unmanaged(L"Client"); break;
case ::vl::presentation::INativeWindowListener::Icon: node->content.value = WString::Unmanaged(L"Icon"); break;
case ::vl::presentation::INativeWindowListener::NoDecision: node->content.value = WString::Unmanaged(L"NoDecision"); break;
default: CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
}
return node;
#undef ERROR_MESSAGE_PREFIX
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::INativeCursor::SystemCursorType>(const ::vl::presentation::INativeCursor::SystemCursorType & value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertCustomTypeToJson<::vl::presentation::INativeCursor::SystemCursorType>(const ::vl::presentation::INativeCursor::SystemCursorType&)#"
auto node = Ptr(new glr::json::JsonString);
switch (value)
{
case ::vl::presentation::INativeCursor::SmallWaiting: node->content.value = WString::Unmanaged(L"SmallWaiting"); break;
case ::vl::presentation::INativeCursor::LargeWaiting: node->content.value = WString::Unmanaged(L"LargeWaiting"); break;
case ::vl::presentation::INativeCursor::Arrow: node->content.value = WString::Unmanaged(L"Arrow"); break;
case ::vl::presentation::INativeCursor::Cross: node->content.value = WString::Unmanaged(L"Cross"); break;
case ::vl::presentation::INativeCursor::Hand: node->content.value = WString::Unmanaged(L"Hand"); break;
case ::vl::presentation::INativeCursor::Help: node->content.value = WString::Unmanaged(L"Help"); break;
case ::vl::presentation::INativeCursor::IBeam: node->content.value = WString::Unmanaged(L"IBeam"); break;
case ::vl::presentation::INativeCursor::SizeAll: node->content.value = WString::Unmanaged(L"SizeAll"); break;
case ::vl::presentation::INativeCursor::SizeNESW: node->content.value = WString::Unmanaged(L"SizeNESW"); break;
case ::vl::presentation::INativeCursor::SizeNS: node->content.value = WString::Unmanaged(L"SizeNS"); break;
case ::vl::presentation::INativeCursor::SizeNWSE: node->content.value = WString::Unmanaged(L"SizeNWSE"); break;
case ::vl::presentation::INativeCursor::SizeWE: node->content.value = WString::Unmanaged(L"SizeWE"); break;
default: CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
}
return node;
#undef ERROR_MESSAGE_PREFIX
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::INativeWindow::WindowSizeState>(const ::vl::presentation::INativeWindow::WindowSizeState & value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertCustomTypeToJson<::vl::presentation::INativeWindow::WindowSizeState>(const ::vl::presentation::INativeWindow::WindowSizeState&)#"
auto node = Ptr(new glr::json::JsonString);
switch (value)
{
case ::vl::presentation::INativeWindow::WindowSizeState::Minimized: node->content.value = WString::Unmanaged(L"Minimized"); break;
case ::vl::presentation::INativeWindow::WindowSizeState::Restored: node->content.value = WString::Unmanaged(L"Restored"); break;
case ::vl::presentation::INativeWindow::WindowSizeState::Maximized: node->content.value = WString::Unmanaged(L"Maximized"); break;
default: CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
}
return node;
#undef ERROR_MESSAGE_PREFIX
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::IOMouseButton>(const ::vl::presentation::remoteprotocol::IOMouseButton & value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::IOMouseButton>(const ::vl::presentation::remoteprotocol::IOMouseButton&)#"
auto node = Ptr(new glr::json::JsonString);
switch (value)
{
case ::vl::presentation::remoteprotocol::IOMouseButton::Left: node->content.value = WString::Unmanaged(L"Left"); break;
case ::vl::presentation::remoteprotocol::IOMouseButton::Middle: node->content.value = WString::Unmanaged(L"Middle"); break;
case ::vl::presentation::remoteprotocol::IOMouseButton::Right: node->content.value = WString::Unmanaged(L"Right"); break;
default: CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
}
return node;
#undef ERROR_MESSAGE_PREFIX
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::elements::ElementShapeType>(const ::vl::presentation::elements::ElementShapeType & value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertCustomTypeToJson<::vl::presentation::elements::ElementShapeType>(const ::vl::presentation::elements::ElementShapeType&)#"
auto node = Ptr(new glr::json::JsonString);
switch (value)
{
case ::vl::presentation::elements::ElementShapeType::Rectangle: node->content.value = WString::Unmanaged(L"Rectangle"); break;
case ::vl::presentation::elements::ElementShapeType::Ellipse: node->content.value = WString::Unmanaged(L"Ellipse"); break;
case ::vl::presentation::elements::ElementShapeType::RoundRect: node->content.value = WString::Unmanaged(L"RoundRect"); break;
default: CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
}
return node;
#undef ERROR_MESSAGE_PREFIX
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::elements::GuiGradientBackgroundElement::Direction>(const ::vl::presentation::elements::GuiGradientBackgroundElement::Direction & value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertCustomTypeToJson<::vl::presentation::elements::GuiGradientBackgroundElement::Direction>(const ::vl::presentation::elements::GuiGradientBackgroundElement::Direction&)#"
auto node = Ptr(new glr::json::JsonString);
switch (value)
{
case ::vl::presentation::elements::GuiGradientBackgroundElement::Horizontal: node->content.value = WString::Unmanaged(L"Horizontal"); break;
case ::vl::presentation::elements::GuiGradientBackgroundElement::Vertical: node->content.value = WString::Unmanaged(L"Vertical"); break;
case ::vl::presentation::elements::GuiGradientBackgroundElement::Slash: node->content.value = WString::Unmanaged(L"Slash"); break;
case ::vl::presentation::elements::GuiGradientBackgroundElement::Backslash: node->content.value = WString::Unmanaged(L"Backslash"); break;
default: CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
}
return node;
#undef ERROR_MESSAGE_PREFIX
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::elements::Gui3DSplitterElement::Direction>(const ::vl::presentation::elements::Gui3DSplitterElement::Direction & value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertCustomTypeToJson<::vl::presentation::elements::Gui3DSplitterElement::Direction>(const ::vl::presentation::elements::Gui3DSplitterElement::Direction&)#"
auto node = Ptr(new glr::json::JsonString);
switch (value)
{
case ::vl::presentation::elements::Gui3DSplitterElement::Horizontal: node->content.value = WString::Unmanaged(L"Horizontal"); break;
case ::vl::presentation::elements::Gui3DSplitterElement::Vertical: node->content.value = WString::Unmanaged(L"Vertical"); break;
default: CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
}
return node;
#undef ERROR_MESSAGE_PREFIX
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementHorizontalAlignment>(const ::vl::presentation::remoteprotocol::ElementHorizontalAlignment & value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementHorizontalAlignment>(const ::vl::presentation::remoteprotocol::ElementHorizontalAlignment&)#"
auto node = Ptr(new glr::json::JsonString);
switch (value)
{
case ::vl::presentation::remoteprotocol::ElementHorizontalAlignment::Left: node->content.value = WString::Unmanaged(L"Left"); break;
case ::vl::presentation::remoteprotocol::ElementHorizontalAlignment::Right: node->content.value = WString::Unmanaged(L"Right"); break;
case ::vl::presentation::remoteprotocol::ElementHorizontalAlignment::Center: node->content.value = WString::Unmanaged(L"Center"); break;
default: CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
}
return node;
#undef ERROR_MESSAGE_PREFIX
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementVerticalAlignment>(const ::vl::presentation::remoteprotocol::ElementVerticalAlignment & value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementVerticalAlignment>(const ::vl::presentation::remoteprotocol::ElementVerticalAlignment&)#"
auto node = Ptr(new glr::json::JsonString);
switch (value)
{
case ::vl::presentation::remoteprotocol::ElementVerticalAlignment::Top: node->content.value = WString::Unmanaged(L"Top"); break;
case ::vl::presentation::remoteprotocol::ElementVerticalAlignment::Bottom: node->content.value = WString::Unmanaged(L"Bottom"); break;
case ::vl::presentation::remoteprotocol::ElementVerticalAlignment::Center: node->content.value = WString::Unmanaged(L"Center"); break;
default: CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
}
return node;
#undef ERROR_MESSAGE_PREFIX
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementSolidLabelMeasuringRequest>(const ::vl::presentation::remoteprotocol::ElementSolidLabelMeasuringRequest & value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementSolidLabelMeasuringRequest>(const ::vl::presentation::remoteprotocol::ElementSolidLabelMeasuringRequest&)#"
auto node = Ptr(new glr::json::JsonString);
switch (value)
{
case ::vl::presentation::remoteprotocol::ElementSolidLabelMeasuringRequest::FontHeight: node->content.value = WString::Unmanaged(L"FontHeight"); break;
case ::vl::presentation::remoteprotocol::ElementSolidLabelMeasuringRequest::TotalSize: node->content.value = WString::Unmanaged(L"TotalSize"); break;
default: CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
}
return node;
#undef ERROR_MESSAGE_PREFIX
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::INativeImage::FormatType>(const ::vl::presentation::INativeImage::FormatType & value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertCustomTypeToJson<::vl::presentation::INativeImage::FormatType>(const ::vl::presentation::INativeImage::FormatType&)#"
auto node = Ptr(new glr::json::JsonString);
switch (value)
{
case ::vl::presentation::INativeImage::Bmp: node->content.value = WString::Unmanaged(L"Bmp"); break;
case ::vl::presentation::INativeImage::Gif: node->content.value = WString::Unmanaged(L"Gif"); break;
case ::vl::presentation::INativeImage::Icon: node->content.value = WString::Unmanaged(L"Icon"); break;
case ::vl::presentation::INativeImage::Jpeg: node->content.value = WString::Unmanaged(L"Jpeg"); break;
case ::vl::presentation::INativeImage::Png: node->content.value = WString::Unmanaged(L"Png"); break;
case ::vl::presentation::INativeImage::Tiff: node->content.value = WString::Unmanaged(L"Tiff"); break;
case ::vl::presentation::INativeImage::Wmp: node->content.value = WString::Unmanaged(L"Wmp"); break;
case ::vl::presentation::INativeImage::Unknown: node->content.value = WString::Unmanaged(L"Unknown"); break;
default: CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
}
return node;
#undef ERROR_MESSAGE_PREFIX
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::RendererType>(const ::vl::presentation::remoteprotocol::RendererType & value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::RendererType>(const ::vl::presentation::remoteprotocol::RendererType&)#"
auto node = Ptr(new glr::json::JsonString);
switch (value)
{
case ::vl::presentation::remoteprotocol::RendererType::FocusRectangle: node->content.value = WString::Unmanaged(L"FocusRectangle"); break;
case ::vl::presentation::remoteprotocol::RendererType::SolidBorder: node->content.value = WString::Unmanaged(L"SolidBorder"); break;
case ::vl::presentation::remoteprotocol::RendererType::SinkBorder: node->content.value = WString::Unmanaged(L"SinkBorder"); break;
case ::vl::presentation::remoteprotocol::RendererType::SinkSplitter: node->content.value = WString::Unmanaged(L"SinkSplitter"); break;
case ::vl::presentation::remoteprotocol::RendererType::SolidBackground: node->content.value = WString::Unmanaged(L"SolidBackground"); break;
case ::vl::presentation::remoteprotocol::RendererType::GradientBackground: node->content.value = WString::Unmanaged(L"GradientBackground"); break;
case ::vl::presentation::remoteprotocol::RendererType::InnerShadow: node->content.value = WString::Unmanaged(L"InnerShadow"); break;
case ::vl::presentation::remoteprotocol::RendererType::SolidLabel: node->content.value = WString::Unmanaged(L"SolidLabel"); break;
case ::vl::presentation::remoteprotocol::RendererType::Polygon: node->content.value = WString::Unmanaged(L"Polygon"); break;
case ::vl::presentation::remoteprotocol::RendererType::ImageFrame: node->content.value = WString::Unmanaged(L"ImageFrame"); break;
case ::vl::presentation::remoteprotocol::RendererType::UnsupportedColorizedText: node->content.value = WString::Unmanaged(L"UnsupportedColorizedText"); break;
case ::vl::presentation::remoteprotocol::RendererType::UnsupportedDocument: node->content.value = WString::Unmanaged(L"UnsupportedDocument"); break;
default: CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
}
return node;
#undef ERROR_MESSAGE_PREFIX
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::RenderingDom_DiffType>(const ::vl::presentation::remoteprotocol::RenderingDom_DiffType & value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::RenderingDom_DiffType>(const ::vl::presentation::remoteprotocol::RenderingDom_DiffType&)#"
auto node = Ptr(new glr::json::JsonString);
switch (value)
{
case ::vl::presentation::remoteprotocol::RenderingDom_DiffType::Deleted: node->content.value = WString::Unmanaged(L"Deleted"); break;
case ::vl::presentation::remoteprotocol::RenderingDom_DiffType::Created: node->content.value = WString::Unmanaged(L"Created"); break;
case ::vl::presentation::remoteprotocol::RenderingDom_DiffType::Modified: node->content.value = WString::Unmanaged(L"Modified"); break;
default: CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
}
return node;
#undef ERROR_MESSAGE_PREFIX
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::NativeCoordinate>(const ::vl::presentation::NativeCoordinate & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"value", value.value);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::NativePoint>(const ::vl::presentation::NativePoint & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"x", value.x);
ConvertCustomTypeToJsonField(node, L"y", value.y);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::NativeSize>(const ::vl::presentation::NativeSize & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"x", value.x);
ConvertCustomTypeToJsonField(node, L"y", value.y);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::NativeRect>(const ::vl::presentation::NativeRect & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"x1", value.x1);
ConvertCustomTypeToJsonField(node, L"y1", value.y1);
ConvertCustomTypeToJsonField(node, L"x2", value.x2);
ConvertCustomTypeToJsonField(node, L"y2", value.y2);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::NativeMargin>(const ::vl::presentation::NativeMargin & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"left", value.left);
ConvertCustomTypeToJsonField(node, L"top", value.top);
ConvertCustomTypeToJsonField(node, L"right", value.right);
ConvertCustomTypeToJsonField(node, L"bottom", value.bottom);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::Point>(const ::vl::presentation::Point & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"x", value.x);
ConvertCustomTypeToJsonField(node, L"y", value.y);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::Size>(const ::vl::presentation::Size & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"x", value.x);
ConvertCustomTypeToJsonField(node, L"y", value.y);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::Rect>(const ::vl::presentation::Rect & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"x1", value.x1);
ConvertCustomTypeToJsonField(node, L"y1", value.y1);
ConvertCustomTypeToJsonField(node, L"x2", value.x2);
ConvertCustomTypeToJsonField(node, L"y2", value.y2);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::FontProperties>(const ::vl::presentation::FontProperties & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"fontFamily", value.fontFamily);
ConvertCustomTypeToJsonField(node, L"size", value.size);
ConvertCustomTypeToJsonField(node, L"bold", value.bold);
ConvertCustomTypeToJsonField(node, L"italic", value.italic);
ConvertCustomTypeToJsonField(node, L"underline", value.underline);
ConvertCustomTypeToJsonField(node, L"strikeline", value.strikeline);
ConvertCustomTypeToJsonField(node, L"antialias", value.antialias);
ConvertCustomTypeToJsonField(node, L"verticalAntialias", value.verticalAntialias);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::FontConfig>(const ::vl::presentation::remoteprotocol::FontConfig & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"defaultFont", value.defaultFont);
ConvertCustomTypeToJsonField(node, L"supportedFonts", value.supportedFonts);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ScreenConfig>(const ::vl::presentation::remoteprotocol::ScreenConfig & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"bounds", value.bounds);
ConvertCustomTypeToJsonField(node, L"clientBounds", value.clientBounds);
ConvertCustomTypeToJsonField(node, L"scalingX", value.scalingX);
ConvertCustomTypeToJsonField(node, L"scalingY", value.scalingY);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::WindowSizingConfig>(const ::vl::presentation::remoteprotocol::WindowSizingConfig & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"bounds", value.bounds);
ConvertCustomTypeToJsonField(node, L"clientBounds", value.clientBounds);
ConvertCustomTypeToJsonField(node, L"sizeState", value.sizeState);
ConvertCustomTypeToJsonField(node, L"customFramePadding", value.customFramePadding);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::WindowShowing>(const ::vl::presentation::remoteprotocol::WindowShowing & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"activate", value.activate);
ConvertCustomTypeToJsonField(node, L"sizeState", value.sizeState);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::NativeWindowMouseInfo>(const ::vl::presentation::NativeWindowMouseInfo & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"ctrl", value.ctrl);
ConvertCustomTypeToJsonField(node, L"shift", value.shift);
ConvertCustomTypeToJsonField(node, L"left", value.left);
ConvertCustomTypeToJsonField(node, L"middle", value.middle);
ConvertCustomTypeToJsonField(node, L"right", value.right);
ConvertCustomTypeToJsonField(node, L"x", value.x);
ConvertCustomTypeToJsonField(node, L"y", value.y);
ConvertCustomTypeToJsonField(node, L"wheel", value.wheel);
ConvertCustomTypeToJsonField(node, L"nonClient", value.nonClient);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::IOMouseInfoWithButton>(const ::vl::presentation::remoteprotocol::IOMouseInfoWithButton & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"button", value.button);
ConvertCustomTypeToJsonField(node, L"info", value.info);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::NativeWindowKeyInfo>(const ::vl::presentation::NativeWindowKeyInfo & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"code", value.code);
ConvertCustomTypeToJsonField(node, L"ctrl", value.ctrl);
ConvertCustomTypeToJsonField(node, L"shift", value.shift);
ConvertCustomTypeToJsonField(node, L"alt", value.alt);
ConvertCustomTypeToJsonField(node, L"capslock", value.capslock);
ConvertCustomTypeToJsonField(node, L"autoRepeatKeyDown", value.autoRepeatKeyDown);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::NativeWindowCharInfo>(const ::vl::presentation::NativeWindowCharInfo & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"code", value.code);
ConvertCustomTypeToJsonField(node, L"ctrl", value.ctrl);
ConvertCustomTypeToJsonField(node, L"shift", value.shift);
ConvertCustomTypeToJsonField(node, L"alt", value.alt);
ConvertCustomTypeToJsonField(node, L"capslock", value.capslock);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::GlobalShortcutKey>(const ::vl::presentation::remoteprotocol::GlobalShortcutKey & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"ctrl", value.ctrl);
ConvertCustomTypeToJsonField(node, L"shift", value.shift);
ConvertCustomTypeToJsonField(node, L"alt", value.alt);
ConvertCustomTypeToJsonField(node, L"code", value.code);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::elements::ElementShape>(const ::vl::presentation::elements::ElementShape & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"shapeType", value.shapeType);
ConvertCustomTypeToJsonField(node, L"radiusX", value.radiusX);
ConvertCustomTypeToJsonField(node, L"radiusY", value.radiusY);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementDesc_SolidBorder>(const ::vl::presentation::remoteprotocol::ElementDesc_SolidBorder & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"borderColor", value.borderColor);
ConvertCustomTypeToJsonField(node, L"shape", value.shape);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementDesc_SinkBorder>(const ::vl::presentation::remoteprotocol::ElementDesc_SinkBorder & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"leftTopColor", value.leftTopColor);
ConvertCustomTypeToJsonField(node, L"rightBottomColor", value.rightBottomColor);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementDesc_SinkSplitter>(const ::vl::presentation::remoteprotocol::ElementDesc_SinkSplitter & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"leftTopColor", value.leftTopColor);
ConvertCustomTypeToJsonField(node, L"rightBottomColor", value.rightBottomColor);
ConvertCustomTypeToJsonField(node, L"direction", value.direction);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementDesc_SolidBackground>(const ::vl::presentation::remoteprotocol::ElementDesc_SolidBackground & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"backgroundColor", value.backgroundColor);
ConvertCustomTypeToJsonField(node, L"shape", value.shape);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementDesc_GradientBackground>(const ::vl::presentation::remoteprotocol::ElementDesc_GradientBackground & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"leftTopColor", value.leftTopColor);
ConvertCustomTypeToJsonField(node, L"rightBottomColor", value.rightBottomColor);
ConvertCustomTypeToJsonField(node, L"direction", value.direction);
ConvertCustomTypeToJsonField(node, L"shape", value.shape);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementDesc_InnerShadow>(const ::vl::presentation::remoteprotocol::ElementDesc_InnerShadow & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"shadowColor", value.shadowColor);
ConvertCustomTypeToJsonField(node, L"thickness", value.thickness);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementDesc_Polygon>(const ::vl::presentation::remoteprotocol::ElementDesc_Polygon & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"size", value.size);
ConvertCustomTypeToJsonField(node, L"borderColor", value.borderColor);
ConvertCustomTypeToJsonField(node, L"backgroundColor", value.backgroundColor);
ConvertCustomTypeToJsonField(node, L"points", value.points);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementDesc_SolidLabel>(const ::vl::presentation::remoteprotocol::ElementDesc_SolidLabel & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"textColor", value.textColor);
ConvertCustomTypeToJsonField(node, L"horizontalAlignment", value.horizontalAlignment);
ConvertCustomTypeToJsonField(node, L"verticalAlignment", value.verticalAlignment);
ConvertCustomTypeToJsonField(node, L"wrapLine", value.wrapLine);
ConvertCustomTypeToJsonField(node, L"wrapLineHeightCalculation", value.wrapLineHeightCalculation);
ConvertCustomTypeToJsonField(node, L"ellipse", value.ellipse);
ConvertCustomTypeToJsonField(node, L"multiline", value.multiline);
ConvertCustomTypeToJsonField(node, L"font", value.font);
ConvertCustomTypeToJsonField(node, L"text", value.text);
ConvertCustomTypeToJsonField(node, L"measuringRequest", value.measuringRequest);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ImageCreation>(const ::vl::presentation::remoteprotocol::ImageCreation & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"imageData", value.imageData);
ConvertCustomTypeToJsonField(node, L"imageDataOmitted", value.imageDataOmitted);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ImageFrameMetadata>(const ::vl::presentation::remoteprotocol::ImageFrameMetadata & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"size", value.size);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ImageMetadata>(const ::vl::presentation::remoteprotocol::ImageMetadata & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"format", value.format);
ConvertCustomTypeToJsonField(node, L"frames", value.frames);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementDesc_ImageFrame>(const ::vl::presentation::remoteprotocol::ElementDesc_ImageFrame & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"imageId", value.imageId);
ConvertCustomTypeToJsonField(node, L"imageFrame", value.imageFrame);
ConvertCustomTypeToJsonField(node, L"horizontalAlignment", value.horizontalAlignment);
ConvertCustomTypeToJsonField(node, L"verticalAlignment", value.verticalAlignment);
ConvertCustomTypeToJsonField(node, L"stretch", value.stretch);
ConvertCustomTypeToJsonField(node, L"enabled", value.enabled);
ConvertCustomTypeToJsonField(node, L"imageCreation", value.imageCreation);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::RendererCreation>(const ::vl::presentation::remoteprotocol::RendererCreation & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"type", value.type);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementBeginRendering>(const ::vl::presentation::remoteprotocol::ElementBeginRendering & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"frameId", value.frameId);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementRendering>(const ::vl::presentation::remoteprotocol::ElementRendering & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"bounds", value.bounds);
ConvertCustomTypeToJsonField(node, L"areaClippedByParent", value.areaClippedByParent);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementBoundary>(const ::vl::presentation::remoteprotocol::ElementBoundary & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"hitTestResult", value.hitTestResult);
ConvertCustomTypeToJsonField(node, L"cursor", value.cursor);
ConvertCustomTypeToJsonField(node, L"bounds", value.bounds);
ConvertCustomTypeToJsonField(node, L"areaClippedBySelf", value.areaClippedBySelf);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementMeasuring_FontHeight>(const ::vl::presentation::remoteprotocol::ElementMeasuring_FontHeight & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"fontFamily", value.fontFamily);
ConvertCustomTypeToJsonField(node, L"fontSize", value.fontSize);
ConvertCustomTypeToJsonField(node, L"height", value.height);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementMeasuring_ElementMinSize>(const ::vl::presentation::remoteprotocol::ElementMeasuring_ElementMinSize & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"minSize", value.minSize);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::ElementMeasurings>(const ::vl::presentation::remoteprotocol::ElementMeasurings & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"fontHeights", value.fontHeights);
ConvertCustomTypeToJsonField(node, L"minSizes", value.minSizes);
ConvertCustomTypeToJsonField(node, L"createdImages", value.createdImages);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::RenderingDomContent>(const ::vl::presentation::remoteprotocol::RenderingDomContent & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"hitTestResult", value.hitTestResult);
ConvertCustomTypeToJsonField(node, L"cursor", value.cursor);
ConvertCustomTypeToJsonField(node, L"element", value.element);
ConvertCustomTypeToJsonField(node, L"bounds", value.bounds);
ConvertCustomTypeToJsonField(node, L"validArea", value.validArea);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::RenderingDom>(const ::vl::presentation::remoteprotocol::RenderingDom & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"content", value.content);
ConvertCustomTypeToJsonField(node, L"children", value.children);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::RenderingDom_Diff>(const ::vl::presentation::remoteprotocol::RenderingDom_Diff & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"id", value.id);
ConvertCustomTypeToJsonField(node, L"diffType", value.diffType);
ConvertCustomTypeToJsonField(node, L"content", value.content);
ConvertCustomTypeToJsonField(node, L"children", value.children);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::RenderingDom_DiffsInOrder>(const ::vl::presentation::remoteprotocol::RenderingDom_DiffsInOrder & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"diffsInOrder", value.diffsInOrder);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::UnitTest_RenderingFrame>(const ::vl::presentation::remoteprotocol::UnitTest_RenderingFrame & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"frameId", value.frameId);
ConvertCustomTypeToJsonField(node, L"frameName", value.frameName);
ConvertCustomTypeToJsonField(node, L"windowSize", value.windowSize);
ConvertCustomTypeToJsonField(node, L"elements", value.elements);
ConvertCustomTypeToJsonField(node, L"root", value.root);
return node;
}
template<> vl::Ptr<vl::glr::json::JsonNode> ConvertCustomTypeToJson<::vl::presentation::remoteprotocol::UnitTest_RenderingTrace>(const ::vl::presentation::remoteprotocol::UnitTest_RenderingTrace & value)
{
auto node = Ptr(new glr::json::JsonObject);
ConvertCustomTypeToJsonField(node, L"createdElements", value.createdElements);
ConvertCustomTypeToJsonField(node, L"imageCreations", value.imageCreations);
ConvertCustomTypeToJsonField(node, L"imageMetadatas", value.imageMetadatas);
ConvertCustomTypeToJsonField(node, L"frames", value.frames);
return node;
}
template<> void ConvertJsonToCustomType<::vl::presentation::INativeWindowListener::HitTestResult>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::INativeWindowListener::HitTestResult& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::INativeWindowListener::HitTestResult>(Ptr<JsonNode>, ::vl::presentation::INativeWindowListener::HitTestResult&)#"
auto jsonNode = node.Cast<glr::json::JsonString>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
if (jsonNode->content.value == L"BorderNoSizing") value = ::vl::presentation::INativeWindowListener::BorderNoSizing; else
if (jsonNode->content.value == L"BorderLeft") value = ::vl::presentation::INativeWindowListener::BorderLeft; else
if (jsonNode->content.value == L"BorderRight") value = ::vl::presentation::INativeWindowListener::BorderRight; else
if (jsonNode->content.value == L"BorderTop") value = ::vl::presentation::INativeWindowListener::BorderTop; else
if (jsonNode->content.value == L"BorderBottom") value = ::vl::presentation::INativeWindowListener::BorderBottom; else
if (jsonNode->content.value == L"BorderLeftTop") value = ::vl::presentation::INativeWindowListener::BorderLeftTop; else
if (jsonNode->content.value == L"BorderRightTop") value = ::vl::presentation::INativeWindowListener::BorderRightTop; else
if (jsonNode->content.value == L"BorderLeftBottom") value = ::vl::presentation::INativeWindowListener::BorderLeftBottom; else
if (jsonNode->content.value == L"BorderRightBottom") value = ::vl::presentation::INativeWindowListener::BorderRightBottom; else
if (jsonNode->content.value == L"Title") value = ::vl::presentation::INativeWindowListener::Title; else
if (jsonNode->content.value == L"ButtonMinimum") value = ::vl::presentation::INativeWindowListener::ButtonMinimum; else
if (jsonNode->content.value == L"ButtonMaximum") value = ::vl::presentation::INativeWindowListener::ButtonMaximum; else
if (jsonNode->content.value == L"ButtonClose") value = ::vl::presentation::INativeWindowListener::ButtonClose; else
if (jsonNode->content.value == L"Client") value = ::vl::presentation::INativeWindowListener::Client; else
if (jsonNode->content.value == L"Icon") value = ::vl::presentation::INativeWindowListener::Icon; else
if (jsonNode->content.value == L"NoDecision") value = ::vl::presentation::INativeWindowListener::NoDecision; else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::INativeCursor::SystemCursorType>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::INativeCursor::SystemCursorType& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::INativeCursor::SystemCursorType>(Ptr<JsonNode>, ::vl::presentation::INativeCursor::SystemCursorType&)#"
auto jsonNode = node.Cast<glr::json::JsonString>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
if (jsonNode->content.value == L"SmallWaiting") value = ::vl::presentation::INativeCursor::SmallWaiting; else
if (jsonNode->content.value == L"LargeWaiting") value = ::vl::presentation::INativeCursor::LargeWaiting; else
if (jsonNode->content.value == L"Arrow") value = ::vl::presentation::INativeCursor::Arrow; else
if (jsonNode->content.value == L"Cross") value = ::vl::presentation::INativeCursor::Cross; else
if (jsonNode->content.value == L"Hand") value = ::vl::presentation::INativeCursor::Hand; else
if (jsonNode->content.value == L"Help") value = ::vl::presentation::INativeCursor::Help; else
if (jsonNode->content.value == L"IBeam") value = ::vl::presentation::INativeCursor::IBeam; else
if (jsonNode->content.value == L"SizeAll") value = ::vl::presentation::INativeCursor::SizeAll; else
if (jsonNode->content.value == L"SizeNESW") value = ::vl::presentation::INativeCursor::SizeNESW; else
if (jsonNode->content.value == L"SizeNS") value = ::vl::presentation::INativeCursor::SizeNS; else
if (jsonNode->content.value == L"SizeNWSE") value = ::vl::presentation::INativeCursor::SizeNWSE; else
if (jsonNode->content.value == L"SizeWE") value = ::vl::presentation::INativeCursor::SizeWE; else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::INativeWindow::WindowSizeState>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::INativeWindow::WindowSizeState& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::INativeWindow::WindowSizeState>(Ptr<JsonNode>, ::vl::presentation::INativeWindow::WindowSizeState&)#"
auto jsonNode = node.Cast<glr::json::JsonString>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
if (jsonNode->content.value == L"Minimized") value = ::vl::presentation::INativeWindow::WindowSizeState::Minimized; else
if (jsonNode->content.value == L"Restored") value = ::vl::presentation::INativeWindow::WindowSizeState::Restored; else
if (jsonNode->content.value == L"Maximized") value = ::vl::presentation::INativeWindow::WindowSizeState::Maximized; else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::IOMouseButton>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::IOMouseButton& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::IOMouseButton>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::IOMouseButton&)#"
auto jsonNode = node.Cast<glr::json::JsonString>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
if (jsonNode->content.value == L"Left") value = ::vl::presentation::remoteprotocol::IOMouseButton::Left; else
if (jsonNode->content.value == L"Middle") value = ::vl::presentation::remoteprotocol::IOMouseButton::Middle; else
if (jsonNode->content.value == L"Right") value = ::vl::presentation::remoteprotocol::IOMouseButton::Right; else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::elements::ElementShapeType>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::elements::ElementShapeType& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::elements::ElementShapeType>(Ptr<JsonNode>, ::vl::presentation::elements::ElementShapeType&)#"
auto jsonNode = node.Cast<glr::json::JsonString>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
if (jsonNode->content.value == L"Rectangle") value = ::vl::presentation::elements::ElementShapeType::Rectangle; else
if (jsonNode->content.value == L"Ellipse") value = ::vl::presentation::elements::ElementShapeType::Ellipse; else
if (jsonNode->content.value == L"RoundRect") value = ::vl::presentation::elements::ElementShapeType::RoundRect; else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::elements::GuiGradientBackgroundElement::Direction>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::elements::GuiGradientBackgroundElement::Direction& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::elements::GuiGradientBackgroundElement::Direction>(Ptr<JsonNode>, ::vl::presentation::elements::GuiGradientBackgroundElement::Direction&)#"
auto jsonNode = node.Cast<glr::json::JsonString>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
if (jsonNode->content.value == L"Horizontal") value = ::vl::presentation::elements::GuiGradientBackgroundElement::Horizontal; else
if (jsonNode->content.value == L"Vertical") value = ::vl::presentation::elements::GuiGradientBackgroundElement::Vertical; else
if (jsonNode->content.value == L"Slash") value = ::vl::presentation::elements::GuiGradientBackgroundElement::Slash; else
if (jsonNode->content.value == L"Backslash") value = ::vl::presentation::elements::GuiGradientBackgroundElement::Backslash; else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::elements::Gui3DSplitterElement::Direction>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::elements::Gui3DSplitterElement::Direction& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::elements::Gui3DSplitterElement::Direction>(Ptr<JsonNode>, ::vl::presentation::elements::Gui3DSplitterElement::Direction&)#"
auto jsonNode = node.Cast<glr::json::JsonString>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
if (jsonNode->content.value == L"Horizontal") value = ::vl::presentation::elements::Gui3DSplitterElement::Horizontal; else
if (jsonNode->content.value == L"Vertical") value = ::vl::presentation::elements::Gui3DSplitterElement::Vertical; else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementHorizontalAlignment>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementHorizontalAlignment& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementHorizontalAlignment>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementHorizontalAlignment&)#"
auto jsonNode = node.Cast<glr::json::JsonString>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
if (jsonNode->content.value == L"Left") value = ::vl::presentation::remoteprotocol::ElementHorizontalAlignment::Left; else
if (jsonNode->content.value == L"Right") value = ::vl::presentation::remoteprotocol::ElementHorizontalAlignment::Right; else
if (jsonNode->content.value == L"Center") value = ::vl::presentation::remoteprotocol::ElementHorizontalAlignment::Center; else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementVerticalAlignment>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementVerticalAlignment& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementVerticalAlignment>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementVerticalAlignment&)#"
auto jsonNode = node.Cast<glr::json::JsonString>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
if (jsonNode->content.value == L"Top") value = ::vl::presentation::remoteprotocol::ElementVerticalAlignment::Top; else
if (jsonNode->content.value == L"Bottom") value = ::vl::presentation::remoteprotocol::ElementVerticalAlignment::Bottom; else
if (jsonNode->content.value == L"Center") value = ::vl::presentation::remoteprotocol::ElementVerticalAlignment::Center; else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementSolidLabelMeasuringRequest>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementSolidLabelMeasuringRequest& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementSolidLabelMeasuringRequest>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementSolidLabelMeasuringRequest&)#"
auto jsonNode = node.Cast<glr::json::JsonString>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
if (jsonNode->content.value == L"FontHeight") value = ::vl::presentation::remoteprotocol::ElementSolidLabelMeasuringRequest::FontHeight; else
if (jsonNode->content.value == L"TotalSize") value = ::vl::presentation::remoteprotocol::ElementSolidLabelMeasuringRequest::TotalSize; else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::INativeImage::FormatType>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::INativeImage::FormatType& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::INativeImage::FormatType>(Ptr<JsonNode>, ::vl::presentation::INativeImage::FormatType&)#"
auto jsonNode = node.Cast<glr::json::JsonString>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
if (jsonNode->content.value == L"Bmp") value = ::vl::presentation::INativeImage::Bmp; else
if (jsonNode->content.value == L"Gif") value = ::vl::presentation::INativeImage::Gif; else
if (jsonNode->content.value == L"Icon") value = ::vl::presentation::INativeImage::Icon; else
if (jsonNode->content.value == L"Jpeg") value = ::vl::presentation::INativeImage::Jpeg; else
if (jsonNode->content.value == L"Png") value = ::vl::presentation::INativeImage::Png; else
if (jsonNode->content.value == L"Tiff") value = ::vl::presentation::INativeImage::Tiff; else
if (jsonNode->content.value == L"Wmp") value = ::vl::presentation::INativeImage::Wmp; else
if (jsonNode->content.value == L"Unknown") value = ::vl::presentation::INativeImage::Unknown; else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::RendererType>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::RendererType& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::RendererType>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::RendererType&)#"
auto jsonNode = node.Cast<glr::json::JsonString>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
if (jsonNode->content.value == L"FocusRectangle") value = ::vl::presentation::remoteprotocol::RendererType::FocusRectangle; else
if (jsonNode->content.value == L"SolidBorder") value = ::vl::presentation::remoteprotocol::RendererType::SolidBorder; else
if (jsonNode->content.value == L"SinkBorder") value = ::vl::presentation::remoteprotocol::RendererType::SinkBorder; else
if (jsonNode->content.value == L"SinkSplitter") value = ::vl::presentation::remoteprotocol::RendererType::SinkSplitter; else
if (jsonNode->content.value == L"SolidBackground") value = ::vl::presentation::remoteprotocol::RendererType::SolidBackground; else
if (jsonNode->content.value == L"GradientBackground") value = ::vl::presentation::remoteprotocol::RendererType::GradientBackground; else
if (jsonNode->content.value == L"InnerShadow") value = ::vl::presentation::remoteprotocol::RendererType::InnerShadow; else
if (jsonNode->content.value == L"SolidLabel") value = ::vl::presentation::remoteprotocol::RendererType::SolidLabel; else
if (jsonNode->content.value == L"Polygon") value = ::vl::presentation::remoteprotocol::RendererType::Polygon; else
if (jsonNode->content.value == L"ImageFrame") value = ::vl::presentation::remoteprotocol::RendererType::ImageFrame; else
if (jsonNode->content.value == L"UnsupportedColorizedText") value = ::vl::presentation::remoteprotocol::RendererType::UnsupportedColorizedText; else
if (jsonNode->content.value == L"UnsupportedDocument") value = ::vl::presentation::remoteprotocol::RendererType::UnsupportedDocument; else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::RenderingDom_DiffType>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::RenderingDom_DiffType& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::RenderingDom_DiffType>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::RenderingDom_DiffType&)#"
auto jsonNode = node.Cast<glr::json::JsonString>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
if (jsonNode->content.value == L"Deleted") value = ::vl::presentation::remoteprotocol::RenderingDom_DiffType::Deleted; else
if (jsonNode->content.value == L"Created") value = ::vl::presentation::remoteprotocol::RenderingDom_DiffType::Created; else
if (jsonNode->content.value == L"Modified") value = ::vl::presentation::remoteprotocol::RenderingDom_DiffType::Modified; else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported enum value.");
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::NativeCoordinate>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::NativeCoordinate& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::NativeCoordinate>(Ptr<JsonNode>, ::vl::presentation::NativeCoordinate&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"value") ConvertJsonToCustomType(field->value, value.value); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::NativePoint>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::NativePoint& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::NativePoint>(Ptr<JsonNode>, ::vl::presentation::NativePoint&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"x") ConvertJsonToCustomType(field->value, value.x); else
if (field->name.value == L"y") ConvertJsonToCustomType(field->value, value.y); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::NativeSize>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::NativeSize& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::NativeSize>(Ptr<JsonNode>, ::vl::presentation::NativeSize&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"x") ConvertJsonToCustomType(field->value, value.x); else
if (field->name.value == L"y") ConvertJsonToCustomType(field->value, value.y); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::NativeRect>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::NativeRect& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::NativeRect>(Ptr<JsonNode>, ::vl::presentation::NativeRect&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"x1") ConvertJsonToCustomType(field->value, value.x1); else
if (field->name.value == L"y1") ConvertJsonToCustomType(field->value, value.y1); else
if (field->name.value == L"x2") ConvertJsonToCustomType(field->value, value.x2); else
if (field->name.value == L"y2") ConvertJsonToCustomType(field->value, value.y2); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::NativeMargin>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::NativeMargin& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::NativeMargin>(Ptr<JsonNode>, ::vl::presentation::NativeMargin&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"left") ConvertJsonToCustomType(field->value, value.left); else
if (field->name.value == L"top") ConvertJsonToCustomType(field->value, value.top); else
if (field->name.value == L"right") ConvertJsonToCustomType(field->value, value.right); else
if (field->name.value == L"bottom") ConvertJsonToCustomType(field->value, value.bottom); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::Point>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::Point& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::Point>(Ptr<JsonNode>, ::vl::presentation::Point&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"x") ConvertJsonToCustomType(field->value, value.x); else
if (field->name.value == L"y") ConvertJsonToCustomType(field->value, value.y); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::Size>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::Size& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::Size>(Ptr<JsonNode>, ::vl::presentation::Size&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"x") ConvertJsonToCustomType(field->value, value.x); else
if (field->name.value == L"y") ConvertJsonToCustomType(field->value, value.y); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::Rect>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::Rect& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::Rect>(Ptr<JsonNode>, ::vl::presentation::Rect&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"x1") ConvertJsonToCustomType(field->value, value.x1); else
if (field->name.value == L"y1") ConvertJsonToCustomType(field->value, value.y1); else
if (field->name.value == L"x2") ConvertJsonToCustomType(field->value, value.x2); else
if (field->name.value == L"y2") ConvertJsonToCustomType(field->value, value.y2); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::FontProperties>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::FontProperties& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::FontProperties>(Ptr<JsonNode>, ::vl::presentation::FontProperties&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"fontFamily") ConvertJsonToCustomType(field->value, value.fontFamily); else
if (field->name.value == L"size") ConvertJsonToCustomType(field->value, value.size); else
if (field->name.value == L"bold") ConvertJsonToCustomType(field->value, value.bold); else
if (field->name.value == L"italic") ConvertJsonToCustomType(field->value, value.italic); else
if (field->name.value == L"underline") ConvertJsonToCustomType(field->value, value.underline); else
if (field->name.value == L"strikeline") ConvertJsonToCustomType(field->value, value.strikeline); else
if (field->name.value == L"antialias") ConvertJsonToCustomType(field->value, value.antialias); else
if (field->name.value == L"verticalAntialias") ConvertJsonToCustomType(field->value, value.verticalAntialias); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::FontConfig>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::FontConfig& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::FontConfig>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::FontConfig&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"defaultFont") ConvertJsonToCustomType(field->value, value.defaultFont); else
if (field->name.value == L"supportedFonts") ConvertJsonToCustomType(field->value, value.supportedFonts); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ScreenConfig>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ScreenConfig& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ScreenConfig>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ScreenConfig&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"bounds") ConvertJsonToCustomType(field->value, value.bounds); else
if (field->name.value == L"clientBounds") ConvertJsonToCustomType(field->value, value.clientBounds); else
if (field->name.value == L"scalingX") ConvertJsonToCustomType(field->value, value.scalingX); else
if (field->name.value == L"scalingY") ConvertJsonToCustomType(field->value, value.scalingY); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::WindowSizingConfig>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::WindowSizingConfig& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::WindowSizingConfig>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::WindowSizingConfig&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"bounds") ConvertJsonToCustomType(field->value, value.bounds); else
if (field->name.value == L"clientBounds") ConvertJsonToCustomType(field->value, value.clientBounds); else
if (field->name.value == L"sizeState") ConvertJsonToCustomType(field->value, value.sizeState); else
if (field->name.value == L"customFramePadding") ConvertJsonToCustomType(field->value, value.customFramePadding); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::WindowShowing>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::WindowShowing& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::WindowShowing>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::WindowShowing&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"activate") ConvertJsonToCustomType(field->value, value.activate); else
if (field->name.value == L"sizeState") ConvertJsonToCustomType(field->value, value.sizeState); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::NativeWindowMouseInfo>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::NativeWindowMouseInfo& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::NativeWindowMouseInfo>(Ptr<JsonNode>, ::vl::presentation::NativeWindowMouseInfo&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"ctrl") ConvertJsonToCustomType(field->value, value.ctrl); else
if (field->name.value == L"shift") ConvertJsonToCustomType(field->value, value.shift); else
if (field->name.value == L"left") ConvertJsonToCustomType(field->value, value.left); else
if (field->name.value == L"middle") ConvertJsonToCustomType(field->value, value.middle); else
if (field->name.value == L"right") ConvertJsonToCustomType(field->value, value.right); else
if (field->name.value == L"x") ConvertJsonToCustomType(field->value, value.x); else
if (field->name.value == L"y") ConvertJsonToCustomType(field->value, value.y); else
if (field->name.value == L"wheel") ConvertJsonToCustomType(field->value, value.wheel); else
if (field->name.value == L"nonClient") ConvertJsonToCustomType(field->value, value.nonClient); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::IOMouseInfoWithButton>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::IOMouseInfoWithButton& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::IOMouseInfoWithButton>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::IOMouseInfoWithButton&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"button") ConvertJsonToCustomType(field->value, value.button); else
if (field->name.value == L"info") ConvertJsonToCustomType(field->value, value.info); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::NativeWindowKeyInfo>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::NativeWindowKeyInfo& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::NativeWindowKeyInfo>(Ptr<JsonNode>, ::vl::presentation::NativeWindowKeyInfo&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"code") ConvertJsonToCustomType(field->value, value.code); else
if (field->name.value == L"ctrl") ConvertJsonToCustomType(field->value, value.ctrl); else
if (field->name.value == L"shift") ConvertJsonToCustomType(field->value, value.shift); else
if (field->name.value == L"alt") ConvertJsonToCustomType(field->value, value.alt); else
if (field->name.value == L"capslock") ConvertJsonToCustomType(field->value, value.capslock); else
if (field->name.value == L"autoRepeatKeyDown") ConvertJsonToCustomType(field->value, value.autoRepeatKeyDown); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::NativeWindowCharInfo>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::NativeWindowCharInfo& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::NativeWindowCharInfo>(Ptr<JsonNode>, ::vl::presentation::NativeWindowCharInfo&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"code") ConvertJsonToCustomType(field->value, value.code); else
if (field->name.value == L"ctrl") ConvertJsonToCustomType(field->value, value.ctrl); else
if (field->name.value == L"shift") ConvertJsonToCustomType(field->value, value.shift); else
if (field->name.value == L"alt") ConvertJsonToCustomType(field->value, value.alt); else
if (field->name.value == L"capslock") ConvertJsonToCustomType(field->value, value.capslock); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::GlobalShortcutKey>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::GlobalShortcutKey& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::GlobalShortcutKey>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::GlobalShortcutKey&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"ctrl") ConvertJsonToCustomType(field->value, value.ctrl); else
if (field->name.value == L"shift") ConvertJsonToCustomType(field->value, value.shift); else
if (field->name.value == L"alt") ConvertJsonToCustomType(field->value, value.alt); else
if (field->name.value == L"code") ConvertJsonToCustomType(field->value, value.code); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::elements::ElementShape>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::elements::ElementShape& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::elements::ElementShape>(Ptr<JsonNode>, ::vl::presentation::elements::ElementShape&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"shapeType") ConvertJsonToCustomType(field->value, value.shapeType); else
if (field->name.value == L"radiusX") ConvertJsonToCustomType(field->value, value.radiusX); else
if (field->name.value == L"radiusY") ConvertJsonToCustomType(field->value, value.radiusY); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_SolidBorder>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementDesc_SolidBorder& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_SolidBorder>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementDesc_SolidBorder&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"borderColor") ConvertJsonToCustomType(field->value, value.borderColor); else
if (field->name.value == L"shape") ConvertJsonToCustomType(field->value, value.shape); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_SinkBorder>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementDesc_SinkBorder& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_SinkBorder>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementDesc_SinkBorder&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"leftTopColor") ConvertJsonToCustomType(field->value, value.leftTopColor); else
if (field->name.value == L"rightBottomColor") ConvertJsonToCustomType(field->value, value.rightBottomColor); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_SinkSplitter>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementDesc_SinkSplitter& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_SinkSplitter>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementDesc_SinkSplitter&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"leftTopColor") ConvertJsonToCustomType(field->value, value.leftTopColor); else
if (field->name.value == L"rightBottomColor") ConvertJsonToCustomType(field->value, value.rightBottomColor); else
if (field->name.value == L"direction") ConvertJsonToCustomType(field->value, value.direction); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_SolidBackground>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementDesc_SolidBackground& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_SolidBackground>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementDesc_SolidBackground&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"backgroundColor") ConvertJsonToCustomType(field->value, value.backgroundColor); else
if (field->name.value == L"shape") ConvertJsonToCustomType(field->value, value.shape); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_GradientBackground>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementDesc_GradientBackground& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_GradientBackground>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementDesc_GradientBackground&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"leftTopColor") ConvertJsonToCustomType(field->value, value.leftTopColor); else
if (field->name.value == L"rightBottomColor") ConvertJsonToCustomType(field->value, value.rightBottomColor); else
if (field->name.value == L"direction") ConvertJsonToCustomType(field->value, value.direction); else
if (field->name.value == L"shape") ConvertJsonToCustomType(field->value, value.shape); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_InnerShadow>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementDesc_InnerShadow& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_InnerShadow>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementDesc_InnerShadow&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"shadowColor") ConvertJsonToCustomType(field->value, value.shadowColor); else
if (field->name.value == L"thickness") ConvertJsonToCustomType(field->value, value.thickness); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_Polygon>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementDesc_Polygon& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_Polygon>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementDesc_Polygon&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"size") ConvertJsonToCustomType(field->value, value.size); else
if (field->name.value == L"borderColor") ConvertJsonToCustomType(field->value, value.borderColor); else
if (field->name.value == L"backgroundColor") ConvertJsonToCustomType(field->value, value.backgroundColor); else
if (field->name.value == L"points") ConvertJsonToCustomType(field->value, value.points); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_SolidLabel>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementDesc_SolidLabel& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_SolidLabel>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementDesc_SolidLabel&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"textColor") ConvertJsonToCustomType(field->value, value.textColor); else
if (field->name.value == L"horizontalAlignment") ConvertJsonToCustomType(field->value, value.horizontalAlignment); else
if (field->name.value == L"verticalAlignment") ConvertJsonToCustomType(field->value, value.verticalAlignment); else
if (field->name.value == L"wrapLine") ConvertJsonToCustomType(field->value, value.wrapLine); else
if (field->name.value == L"wrapLineHeightCalculation") ConvertJsonToCustomType(field->value, value.wrapLineHeightCalculation); else
if (field->name.value == L"ellipse") ConvertJsonToCustomType(field->value, value.ellipse); else
if (field->name.value == L"multiline") ConvertJsonToCustomType(field->value, value.multiline); else
if (field->name.value == L"font") ConvertJsonToCustomType(field->value, value.font); else
if (field->name.value == L"text") ConvertJsonToCustomType(field->value, value.text); else
if (field->name.value == L"measuringRequest") ConvertJsonToCustomType(field->value, value.measuringRequest); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ImageCreation>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ImageCreation& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ImageCreation>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ImageCreation&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"imageData") ConvertJsonToCustomType(field->value, value.imageData); else
if (field->name.value == L"imageDataOmitted") ConvertJsonToCustomType(field->value, value.imageDataOmitted); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ImageFrameMetadata>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ImageFrameMetadata& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ImageFrameMetadata>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ImageFrameMetadata&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"size") ConvertJsonToCustomType(field->value, value.size); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ImageMetadata>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ImageMetadata& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ImageMetadata>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ImageMetadata&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"format") ConvertJsonToCustomType(field->value, value.format); else
if (field->name.value == L"frames") ConvertJsonToCustomType(field->value, value.frames); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_ImageFrame>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementDesc_ImageFrame& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementDesc_ImageFrame>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementDesc_ImageFrame&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"imageId") ConvertJsonToCustomType(field->value, value.imageId); else
if (field->name.value == L"imageFrame") ConvertJsonToCustomType(field->value, value.imageFrame); else
if (field->name.value == L"horizontalAlignment") ConvertJsonToCustomType(field->value, value.horizontalAlignment); else
if (field->name.value == L"verticalAlignment") ConvertJsonToCustomType(field->value, value.verticalAlignment); else
if (field->name.value == L"stretch") ConvertJsonToCustomType(field->value, value.stretch); else
if (field->name.value == L"enabled") ConvertJsonToCustomType(field->value, value.enabled); else
if (field->name.value == L"imageCreation") ConvertJsonToCustomType(field->value, value.imageCreation); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::RendererCreation>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::RendererCreation& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::RendererCreation>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::RendererCreation&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"type") ConvertJsonToCustomType(field->value, value.type); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementBeginRendering>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementBeginRendering& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementBeginRendering>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementBeginRendering&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"frameId") ConvertJsonToCustomType(field->value, value.frameId); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementRendering>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementRendering& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementRendering>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementRendering&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"bounds") ConvertJsonToCustomType(field->value, value.bounds); else
if (field->name.value == L"areaClippedByParent") ConvertJsonToCustomType(field->value, value.areaClippedByParent); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementBoundary>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementBoundary& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementBoundary>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementBoundary&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"hitTestResult") ConvertJsonToCustomType(field->value, value.hitTestResult); else
if (field->name.value == L"cursor") ConvertJsonToCustomType(field->value, value.cursor); else
if (field->name.value == L"bounds") ConvertJsonToCustomType(field->value, value.bounds); else
if (field->name.value == L"areaClippedBySelf") ConvertJsonToCustomType(field->value, value.areaClippedBySelf); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementMeasuring_FontHeight>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementMeasuring_FontHeight& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementMeasuring_FontHeight>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementMeasuring_FontHeight&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"fontFamily") ConvertJsonToCustomType(field->value, value.fontFamily); else
if (field->name.value == L"fontSize") ConvertJsonToCustomType(field->value, value.fontSize); else
if (field->name.value == L"height") ConvertJsonToCustomType(field->value, value.height); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementMeasuring_ElementMinSize>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementMeasuring_ElementMinSize& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementMeasuring_ElementMinSize>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementMeasuring_ElementMinSize&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"minSize") ConvertJsonToCustomType(field->value, value.minSize); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementMeasurings>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::ElementMeasurings& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::ElementMeasurings>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::ElementMeasurings&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"fontHeights") ConvertJsonToCustomType(field->value, value.fontHeights); else
if (field->name.value == L"minSizes") ConvertJsonToCustomType(field->value, value.minSizes); else
if (field->name.value == L"createdImages") ConvertJsonToCustomType(field->value, value.createdImages); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::RenderingDomContent>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::RenderingDomContent& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::RenderingDomContent>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::RenderingDomContent&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"hitTestResult") ConvertJsonToCustomType(field->value, value.hitTestResult); else
if (field->name.value == L"cursor") ConvertJsonToCustomType(field->value, value.cursor); else
if (field->name.value == L"element") ConvertJsonToCustomType(field->value, value.element); else
if (field->name.value == L"bounds") ConvertJsonToCustomType(field->value, value.bounds); else
if (field->name.value == L"validArea") ConvertJsonToCustomType(field->value, value.validArea); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::RenderingDom>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::RenderingDom& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::RenderingDom>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::RenderingDom&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"content") ConvertJsonToCustomType(field->value, value.content); else
if (field->name.value == L"children") ConvertJsonToCustomType(field->value, value.children); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::RenderingDom_Diff>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::RenderingDom_Diff& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::RenderingDom_Diff>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::RenderingDom_Diff&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"id") ConvertJsonToCustomType(field->value, value.id); else
if (field->name.value == L"diffType") ConvertJsonToCustomType(field->value, value.diffType); else
if (field->name.value == L"content") ConvertJsonToCustomType(field->value, value.content); else
if (field->name.value == L"children") ConvertJsonToCustomType(field->value, value.children); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::RenderingDom_DiffsInOrder>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::RenderingDom_DiffsInOrder& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::RenderingDom_DiffsInOrder>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::RenderingDom_DiffsInOrder&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"diffsInOrder") ConvertJsonToCustomType(field->value, value.diffsInOrder); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::UnitTest_RenderingFrame>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::UnitTest_RenderingFrame& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::UnitTest_RenderingFrame>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::UnitTest_RenderingFrame&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"frameId") ConvertJsonToCustomType(field->value, value.frameId); else
if (field->name.value == L"frameName") ConvertJsonToCustomType(field->value, value.frameName); else
if (field->name.value == L"windowSize") ConvertJsonToCustomType(field->value, value.windowSize); else
if (field->name.value == L"elements") ConvertJsonToCustomType(field->value, value.elements); else
if (field->name.value == L"root") ConvertJsonToCustomType(field->value, value.root); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
template<> void ConvertJsonToCustomType<::vl::presentation::remoteprotocol::UnitTest_RenderingTrace>(vl::Ptr<vl::glr::json::JsonNode> node, ::vl::presentation::remoteprotocol::UnitTest_RenderingTrace& value)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::ConvertJsonToCustomType<::vl::presentation::remoteprotocol::UnitTest_RenderingTrace>(Ptr<JsonNode>, ::vl::presentation::remoteprotocol::UnitTest_RenderingTrace&)#"
auto jsonNode = node.Cast<glr::json::JsonObject>();
CHECK_ERROR(jsonNode, ERROR_MESSAGE_PREFIX L"Json node does not match the expected type.");
for (auto field : jsonNode->fields)
{
if (field->name.value == L"createdElements") ConvertJsonToCustomType(field->value, value.createdElements); else
if (field->name.value == L"imageCreations") ConvertJsonToCustomType(field->value, value.imageCreations); else
if (field->name.value == L"imageMetadatas") ConvertJsonToCustomType(field->value, value.imageMetadatas); else
if (field->name.value == L"frames") ConvertJsonToCustomType(field->value, value.frames); else
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unsupported struct member.");
}
#undef ERROR_MESSAGE_PREFIX
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTERENDERER\GUIREMOTERENDERERSINGLE.CPP
***********************************************************************/
namespace vl::presentation::remote_renderer
{
using namespace elements;
using namespace remoteprotocol;
remoteprotocol::ScreenConfig GuiRemoteRendererSingle::GetScreenConfig(INativeScreen* screen)
{
ScreenConfig response;
response.bounds = screen->GetBounds();
response.clientBounds = screen->GetClientBounds();
response.scalingX = screen->GetScalingX();
response.scalingY = screen->GetScalingY();
return response;
}
remoteprotocol::WindowSizingConfig GuiRemoteRendererSingle::GetWindowSizingConfig()
{
WindowSizingConfig response;
response.bounds = window->GetBounds();
response.clientBounds = window->GetClientBoundsInScreen();
response.sizeState = window->GetSizeState();
response.customFramePadding = window->GetCustomFramePadding();
return response;
}
void GuiRemoteRendererSingle::UpdateConfigsIfNecessary()
{
if (screen)
{
auto currentScreen = GetCurrentController()->ScreenService()->GetScreen(window);
if (screen != currentScreen)
{
screen = currentScreen;
events->OnControllerScreenUpdated(GetScreenConfig(screen));
}
auto newWindowSizingConfig = GetWindowSizingConfig();
if (
newWindowSizingConfig.bounds != windowSizingConfig.bounds ||
newWindowSizingConfig.clientBounds != windowSizingConfig.clientBounds)
{
windowSizingConfig = newWindowSizingConfig;
if (!updatingBounds)
{
events->OnWindowBoundsUpdated(windowSizingConfig);
}
}
else if (
newWindowSizingConfig.sizeState != windowSizingConfig.sizeState ||
newWindowSizingConfig.customFramePadding != windowSizingConfig.customFramePadding)
{
windowSizingConfig = newWindowSizingConfig;
events->OnWindowBoundsUpdated(windowSizingConfig);
}
}
}
void GuiRemoteRendererSingle::NativeWindowDestroying(INativeWindow* _window)
{
if (window == _window)
{
window->UninstallListener(this);
window = nullptr;
}
}
void GuiRemoteRendererSingle::Opened()
{
events->OnControllerConnect();
}
void GuiRemoteRendererSingle::BeforeClosing(bool& cancel)
{
if (!disconnectingFromCore)
{
cancel = true;
events->OnControllerRequestExit();
}
}
void GuiRemoteRendererSingle::AfterClosing()
{
renderingDom = nullptr;
availableElements.Clear();
availableImages.Clear();
}
void GuiRemoteRendererSingle::Closed()
{
}
void GuiRemoteRendererSingle::Moved()
{
UpdateConfigsIfNecessary();
}
void GuiRemoteRendererSingle::DpiChanged(bool preparing)
{
if (preparing)
{
UpdateRenderTarget(nullptr);
}
else
{
GetGuiGraphicsResourceManager()->RecreateRenderTarget(window);
UpdateRenderTarget(GetGuiGraphicsResourceManager()->GetRenderTarget(window));
UpdateConfigsIfNecessary();
}
}
void GuiRemoteRendererSingle::RenderingAsActivated()
{
if (disconnectingFromCore) return;
events->OnWindowActivatedUpdated(true);
}
void GuiRemoteRendererSingle::RenderingAsDeactivated()
{
if (disconnectingFromCore) return;
events->OnWindowActivatedUpdated(false);
}
GuiRemoteRendererSingle::GuiRemoteRendererSingle()
{
}
GuiRemoteRendererSingle::~GuiRemoteRendererSingle()
{
}
void GuiRemoteRendererSingle::RegisterMainWindow(INativeWindow* _window)
{
window = _window;
window->InstallListener(this);
GetCurrentController()->CallbackService()->InstallListener(this);
}
void GuiRemoteRendererSingle::UnregisterMainWindow()
{
UnregisterGlobalShortcutKeys();
GetCurrentController()->CallbackService()->UninstallListener(this);
}
void GuiRemoteRendererSingle::ForceExitByFatelError()
{
if (window)
{
disconnectingFromCore = true;
window->Hide(true);
}
}
WString GuiRemoteRendererSingle::GetExecutablePath()
{
CHECK_FAIL(L"This function should not be called!");
}
void GuiRemoteRendererSingle::Initialize(IGuiRemoteProtocolEvents* _events)
{
events = _events;
}
void GuiRemoteRendererSingle::Submit(bool& disconnected)
{
CHECK_FAIL(L"This function should not be called!");
}
void GuiRemoteRendererSingle::ProcessRemoteEvents()
{
CHECK_FAIL(L"This function should not be called!");
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTERENDERER\GUIREMOTERENDERERSINGLE_CONTROLLER.CPP
***********************************************************************/
namespace vl::presentation::remote_renderer
{
using namespace collections;
using namespace remoteprotocol;
void GuiRemoteRendererSingle::RequestControllerGetFontConfig(vint id)
{
FontConfig response;
auto rs = GetCurrentController()->ResourceService();
response.defaultFont = rs->GetDefaultFont();
response.supportedFonts = Ptr(new List<WString>);
rs->EnumerateFonts(*response.supportedFonts.Obj());
events->RespondControllerGetFontConfig(id, response);
}
void GuiRemoteRendererSingle::RequestControllerGetScreenConfig(vint id)
{
auto primary = screen ? screen : GetCurrentController()->ScreenService()->GetScreen((vint)0);
events->RespondControllerGetScreenConfig(id, GetScreenConfig(primary));
}
void GuiRemoteRendererSingle::RequestControllerConnectionEstablished()
{
}
void GuiRemoteRendererSingle::RequestControllerConnectionStopped()
{
if (window)
{
disconnectingFromCore = true;
window->ReleaseCapture();
window->Hide(true);
}
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTERENDERER\GUIREMOTERENDERERSINGLE_IO.CPP
***********************************************************************/
namespace vl::presentation::remote_renderer
{
using namespace remoteprotocol;
/***********************************************************************
* Rendering (Commands)
***********************************************************************/
void GuiRemoteRendererSingle::UnregisterGlobalShortcutKeys()
{
auto inputService = GetCurrentController()->InputService();
for (vint id : globalShortcuts.Keys())
{
inputService->UnregisterGlobalShortcutKey(id);
}
globalShortcuts.Clear();
}
void GuiRemoteRendererSingle::GlobalShortcutKeyActivated(vint id)
{
vint index = globalShortcuts.Keys().IndexOf(id);
if (index != -1)
{
events->OnIOGlobalShortcutKey(globalShortcuts.Values()[index].id);
}
}
void GuiRemoteRendererSingle::RequestIOUpdateGlobalShortcutKey(const Ptr<collections::List<remoteprotocol::GlobalShortcutKey>>& arguments)
{
UnregisterGlobalShortcutKeys();
if (arguments)
{
auto inputService = GetCurrentController()->InputService();
for (auto&& shortcut : *arguments.Obj())
{
vint id = inputService->RegisterGlobalShortcutKey(shortcut.ctrl, shortcut.shift, shortcut.alt, shortcut.code);
if (id != -1)
{
globalShortcuts.Add(id, shortcut);
}
}
}
}
void GuiRemoteRendererSingle::RequestIORequireCapture()
{
window->RequireCapture();
}
void GuiRemoteRendererSingle::RequestIOReleaseCapture()
{
window->ReleaseCapture();
}
void GuiRemoteRendererSingle::RequestIOIsKeyPressing(vint id, const VKEY& arguments)
{
CHECK_FAIL(L"Not Implemented");
}
void GuiRemoteRendererSingle::RequestIOIsKeyToggled(vint id, const VKEY& arguments)
{
CHECK_FAIL(L"Not Implemented");
}
/***********************************************************************
* Rendering (INativeWindow)
***********************************************************************/
void GuiRemoteRendererSingle::LeftButtonDown(const NativeWindowMouseInfo& info)
{
IOMouseInfoWithButton arguments;
arguments.button = IOMouseButton::Left;
arguments.info = info;
events->OnIOButtonDown(arguments);
}
void GuiRemoteRendererSingle::LeftButtonUp(const NativeWindowMouseInfo& info)
{
IOMouseInfoWithButton arguments;
arguments.button = IOMouseButton::Left;
arguments.info = info;
events->OnIOButtonUp(arguments);
}
void GuiRemoteRendererSingle::LeftButtonDoubleClick(const NativeWindowMouseInfo& info)
{
IOMouseInfoWithButton arguments;
arguments.button = IOMouseButton::Left;
arguments.info = info;
events->OnIOButtonDoubleClick(arguments);
}
void GuiRemoteRendererSingle::RightButtonDown(const NativeWindowMouseInfo& info)
{
IOMouseInfoWithButton arguments;
arguments.button = IOMouseButton::Right;
arguments.info = info;
events->OnIOButtonDown(arguments);
}
void GuiRemoteRendererSingle::RightButtonUp(const NativeWindowMouseInfo& info)
{
IOMouseInfoWithButton arguments;
arguments.button = IOMouseButton::Right;
arguments.info = info;
events->OnIOButtonUp(arguments);
}
void GuiRemoteRendererSingle::RightButtonDoubleClick(const NativeWindowMouseInfo& info)
{
IOMouseInfoWithButton arguments;
arguments.button = IOMouseButton::Right;
arguments.info = info;
events->OnIOButtonDoubleClick(arguments);
}
void GuiRemoteRendererSingle::MiddleButtonDown(const NativeWindowMouseInfo& info)
{
IOMouseInfoWithButton arguments;
arguments.button = IOMouseButton::Middle;
arguments.info = info;
events->OnIOButtonDown(arguments);
}
void GuiRemoteRendererSingle::MiddleButtonUp(const NativeWindowMouseInfo& info)
{
IOMouseInfoWithButton arguments;
arguments.button = IOMouseButton::Middle;
arguments.info = info;
events->OnIOButtonUp(arguments);
}
void GuiRemoteRendererSingle::MiddleButtonDoubleClick(const NativeWindowMouseInfo& info)
{
IOMouseInfoWithButton arguments;
arguments.button = IOMouseButton::Middle;
arguments.info = info;
events->OnIOButtonDoubleClick(arguments);
}
void GuiRemoteRendererSingle::HorizontalWheel(const NativeWindowMouseInfo& info)
{
events->OnIOHWheel(info);
}
void GuiRemoteRendererSingle::VerticalWheel(const NativeWindowMouseInfo& info)
{
events->OnIOVWheel(info);
}
void GuiRemoteRendererSingle::MouseMoving(const NativeWindowMouseInfo& info)
{
if (renderingDom)
{
INativeWindowListener::HitTestResult hitTestResult = INativeWindowListener::NoDecision;
INativeCursor* cursor = nullptr;
HitTest(renderingDom, window->Convert(NativePoint{ info.x,info.y }), hitTestResult, cursor);
window->SetWindowCursor(cursor);
}
events->OnIOMouseMoving(info);
}
void GuiRemoteRendererSingle::MouseEntered()
{
events->OnIOMouseEntered();
}
void GuiRemoteRendererSingle::MouseLeaved()
{
events->OnIOMouseLeaved();
}
void GuiRemoteRendererSingle::KeyDown(const NativeWindowKeyInfo& info)
{
events->OnIOKeyDown(info);
}
void GuiRemoteRendererSingle::KeyUp(const NativeWindowKeyInfo& info)
{
if (!info.ctrl && !info.shift && info.code == VKEY::KEY_MENU)
{
window->SupressAlt();
}
events->OnIOKeyUp(info);
}
void GuiRemoteRendererSingle::Char(const NativeWindowCharInfo& info)
{
events->OnIOChar(info);
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTERENDERER\GUIREMOTERENDERERSINGLE_MAINWINDOW.CPP
***********************************************************************/
namespace vl::presentation::remote_renderer
{
using namespace remoteprotocol;
void GuiRemoteRendererSingle::RequestWindowGetBounds(vint id)
{
events->RespondWindowGetBounds(id, GetWindowSizingConfig());
}
void GuiRemoteRendererSingle::RequestWindowNotifySetBounds(const NativeRect& arguments)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remote_renderer::GuiRemoteRendererSingle::RequestWindowNotifySetBounds(const NativeRect&)#"
CHECK_ERROR(!updatingBounds, ERROR_MESSAGE_PREFIX L"This function cannot be called recursively.");
updatingBounds = true;
if (!screen)
{
auto primary = GetCurrentController()->ScreenService()->GetScreen((vint)0);
NativeRect screenBounds = primary->GetBounds();
NativeRect windowBounds = arguments;
windowBounds.x1 = (screenBounds.Width() - windowBounds.Width()) / 2;
windowBounds.y1 = (screenBounds.Height() - windowBounds.Height()) / 2;
window->SetBounds(windowBounds);
screen = primary;
windowSizingConfig = GetWindowSizingConfig();
}
else
{
window->SetBounds(arguments);
}
updatingBounds = false;
#undef ERROR_MESSAGE_PREFIX
}
void GuiRemoteRendererSingle::RequestWindowNotifySetTitle(const WString& arguments)
{
window->SetTitle(arguments);
}
void GuiRemoteRendererSingle::RequestWindowNotifySetEnabled(const bool& arguments)
{
if (arguments)
{
window->Enable();
}
else
{
window->Disable();
}
}
void GuiRemoteRendererSingle::RequestWindowNotifySetTopMost(const bool& arguments)
{
window->SetTopMost(arguments);
}
void GuiRemoteRendererSingle::RequestWindowNotifySetShowInTaskBar(const bool& arguments)
{
if (arguments)
{
window->ShowInTaskBar();
}
else
{
window->HideInTaskBar();
}
}
void GuiRemoteRendererSingle::RequestWindowNotifySetClientSize(const NativeSize& arguments)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remote_renderer::GuiRemoteRendererSingle::RequestWindowNotifySetClientSize(const NativeSize&)#"
CHECK_ERROR(screen, ERROR_MESSAGE_PREFIX L"This function cannot be called before RequestWindowNotifySetBounds.");
window->SetClientSize(arguments);
#undef ERROR_MESSAGE_PREFIX
}
void GuiRemoteRendererSingle::RequestWindowNotifySetCustomFrameMode(const bool& arguments)
{
if (window->IsCustomFrameModeEnabled() != arguments)
{
if (arguments)
{
window->EnableCustomFrameMode();
}
else
{
window->DisableCustomFrameMode();
}
UpdateConfigsIfNecessary();
}
}
void GuiRemoteRendererSingle::RequestWindowNotifySetMaximizedBox(const bool& arguments)
{
window->SetMaximizedBox(arguments);
UpdateConfigsIfNecessary();
}
void GuiRemoteRendererSingle::RequestWindowNotifySetMinimizedBox(const bool& arguments)
{
window->SetMinimizedBox(arguments);
UpdateConfigsIfNecessary();
}
void GuiRemoteRendererSingle::RequestWindowNotifySetBorder(const bool& arguments)
{
window->SetBorder(arguments);
UpdateConfigsIfNecessary();
}
void GuiRemoteRendererSingle::RequestWindowNotifySetSizeBox(const bool& arguments)
{
window->SetSizeBox(arguments);
UpdateConfigsIfNecessary();
}
void GuiRemoteRendererSingle::RequestWindowNotifySetIconVisible(const bool& arguments)
{
window->SetIconVisible(arguments);
UpdateConfigsIfNecessary();
}
void GuiRemoteRendererSingle::RequestWindowNotifySetTitleBar(const bool& arguments)
{
window->SetTitleBar(arguments);
UpdateConfigsIfNecessary();
}
void GuiRemoteRendererSingle::RequestWindowNotifyActivate()
{
window->SetActivate();
}
void GuiRemoteRendererSingle::RequestWindowNotifyShow(const remoteprotocol::WindowShowing& arguments)
{
if (arguments.sizeState != window->GetSizeState())
{
if (arguments.activate)
{
window->SetActivate();
}
switch (arguments.sizeState)
{
case INativeWindow::Minimized:
window->ShowMinimized();
break;
case INativeWindow::Restored:
window->ShowRestored();
break;
case INativeWindow::Maximized:
window->ShowMaximized();
break;
}
}
}
}
/***********************************************************************
.\PLATFORMPROVIDERS\REMOTERENDERER\GUIREMOTERENDERERSINGLE_RENDERING.CPP
***********************************************************************/
namespace vl::presentation::remote_renderer
{
using namespace collections;
using namespace elements;
using namespace remoteprotocol;
Alignment GuiRemoteRendererSingle::GetAlignment(remoteprotocol::ElementHorizontalAlignment alignment)
{
switch (alignment)
{
case remoteprotocol::ElementHorizontalAlignment::Left: return Alignment::Left;
case remoteprotocol::ElementHorizontalAlignment::Right: return Alignment::Right;
default: return Alignment::Center;
}
}
Alignment GuiRemoteRendererSingle::GetAlignment(remoteprotocol::ElementVerticalAlignment alignment)
{
switch (alignment)
{
case remoteprotocol::ElementVerticalAlignment::Top: return Alignment::Top;
case remoteprotocol::ElementVerticalAlignment::Bottom: return Alignment::Bottom;
default: return Alignment::Center;
}
}
/***********************************************************************
* Rendering
***********************************************************************/
void GuiRemoteRendererSingle::RequestRendererCreated(const Ptr<collections::List<remoteprotocol::RendererCreation>>& arguments)
{
if (arguments)
{
for (auto&& rc : *arguments.Obj())
{
Ptr<IGuiGraphicsElement> element;
switch (rc.type)
{
case RendererType::FocusRectangle:
element = Ptr(GuiFocusRectangleElement::Create());
break;
case RendererType::SolidBorder:
element = Ptr(GuiSolidBorderElement::Create());
break;
case RendererType::SinkBorder:
element = Ptr(Gui3DBorderElement::Create());
break;
case RendererType::SinkSplitter:
element = Ptr(Gui3DSplitterElement::Create());
break;
case RendererType::SolidBackground:
element = Ptr(GuiSolidBackgroundElement::Create());
break;
case RendererType::GradientBackground:
element = Ptr(GuiGradientBackgroundElement::Create());
break;
case RendererType::InnerShadow:
element = Ptr(GuiInnerShadowElement::Create());
break;
case RendererType::SolidLabel:
element = Ptr(GuiSolidLabelElement::Create());
break;
case RendererType::Polygon:
element = Ptr(GuiPolygonElement::Create());
break;
case RendererType::ImageFrame:
element = Ptr(GuiImageFrameElement::Create());
break;
default:;
}
element->GetRenderer()->SetRenderTarget(GetGuiGraphicsResourceManager()->GetRenderTarget(window));
if (availableElements.Keys().Contains(rc.id))
{
availableElements.Set(rc.id, element);
}
else
{
availableElements.Add(rc.id, element);
}
}
}
}
void GuiRemoteRendererSingle::RequestRendererDestroyed(const Ptr<collections::List<vint>>& arguments)
{
if (arguments)
{
for (auto id : *arguments.Obj())
{
availableElements.Remove(id);
solidLabelMeasurings.Remove(id);
}
}
}
void GuiRemoteRendererSingle::RequestRendererBeginRendering(const remoteprotocol::ElementBeginRendering& arguments)
{
}
void GuiRemoteRendererSingle::RequestRendererEndRendering(vint id)
{
events->RespondRendererEndRendering(id, elementMeasurings);
elementMeasurings = {};
fontHeightMeasurings.Clear();
}
/***********************************************************************
* Rendering (Elemnents)
***********************************************************************/
void GuiRemoteRendererSingle::RequestRendererUpdateElement_SolidBorder(const remoteprotocol::ElementDesc_SolidBorder& arguments)
{
vint index = availableElements.Keys().IndexOf(arguments.id);
if (index == -1) return;
auto element = availableElements.Values()[index].Cast<GuiSolidBorderElement>();
if (!element) return;
element->SetColor(arguments.borderColor);
element->SetShape(arguments.shape);
}
void GuiRemoteRendererSingle::RequestRendererUpdateElement_SinkBorder(const remoteprotocol::ElementDesc_SinkBorder& arguments)
{
vint index = availableElements.Keys().IndexOf(arguments.id);
if (index == -1) return;
auto element = availableElements.Values()[index].Cast<Gui3DBorderElement>();
if (!element) return;
element->SetColors(arguments.leftTopColor, arguments.rightBottomColor);
}
void GuiRemoteRendererSingle::RequestRendererUpdateElement_SinkSplitter(const remoteprotocol::ElementDesc_SinkSplitter& arguments)
{
vint index = availableElements.Keys().IndexOf(arguments.id);
if (index == -1) return;
auto element = availableElements.Values()[index].Cast<Gui3DSplitterElement>();
if (!element) return;
element->SetColors(arguments.leftTopColor, arguments.rightBottomColor);
element->SetDirection(arguments.direction);
}
void GuiRemoteRendererSingle::RequestRendererUpdateElement_SolidBackground(const remoteprotocol::ElementDesc_SolidBackground& arguments)
{
vint index = availableElements.Keys().IndexOf(arguments.id);
if (index == -1) return;
auto element = availableElements.Values()[index].Cast<GuiSolidBackgroundElement>();
if (!element) return;
element->SetColor(arguments.backgroundColor);
element->SetShape(arguments.shape);
}
void GuiRemoteRendererSingle::RequestRendererUpdateElement_GradientBackground(const remoteprotocol::ElementDesc_GradientBackground& arguments)
{
vint index = availableElements.Keys().IndexOf(arguments.id);
if (index == -1) return;
auto element = availableElements.Values()[index].Cast<GuiGradientBackgroundElement>();
if (!element) return;
element->SetColors(arguments.leftTopColor, arguments.rightBottomColor);
element->SetDirection(arguments.direction);
element->SetShape(arguments.shape);
}
void GuiRemoteRendererSingle::RequestRendererUpdateElement_InnerShadow(const remoteprotocol::ElementDesc_InnerShadow& arguments)
{
vint index = availableElements.Keys().IndexOf(arguments.id);
if (index == -1) return;
auto element = availableElements.Values()[index].Cast<GuiInnerShadowElement>();
if (!element) return;
element->SetColor(arguments.shadowColor);
element->SetThickness(arguments.thickness);
}
void GuiRemoteRendererSingle::RequestRendererUpdateElement_Polygon(const remoteprotocol::ElementDesc_Polygon& arguments)
{
vint index = availableElements.Keys().IndexOf(arguments.id);
if (index == -1) return;
auto element = availableElements.Values()[index].Cast<GuiPolygonElement>();
if (!element) return;
element->SetSize(arguments.size);
element->SetBorderColor(arguments.borderColor);
element->SetBackgroundColor(arguments.backgroundColor);
if (arguments.points && arguments.points->Count() > 0)
{
element->SetPoints(&arguments.points->Get(0), arguments.points->Count());
}
}
/***********************************************************************
* Rendering (Elemnents -- Label)
***********************************************************************/
void GuiRemoteRendererSingle::StoreLabelMeasuring(vint id, remoteprotocol::ElementSolidLabelMeasuringRequest request, Ptr<elements::GuiSolidLabelElement> solidLabel, Size minSize)
{
switch (request)
{
case ElementSolidLabelMeasuringRequest::FontHeight:
{
Pair<WString, vint> key = { solidLabel->GetFont().fontFamily,solidLabel->GetFont().size };
if (fontHeightMeasurings.Contains(key)) return;
fontHeightMeasurings.Add(key);
ElementMeasuring_FontHeight response;
response.fontFamily = key.key;
response.fontSize = key.value;
response.height = minSize.y;
if (!elementMeasurings.fontHeights)
{
elementMeasurings.fontHeights = Ptr(new List<ElementMeasuring_FontHeight>);
}
elementMeasurings.fontHeights->Add(response);
}
break;
case ElementSolidLabelMeasuringRequest::TotalSize:
{
ElementMeasuring_ElementMinSize response;
response.id = id;
response.minSize = minSize;
if (!elementMeasurings.minSizes)
{
elementMeasurings.minSizes = Ptr(new List<ElementMeasuring_ElementMinSize>);
}
elementMeasurings.minSizes->Add(response);
}
break;
}
}
void GuiRemoteRendererSingle::RequestRendererUpdateElement_SolidLabel(const remoteprotocol::ElementDesc_SolidLabel& arguments)
{
vint index = availableElements.Keys().IndexOf(arguments.id);
if (index == -1) return;
auto element = availableElements.Values()[index].Cast<GuiSolidLabelElement>();
if (!element) return;
element->SetColor(arguments.textColor);
element->SetAlignments(GetAlignment(arguments.horizontalAlignment), GetAlignment(arguments.verticalAlignment));
element->SetWrapLine(arguments.wrapLine);
element->SetWrapLineHeightCalculation(arguments.wrapLineHeightCalculation);
element->SetEllipse(arguments.ellipse);
element->SetMultiline(arguments.multiline);
if (arguments.font)
{
element->SetFont(arguments.font.Value());
}
if (arguments.text)
{
element->SetText(arguments.text.Value());
}
if (arguments.measuringRequest)
{
SolidLabelMeasuring measuring;
measuring.request = arguments.measuringRequest.Value();
index = solidLabelMeasurings.Keys().IndexOf(arguments.id);
if (solidLabelMeasurings.Keys().Contains(arguments.id))
{
solidLabelMeasurings.Set(arguments.id, measuring);
}
else
{
solidLabelMeasurings.Add(arguments.id, measuring);
}
StoreLabelMeasuring(arguments.id, measuring.request, element, element->GetRenderer()->GetMinSize());
}
}
/***********************************************************************
* Rendering (Elements -- Image)
***********************************************************************/
remoteprotocol::ImageMetadata GuiRemoteRendererSingle::CreateImageMetadata(vint id, INativeImage* image)
{
ImageMetadata response;
response.id = id;
response.format = image->GetFormat();
response.frames = Ptr(new List<ImageFrameMetadata>);
for (vint i = 0; i < image->GetFrameCount(); i++)
{
auto frame = image->GetFrame(i);
response.frames->Add({ frame->GetSize() });
}
return response;
}
remoteprotocol::ImageMetadata GuiRemoteRendererSingle::CreateImage(const remoteprotocol::ImageCreation& arguments)
{
arguments.imageData->SeekFromBegin(0);
auto image = GetCurrentController()->ImageService()->CreateImageFromStream(*arguments.imageData.Obj());
if (availableImages.Keys().Contains(arguments.id))
{
availableImages.Set(arguments.id, image);
}
else
{
availableImages.Add(arguments.id, image);
}
return CreateImageMetadata(arguments.id, image.Obj());
}
void GuiRemoteRendererSingle::RequestImageCreated(vint id, const remoteprotocol::ImageCreation& arguments)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remote_renderer::GuiRemoteRendererSingle::RequestImageCreated(const ImageCreation&)#"
CHECK_ERROR(!arguments.imageDataOmitted && arguments.imageData, ERROR_MESSAGE_PREFIX L"Binary content of the image is missing.");
events->RespondImageCreated(id, CreateImage(arguments));
#undef ERROR_MESSAGE_PREFIX
}
void GuiRemoteRendererSingle::RequestImageDestroyed(const vint& arguments)
{
availableImages.Remove(arguments);
}
void GuiRemoteRendererSingle::RequestRendererUpdateElement_ImageFrame(const remoteprotocol::ElementDesc_ImageFrame& arguments)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remote_renderer::GuiRemoteRendererSingle::RequestRendererUpdateElement_ImageFrame(const arguments&)#"
vint index = availableElements.Keys().IndexOf(arguments.id);
if (index == -1) return;
auto element = availableElements.Values()[index].Cast<GuiImageFrameElement>();
if (!element) return;
element->SetAlignments(GetAlignment(arguments.horizontalAlignment), GetAlignment(arguments.verticalAlignment));
element->SetStretch(arguments.stretch);
element->SetEnabled(arguments.enabled);
if (arguments.imageId && arguments.imageCreation)
{
CHECK_ERROR(arguments.imageId.Value() == arguments.imageCreation.Value().id, ERROR_MESSAGE_PREFIX L"imageId and imageCreation.id must be identical.");
}
if (arguments.imageId)
{
if (arguments.imageCreation && !elementMeasurings.createdImages)
{
elementMeasurings.createdImages = Ptr(new List<ImageMetadata>);
}
vint index = availableImages.Keys().IndexOf(arguments.imageId.Value());
if (index == -1)
{
CHECK_ERROR(arguments.imageCreation && !arguments.imageCreation.Value().imageDataOmitted && arguments.imageCreation.Value().imageData, ERROR_MESSAGE_PREFIX L"Binary content of the image is missing.");
auto response = CreateImage(arguments.imageCreation.Value());
element->SetImage(availableImages[response.id], arguments.imageFrame);
elementMeasurings.createdImages->Add(response);
}
else
{
auto image = availableImages.Values()[index];
element->SetImage(image, arguments.imageFrame);
if (arguments.imageCreation)
{
elementMeasurings.createdImages->Add(CreateImageMetadata(arguments.imageId.Value(), image.Obj()));
}
}
}
#undef ERROR_MESSAGE_PREFIX
}
/***********************************************************************
* Rendering (Dom)
***********************************************************************/
void GuiRemoteRendererSingle::CheckDom()
{
needRefresh = true;
}
void GuiRemoteRendererSingle::RequestRendererRenderDom(const Ptr<remoteprotocol::RenderingDom>& arguments)
{
renderingDom = arguments;
if (renderingDom)
{
BuildDomIndex(renderingDom, renderingDomIndex);
}
CheckDom();
}
void GuiRemoteRendererSingle::RequestRendererRenderDomDiff(const remoteprotocol::RenderingDom_DiffsInOrder& arguments)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remote_renderer::GuiRemoteRendererSingle::RequestRendererRenderDomDiff(const RenderingDom_DiffsInOrder&)#"
CHECK_ERROR(renderingDom, ERROR_MESSAGE_PREFIX L"This function must be called after RequestRendererRenderDom.");
UpdateDomInplace(renderingDom, renderingDomIndex, arguments);
CheckDom();
#undef ERROR_MESSAGE_PREFIX
}
/***********************************************************************
* Rendering (Commands)
***********************************************************************/
void GuiRemoteRendererSingle::RequestRendererBeginBoundary(const remoteprotocol::ElementBoundary& arguments)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remote_renderer::GuiRemoteRendererSingle::RequestRendererBeginBoundary(const ElementBoundary&)#"
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"The current implementation require dom-diff enabled in core side.");
#undef ERROR_MESSAGE_PREFIX
}
void GuiRemoteRendererSingle::RequestRendererEndBoundary()
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remote_renderer::GuiRemoteRendererSingle::RequestRendererEndBoundary()#"
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"The current implementation require dom-diff enabled in core side.");
#undef ERROR_MESSAGE_PREFIX
}
void GuiRemoteRendererSingle::RequestRendererRenderElement(const remoteprotocol::ElementRendering& arguments)
{
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remote_renderer::GuiRemoteRendererSingle::RequestRendererRenderElement(const ElementRendering&)#"
CHECK_FAIL(ERROR_MESSAGE_PREFIX L"The current implementation require dom-diff enabled in core side.");
#undef ERROR_MESSAGE_PREFIX
}
/***********************************************************************
* Rendering (INativeWindow)
***********************************************************************/
void GuiRemoteRendererSingle::UpdateRenderTarget(elements::IGuiGraphicsRenderTarget* rt)
{
for (auto element : availableElements.Values())
{
element->GetRenderer()->SetRenderTarget(rt);
}
}
void GuiRemoteRendererSingle::Render(Ptr<remoteprotocol::RenderingDom> dom, elements::IGuiGraphicsRenderTarget* rt)
{
if (dom->content.element)
{
vint index = availableElements.Keys().IndexOf(dom->content.element.Value());
if (index != -1)
{
auto element = availableElements.Values()[index];
rt->PushClipper(dom->content.validArea, nullptr);
element->GetRenderer()->Render(dom->content.bounds);
rt->PopClipper(nullptr);
if (auto solidLabel = element.Cast<GuiSolidLabelElement>())
{
index = solidLabelMeasurings.Keys().IndexOf(dom->content.element.Value());
if (index != -1)
{
auto& measuring = const_cast<SolidLabelMeasuring&>(solidLabelMeasurings.Values()[index]);
auto minSize = element->GetRenderer()->GetMinSize();
bool measuringChanged = false;
if (!measuring.minSize)
{
measuringChanged = true;
}
else switch (measuring.request)
{
case ElementSolidLabelMeasuringRequest::FontHeight:
if (measuring.minSize.Value().y != minSize.y)
{
measuringChanged = true;
}
break;
case ElementSolidLabelMeasuringRequest::TotalSize:
if (measuring.minSize.Value() != minSize)
{
measuringChanged = true;
}
break;
}
measuring.minSize = minSize;
if (measuringChanged)
{
StoreLabelMeasuring(dom->content.element.Value(), measuring.request, solidLabel, minSize);
}
}
}
}
}
if (dom->children)
{
for (auto child : *dom->children.Obj())
{
if (child->content.validArea.Width() > 0 && child->content.validArea.Height()> 0)
{
Render(child, rt);
}
}
}
}
void GuiRemoteRendererSingle::HitTestInternal(Ptr<remoteprotocol::RenderingDom> dom, Point location, Nullable<INativeWindowListener::HitTestResult>& hitTestResult, Nullable<INativeCursor::SystemCursorType>& cursorType)
{
if (dom->children)
{
for (auto child : *dom->children.Obj())
{
if (child->content.validArea.Contains(location))
{
HitTestInternal(child, location, hitTestResult, cursorType);
if (!hitTestResult && child->content.hitTestResult)
{
hitTestResult = child->content.hitTestResult;
}
if (!cursorType && child->content.cursor)
{
cursorType = child->content.cursor;
}
}
}
}
}
void GuiRemoteRendererSingle::HitTest(Ptr<remoteprotocol::RenderingDom> dom, Point location, INativeWindowListener::HitTestResult& hitTestResult, INativeCursor*& cursor)
{
Nullable<INativeWindowListener::HitTestResult> hitTestResultNullable;
Nullable<INativeCursor::SystemCursorType> cursorTypeNullable;
HitTestInternal(dom, location, hitTestResultNullable, cursorTypeNullable);
hitTestResult = hitTestResultNullable ? hitTestResultNullable.Value() : INativeWindowListener::NoDecision;
cursor = cursorTypeNullable ? GetCurrentController()->ResourceService()->GetSystemCursor(cursorTypeNullable.Value()) : GetCurrentController()->ResourceService()->GetDefaultSystemCursor();
}
void GuiRemoteRendererSingle::GlobalTimer()
{
if (!needRefresh) return;
needRefresh = false;
if (!window) return;
if (!renderingDom) return;
supressPaint = true;
auto rt = GetGuiGraphicsResourceManager()->GetRenderTarget(window);
rt->StartRendering();
Render(renderingDom, rt);
auto result = rt->StopRendering();
window->RedrawContent();
supressPaint = false;
switch (result)
{
case RenderTargetFailure::ResizeWhileRendering:
GetGuiGraphicsResourceManager()->ResizeRenderTarget(window);
needRefresh = true;
break;
case RenderTargetFailure::LostDevice:
UpdateRenderTarget(nullptr);
GetGuiGraphicsResourceManager()->RecreateRenderTarget(window);
UpdateRenderTarget(GetGuiGraphicsResourceManager()->GetRenderTarget(window));
needRefresh = true;
break;
default:;
}
}
void GuiRemoteRendererSingle::Paint()
{
if (!supressPaint)
{
needRefresh = true;
}
}
INativeWindowListener::HitTestResult GuiRemoteRendererSingle::HitTest(NativePoint location)
{
INativeWindowListener::HitTestResult hitTestResult = INativeWindowListener::NoDecision;
INativeCursor* cursor = nullptr;
if (renderingDom)
{
HitTest(renderingDom, window->Convert(location), hitTestResult, cursor);
}
return hitTestResult;
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENT.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace glr::xml;
using namespace regex;
using namespace stream;
/***********************************************************************
DocumentFontSize
***********************************************************************/
DocumentFontSize DocumentFontSize::Parse(const WString& value)
{
if (value.Length() > 0 && value[value.Length() - 1] == L'x')
{
return DocumentFontSize(wtof(value.Left(value.Length() - 1)), true);
}
else
{
return DocumentFontSize(wtof(value), false);
}
}
WString DocumentFontSize::ToString()const
{
return ftow(size) + (relative ? L"x" : L"");
}
/***********************************************************************
DocumentImageRun
***********************************************************************/
const wchar_t* DocumentImageRun::RepresentationText=L"[Image]";
const wchar_t* DocumentEmbeddedObjectRun::RepresentationText=L"[EmbeddedObject]";
/***********************************************************************
ExtractTextVisitor
***********************************************************************/
namespace document_operation_visitors
{
class ExtractTextVisitor : public Object, public DocumentRun::IVisitor
{
public:
stream::TextWriter& writer;
bool skipNonTextContent;
ExtractTextVisitor(stream::TextWriter& _writer, bool _skipNonTextContent)
:writer(_writer)
,skipNonTextContent(_skipNonTextContent)
{
}
void VisitContainer(DocumentContainerRun* run)
{
for (auto subRun : run->runs)
{
subRun->Accept(this);
}
}
void VisitContent(DocumentContentRun* run)
{
writer.WriteString(run->GetRepresentationText());
}
void Visit(DocumentTextRun* run)override
{
VisitContent(run);
}
void Visit(DocumentStylePropertiesRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentStyleApplicationRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentHyperlinkRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentImageRun* run)override
{
if(!skipNonTextContent)
{
VisitContent(run);
}
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
if(!skipNonTextContent)
{
VisitContent(run);
}
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
}
using namespace document_operation_visitors;
/***********************************************************************
DocumentParagraphRun
***********************************************************************/
WString DocumentParagraphRun::GetText(bool skipNonTextContent)
{
return GenerateToStream([&](StreamWriter& writer)
{
GetText(writer, skipNonTextContent);
});
}
void DocumentParagraphRun::GetText(stream::TextWriter& writer, bool skipNonTextContent)
{
ExtractTextVisitor visitor(writer, skipNonTextContent);
Accept(&visitor);
}
/***********************************************************************
DocumentModel
***********************************************************************/
const wchar_t* DocumentModel::DefaultStyleName = L"#Default";
const wchar_t* DocumentModel::SelectionStyleName = L"#Selection";
const wchar_t* DocumentModel::ContextStyleName = L"#Context";
const wchar_t* DocumentModel::NormalLinkStyleName = L"#NormalLink";
const wchar_t* DocumentModel::ActiveLinkStyleName = L"#ActiveLink";
DocumentModel::DocumentModel()
{
{
FontProperties font=GetCurrentController()->ResourceService()->GetDefaultFont();
auto sp=Ptr(new DocumentStyleProperties);
sp->face=font.fontFamily;
sp->size=DocumentFontSize((double)font.size, false);
sp->color=Color();
sp->backgroundColor=Color(0, 0, 0, 0);
sp->bold=font.bold;
sp->italic=font.italic;
sp->underline=font.underline;
sp->strikeline=font.strikeline;
sp->antialias=font.antialias;
sp->verticalAntialias=font.verticalAntialias;
auto style = Ptr(new DocumentStyle);
style->styles=sp;
styles.Add(L"#Default", style);
}
{
auto sp = Ptr(new DocumentStyleProperties);
sp->color=Color(255, 255, 255);
sp->backgroundColor=Color(51, 153, 255);
auto style = Ptr(new DocumentStyle);
style->styles=sp;
styles.Add(L"#Selection", style);
}
{
auto sp = Ptr(new DocumentStyleProperties);
auto style = Ptr(new DocumentStyle);
style->styles=sp;
styles.Add(L"#Context", style);
}
{
auto sp = Ptr(new DocumentStyleProperties);
sp->color=Color(0, 0, 255);
sp->underline=true;
auto style = Ptr(new DocumentStyle);
style->parentStyleName=L"#Context";
style->styles=sp;
styles.Add(L"#NormalLink", style);
}
{
auto sp = Ptr(new DocumentStyleProperties);
sp->color=Color(255, 128, 0);
sp->underline=true;
auto style = Ptr(new DocumentStyle);
style->parentStyleName=L"#Context";
style->styles=sp;
styles.Add(L"#ActiveLink", style);
}
}
void DocumentModel::MergeStyle(Ptr<DocumentStyleProperties> style, Ptr<DocumentStyleProperties> parent)
{
if(!style->face && parent->face) style->face =parent->face;
if(!style->size && parent->size) style->size =parent->size;
if(!style->color && parent->color) style->color =parent->color;
if(!style->backgroundColor && parent->backgroundColor) style->backgroundColor =parent->backgroundColor;
if(!style->bold && parent->bold) style->bold =parent->bold;
if(!style->italic && parent->italic) style->italic =parent->italic;
if(!style->underline && parent->underline) style->underline =parent->underline;
if(!style->strikeline && parent->strikeline) style->strikeline =parent->strikeline;
if(!style->antialias && parent->antialias) style->antialias =parent->antialias;
if(!style->verticalAntialias && parent->verticalAntialias) style->verticalAntialias =parent->verticalAntialias;
}
void DocumentModel::MergeBaselineStyle(Ptr<DocumentStyleProperties> style, const WString& styleName)
{
auto indexDst = styles.Keys().IndexOf(styleName);
auto sp = Ptr(new DocumentStyleProperties);
MergeStyle(sp, style);
if (indexDst != -1)
{
MergeStyle(sp, styles.Values()[indexDst]->styles);
}
if (indexDst == -1)
{
auto style = Ptr(new DocumentStyle);
style->styles = sp;
styles.Add(styleName, style);
}
else
{
styles.Values()[indexDst]->styles = sp;
}
for (auto style : styles.Values())
{
style->resolvedStyles = nullptr;
}
}
void DocumentModel::MergeBaselineStyle(Ptr<DocumentModel> baselineDocument, const WString& styleName)
{
auto indexSrc = baselineDocument->styles.Keys().IndexOf(styleName + L"-Override");
if (indexSrc == -1)
{
return;
}
auto csp = baselineDocument->styles.Values()[indexSrc]->styles;
MergeBaselineStyle(csp, styleName);
}
void DocumentModel::MergeBaselineStyles(Ptr<DocumentModel> baselineDocument)
{
MergeBaselineStyle(baselineDocument, DefaultStyleName);
MergeBaselineStyle(baselineDocument, SelectionStyleName);
MergeBaselineStyle(baselineDocument, ContextStyleName);
MergeBaselineStyle(baselineDocument, NormalLinkStyleName);
MergeBaselineStyle(baselineDocument, ActiveLinkStyleName);
}
void DocumentModel::MergeDefaultFont(const FontProperties& defaultFont)
{
auto style = Ptr(new DocumentStyleProperties);
style->face =defaultFont.fontFamily;
style->size =DocumentFontSize((double)defaultFont.size, false);
style->bold =defaultFont.bold;
style->italic =defaultFont.italic;
style->underline =defaultFont.underline;
style->strikeline =defaultFont.strikeline;
style->antialias =defaultFont.antialias;
style->verticalAntialias =defaultFont.verticalAntialias;
MergeBaselineStyle(style, DefaultStyleName);
}
DocumentModel::ResolvedStyle DocumentModel::GetStyle(Ptr<DocumentStyleProperties> sp, const ResolvedStyle& context)
{
FontProperties font;
font.fontFamily =sp->face ?sp->face.Value() :context.style.fontFamily;
font.bold =sp->bold ?sp->bold.Value() :context.style.bold;
font.italic =sp->italic ?sp->italic.Value() :context.style.italic;
font.underline =sp->underline ?sp->underline.Value() :context.style.underline;
font.strikeline =sp->strikeline ?sp->strikeline.Value() :context.style.strikeline;
font.antialias =sp->antialias ?sp->antialias.Value() :context.style.antialias;
font.verticalAntialias =sp->verticalAntialias ?sp->verticalAntialias.Value() :context.style.verticalAntialias;
Color color =sp->color ?sp->color.Value() :context.color;
Color backgroundColor =sp->backgroundColor ?sp->backgroundColor.Value() :context.backgroundColor;
if (sp->size)
{
font.size = (vint)(sp->size.Value().relative ? context.style.size * sp->size.Value().size : sp->size.Value().size);
}
else
{
font.size = context.style.size;
}
return ResolvedStyle(font, color, backgroundColor);
}
DocumentModel::ResolvedStyle DocumentModel::GetStyle(const WString& styleName, const ResolvedStyle& context)
{
Ptr<DocumentStyle> selectedStyle;
{
vint index=styles.Keys().IndexOf(styleName);
if(index!=-1)
{
selectedStyle=styles.Values()[index];
}
else
{
selectedStyle=styles[L"#Default"];
}
}
if(!selectedStyle->resolvedStyles)
{
auto sp = Ptr(new DocumentStyleProperties);
selectedStyle->resolvedStyles = sp;
Ptr<DocumentStyle> currentStyle;
WString currentName = styleName;
while(true)
{
vint index = styles.Keys().IndexOf(currentName);
if (index == -1) break;
currentStyle = styles.Values().Get(index);
currentName = currentStyle->parentStyleName;
MergeStyle(sp, currentStyle->styles);
}
}
Ptr<DocumentStyleProperties> sp=selectedStyle->resolvedStyles;
return GetStyle(sp, context);
}
WString DocumentModel::GetText(bool skipNonTextContent)
{
return GenerateToStream([&](StreamWriter& writer)
{
GetText(writer, skipNonTextContent);
});
}
void DocumentModel::GetText(stream::TextWriter& writer, bool skipNonTextContent)
{
// TODO: (enumerable) Linq:Aggregate
for(vint i=0;i<paragraphs.Count();i++)
{
Ptr<DocumentParagraphRun> paragraph=paragraphs[i];
paragraph->GetText(writer, skipNonTextContent);
if(i<paragraphs.Count()-1)
{
writer.WriteString(L"\r\n\r\n");
}
}
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENTCLIPBOARD_DOCUMENT.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace glr::xml;
using namespace stream;
namespace document_clipboard_visitors
{
class TraverseDocumentVisitor : public Object, public DocumentRun::IVisitor
{
public:
TraverseDocumentVisitor()
{
}
virtual void VisitContainer(DocumentContainerRun* run)
{
for (auto childRun : run->runs)
{
childRun->Accept(this);
}
}
void Visit(DocumentTextRun* run)override
{
}
void Visit(DocumentStylePropertiesRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentStyleApplicationRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentHyperlinkRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentImageRun* run)override
{
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
class ModifyDocumentForClipboardVisitor : public TraverseDocumentVisitor
{
public:
ModifyDocumentForClipboardVisitor()
{
}
void VisitContainer(DocumentContainerRun* run)override
{
// TODO: (enumerable) foreach:indexed(alterable(reversed))
for (vint i = run->runs.Count() - 1; i >= 0; i--)
{
auto childRun = run->runs[i];
if (childRun.Cast<DocumentEmbeddedObjectRun>())
{
run->runs.RemoveAt(i);
}
}
TraverseDocumentVisitor::VisitContainer(run);
}
};
class CollectImageRunsVisitor : public TraverseDocumentVisitor
{
public:
List<Ptr<DocumentImageRun>> imageRuns;
CollectImageRunsVisitor()
{
}
void Visit(DocumentImageRun* run)override
{
run->source = L"res://Image_" + itow(imageRuns.Count());
imageRuns.Add(Ptr(run));
}
};
}
using namespace document_clipboard_visitors;
void ModifyDocumentForClipboard(Ptr<DocumentModel> model)
{
ModifyDocumentForClipboardVisitor visitor;
for (auto paragraph : model->paragraphs)
{
paragraph->Accept(&visitor);
}
}
Ptr<DocumentModel> LoadDocumentFromClipboardStream(stream::IStream& clipboardStream)
{
auto tempResource = Ptr(new GuiResource);
auto tempResourceItem = Ptr(new GuiResourceItem);
tempResource->AddItem(L"Document", tempResourceItem);
auto tempResolver = Ptr(new GuiResourcePathResolver(tempResource, L""));
internal::ContextFreeReader reader(clipboardStream);
{
WString title;
vint32_t version = 0;
reader << title << version;
if (title != L"WCF_Document" || version < 1)
{
return nullptr;
}
}
WString xmlText;
reader << xmlText;
List<GuiResourceError> errors;
auto parser = GetParserManager()->GetParser<XmlDocument>(L"XML");
auto xml = parser->Parse({}, xmlText, errors);
if (errors.Count() > 0) return nullptr;
{
vint32_t count = 0;
reader << count;
for (vint i = 0; i < count; i++)
{
MemoryStream memoryStream;
reader << (IStream&)memoryStream;
if (auto image = GetCurrentController()->ImageService()->CreateImageFromStream(memoryStream))
{
auto imageItem = Ptr(new GuiResourceItem);
imageItem->SetContent(L"Image", Ptr(new GuiImageData(image, 0)));
tempResource->AddItem(L"Image_" + itow(i), imageItem);
}
}
}
auto document = DocumentModel::LoadFromXml(tempResourceItem, xml, tempResolver, errors);
return document;
}
void SaveDocumentToClipboardStream(Ptr<DocumentModel> model, stream::IStream& clipboardStream)
{
CollectImageRunsVisitor visitor;
for (auto paragraph : model->paragraphs)
{
paragraph->Accept(&visitor);
}
internal::ContextFreeWriter writer(clipboardStream);
{
WString title = L"WCF_Document";
vint32_t version = 1;
writer << title << version;
}
{
auto xmlText = GenerateToStream([&](StreamWriter& streamWriter)
{
auto xml = model->SaveToXml();
XmlPrint(xml, streamWriter);
});
writer << xmlText;
}
{
vint32_t count = (vint32_t)visitor.imageRuns.Count();
writer << count;
for (auto imageRun : visitor.imageRuns)
{
MemoryStream memoryStream;
if (imageRun->image)
{
auto format = imageRun->image->GetFormat();
if (format == INativeImage::Gif)
{
format = INativeImage::Png;
}
imageRun->image->SaveToStream(memoryStream, format);
}
writer << (stream::IStream&)memoryStream;
}
}
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENTCLIPBOARD_HTMLFORMAT.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace stream;
namespace document_clipboard_visitors
{
class GenerateHtmlVisitor : public Object, public DocumentRun::IVisitor
{
typedef DocumentModel::ResolvedStyle ResolvedStyle;
public:
List<ResolvedStyle> styles;
DocumentModel* model;
StreamWriter& writer;
GenerateHtmlVisitor(DocumentModel* _model, StreamWriter& _writer)
:model(_model)
, writer(_writer)
{
ResolvedStyle style;
style.color = Color(0, 0, 0, 0);
style.backgroundColor = Color(0, 0, 0, 0);
style = model->GetStyle(DocumentModel::DefaultStyleName, style);
styles.Add(style);
}
void VisitContainer(DocumentContainerRun* run)
{
for (auto subRun : run->runs)
{
subRun->Accept(this);
}
}
WString ColorToString(Color c)
{
auto result = c.ToString();
if (result.Length() == 9) result = result.Left(7);
return result;
}
void Visit(DocumentTextRun* run)override
{
WString text = run->GetRepresentationText();
if (text.Length() > 0)
{
ResolvedStyle style = styles[styles.Count() - 1];
writer.WriteString(L"<span style=\"");
if (style.style.bold) writer.WriteString(L"font-weight:bold; ");
if (style.style.italic) writer.WriteString(L"font-style:italic; ");
if (style.style.underline && style.style.strikeline) writer.WriteString(L"text-decoration:underline line-through; ");
else if (style.style.underline) writer.WriteString(L"text-decoration:underline; ");
else if (style.style.strikeline) writer.WriteString(L"text-decoration:line-through; ");
if (style.style.fontFamily != L"") writer.WriteString(L"font-family:" + style.style.fontFamily + L"; ");
if (style.style.size != 0) writer.WriteString(L"font-size:" + itow(style.style.size) + L"px; ");
if (style.color.a != 0) writer.WriteString(L"color:" + ColorToString(style.color) + L"; ");
if (style.backgroundColor.a != 0)writer.WriteString(L"background-color:" + ColorToString(style.backgroundColor) + L"; ");
writer.WriteString(L"\">");
for (vint i = 0; i < text.Length(); i++)
{
switch (wchar_t c = text[i])
{
case L'&': writer.WriteString(L"&amp;"); break;
case L'<': writer.WriteString(L"&lt;"); break;
case L'>': writer.WriteString(L"&gt;"); break;
case L'\r': break;
case L'\n': writer.WriteString(L"<br>"); break;
case L' ': writer.WriteString(L"&nbsp;"); break;
case L'\t': writer.WriteString(L"<pre>\t</pre>"); break;
default: writer.WriteChar(c); break;
}
}
writer.WriteString(L"</span>");
}
}
void Visit(DocumentStylePropertiesRun* run)override
{
ResolvedStyle style = styles[styles.Count() - 1];
style = model->GetStyle(run->style, style);
styles.Add(style);
VisitContainer(run);
styles.RemoveAt(styles.Count() - 1);
}
void Visit(DocumentStyleApplicationRun* run)override
{
ResolvedStyle style = styles[styles.Count() - 1];
style = model->GetStyle(run->styleName, style);
styles.Add(style);
VisitContainer(run);
styles.RemoveAt(styles.Count() - 1);
}
void Visit(DocumentHyperlinkRun* run)override
{
writer.WriteString(L"<a href=\"");
for (vint i = 0; i < run->reference.Length(); i++)
{
switch (wchar_t c = run->reference[i])
{
case L'&': writer.WriteString(L"&amp;"); break;
case L'<': writer.WriteString(L"&lt;"); break;
case L'>': writer.WriteString(L"&gt;"); break;
case L'"': writer.WriteString(L"&quot;"); break;
case L'\'': writer.WriteString(L"&#39;"); break;
default: writer.WriteChar(c); break;
}
}
writer.WriteString(L"\">");
ResolvedStyle style = styles[styles.Count() - 1];
style = model->GetStyle((run->normalStyleName == L"" ? DocumentModel::NormalLinkStyleName : run->normalStyleName), style);
styles.Add(style);
VisitContainer(run);
styles.RemoveAt(styles.Count() - 1);
writer.WriteString(L"</a>");
}
void Visit(DocumentImageRun* run)override
{
if (run->image)
{
writer.WriteString(L"<img width=\"" + itow(run->size.x) + L"\" height=\"" + itow(run->size.y) + L"\" src=\"data:image/");
auto format = run->image->GetFormat();
if (format == INativeImage::Gif)
{
format = INativeImage::Png;
}
switch (format)
{
case INativeImage::Bmp: writer.WriteString(L"bmp;base64,"); break;
case INativeImage::Gif: writer.WriteString(L"gif;base64,"); break;
case INativeImage::Icon: writer.WriteString(L"icon;base64,"); break;
case INativeImage::Jpeg: writer.WriteString(L"jpeg;base64,"); break;
case INativeImage::Png: writer.WriteString(L"png;base64,"); break;
case INativeImage::Tiff: writer.WriteString(L"tiff;base64,"); break;
case INativeImage::Wmp: writer.WriteString(L"wmp;base64,"); break;
default: writer.WriteString(L"unsupported;base64,\"/>"); return;
}
MemoryStream memoryStream;
run->image->SaveToStream(memoryStream, format);
memoryStream.SeekFromBegin(0);
while (true)
{
vuint8_t bytes[3] = { 0,0,0 };
vint read = memoryStream.Read(&bytes, sizeof(bytes));
if (read == 0) break;
vuint8_t b1 = bytes[0] / (1 << 2);
vuint8_t b2 = ((bytes[0] % (1 << 2)) << 4) + bytes[1] / (1 << 4);
vuint8_t b3 = ((bytes[1] % (1 << 4)) << 2) + bytes[2] / (1 << 6);
vuint8_t b4 = bytes[2] % (1 << 6);
const wchar_t* BASE64 =
L"ABCDEFG"
L"HIJKLMN"
L"OPQRST"
L"UVWXYZ"
L"abcdefg"
L"hijklmn"
L"opqrst"
L"uvwxyz"
L"0123456789"
L"+/";
#define BASE64_CHAR(b) BASE64[b]
switch (read)
{
case 1:
writer.WriteChar(BASE64_CHAR(b1));
writer.WriteChar(BASE64_CHAR(b2));
writer.WriteChar(L'=');
writer.WriteChar(L'=');
break;
case 2:
writer.WriteChar(BASE64_CHAR(b1));
writer.WriteChar(BASE64_CHAR(b2));
writer.WriteChar(BASE64_CHAR(b3));
writer.WriteChar(L'=');
break;
case 3:
writer.WriteChar(BASE64_CHAR(b1));
writer.WriteChar(BASE64_CHAR(b2));
writer.WriteChar(BASE64_CHAR(b3));
writer.WriteChar(BASE64_CHAR(b4));
break;
}
#undef BASE64_CHAR
}
writer.WriteString(L"\"/>");
}
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
}
using namespace document_clipboard_visitors;
#define HTML_LINE(LINE) LINE "\r\n"
void SaveDocumentToHtmlUtf8(Ptr<DocumentModel> model, AString& header, AString& content, AString& footer)
{
header =
HTML_LINE("<!DOCTYPE html>")
HTML_LINE("<html>")
HTML_LINE("<header>")
HTML_LINE("<title>GacUI Document 1.0</title>")
HTML_LINE("<meta charset=\"utf-8\"/>")
HTML_LINE("</header>")
HTML_LINE("<body>")
;
MemoryStream memoryStream;
{
Utf8Encoder encoder;
EncoderStream encoderStream(memoryStream, encoder);
StreamWriter writer(encoderStream);
GenerateHtmlVisitor visitor(model.Obj(), writer);
// TODO: (enumerable) foreach
for (auto paragraph : model->paragraphs)
{
writer.WriteString(L"<p style=\"text-align:");
if (paragraph->alignment)
{
switch (paragraph->alignment.Value())
{
case Alignment::Left: writer.WriteString(L"left;"); break;
case Alignment::Center: writer.WriteString(L"center;"); break;
case Alignment::Right: writer.WriteString(L"right;"); break;
}
}
else
{
writer.WriteString(L"left;");
}
writer.WriteString(L"\">");
paragraph->Accept(&visitor);
writer.WriteString(L"</p>\r\n");
}
}
char zero = 0;
memoryStream.Write(&zero, sizeof(zero));
content = (const char*)memoryStream.GetInternalBuffer();
footer =
HTML_LINE("</body>")
HTML_LINE("</html>")
;
}
void SaveDocumentToHtmlClipboardStream(Ptr<DocumentModel> model, stream::IStream& clipboardStream)
{
AString header, content, footer;
SaveDocumentToHtmlUtf8(model, header, content, footer);
char clipboardHeader[] =
HTML_LINE("StartHTML:-1")
HTML_LINE("EndHTML:-1")
HTML_LINE("StartFragment:0000000000")
HTML_LINE("EndFragment:0000000000")
;
char commentStart[] = "<!--StartFragment-->";
char commentEnd[] = "<!--EndFragment-->";
vint offsetStart = sizeof(clipboardHeader) - 1 + header.Length() + sizeof(commentStart) - 1;
vint offsetEnd = offsetStart + content.Length();
AString offsetStartString = itoa(offsetStart);
AString offsetEndString = itoa(offsetEnd);
memcpy(strstr(clipboardHeader, "EndFragment:") - offsetStartString.Length() - 2, offsetStartString.Buffer(), offsetStartString.Length());
memcpy(clipboardHeader + sizeof(clipboardHeader) - 1 - offsetEndString.Length() - 2, offsetEndString.Buffer(), offsetEndString.Length());
clipboardStream.Write(clipboardHeader, sizeof(clipboardHeader) - 1);
if (header.Length() > 0) clipboardStream.Write((void*)header.Buffer(), header.Length());
clipboardStream.Write(commentStart, sizeof(commentStart) - 1);
if (content.Length() > 0) clipboardStream.Write((void*)content.Buffer(), content.Length());
clipboardStream.Write(commentEnd, sizeof(commentEnd) - 1);
if (footer.Length() > 0) clipboardStream.Write((void*)footer.Buffer(), footer.Length());
}
#undef HTML_LINE
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENTCLIPBOARD_RICHTEXTFORMAT.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace stream;
namespace document_clipboard_visitors
{
class GenerateRtfVisitor : public Object, public DocumentRun::IVisitor
{
typedef DocumentModel::ResolvedStyle ResolvedStyle;
public:
List<ResolvedStyle> styles;
DocumentModel* model;
StreamWriter& writer;
List<WString>& fontTable;
List<Color>& colorTable;
Dictionary<WString, vint> fontIndex;
Dictionary<Color, vint> colorIndex;
vint GetFont(const WString& fontName)
{
vint index = fontIndex.Keys().IndexOf(fontName);
if (index == -1)
{
index = fontTable.Add(fontName);
fontIndex.Add(fontName, index);
return index;
}
return fontIndex.Values()[index];
}
vint GetColor(Color color)
{
if (color.a == 0) return 0;
vint index = colorIndex.Keys().IndexOf(color);
if (index == -1)
{
index = colorTable.Add(color) + 1;
colorIndex.Add(color, index);
return index;
}
return colorIndex.Values()[index];
}
GenerateRtfVisitor(DocumentModel* _model, List<WString>& _fontTable, List<Color>& _colorTable, StreamWriter& _writer)
:model(_model)
, writer(_writer)
, fontTable(_fontTable)
, colorTable(_colorTable)
{
ResolvedStyle style;
style.color = Color(0, 0, 0, 0);
style.backgroundColor = Color(0, 0, 0, 0);
style = model->GetStyle(DocumentModel::DefaultStyleName, style);
styles.Add(style);
}
void VisitContainer(DocumentContainerRun* run)
{
for (auto subRun : run->runs)
{
subRun->Accept(this);
}
}
void Visit(DocumentTextRun* run)override
{
WString text = run->GetRepresentationText();
if (text.Length() > 0)
{
ResolvedStyle style = styles[styles.Count() - 1];
writer.WriteString(L"{\\f" + itow(GetFont(style.style.fontFamily)));
writer.WriteString(L"\\fs" + itow((vint)(style.style.size * 1.5)));
writer.WriteString(L"\\cf" + itow(GetColor(style.color)));
writer.WriteString(L"\\cb" + itow(GetColor(style.backgroundColor)));
writer.WriteString(L"\\chshdng" + itow(GetColor(style.backgroundColor)));
writer.WriteString(L"\\chcbpat" + itow(GetColor(style.backgroundColor)));
if (style.style.bold) writer.WriteString(L"\\b");
if (style.style.italic) writer.WriteString(L"\\i");
if (style.style.underline) writer.WriteString(L"\\ul");
if (style.style.strikeline) writer.WriteString(L"\\strike");
for (vint i = 0; i < text.Length(); i++)
{
writer.WriteString(L"\\u" + itow(text[i]));
}
writer.WriteString(L"}");
}
}
void Visit(DocumentStylePropertiesRun* run)override
{
ResolvedStyle style = styles[styles.Count() - 1];
style = model->GetStyle(run->style, style);
styles.Add(style);
VisitContainer(run);
styles.RemoveAt(styles.Count() - 1);
}
void Visit(DocumentStyleApplicationRun* run)override
{
ResolvedStyle style = styles[styles.Count() - 1];
style = model->GetStyle(run->styleName, style);
styles.Add(style);
VisitContainer(run);
styles.RemoveAt(styles.Count() - 1);
}
void Visit(DocumentHyperlinkRun* run)override
{
ResolvedStyle style = styles[styles.Count() - 1];
style = model->GetStyle((run->normalStyleName == L"" ? DocumentModel::NormalLinkStyleName : run->normalStyleName), style);
styles.Add(style);
VisitContainer(run);
styles.RemoveAt(styles.Count() - 1);
}
void Visit(DocumentImageRun* run)override
{
if (run->image)
{
writer.WriteString(L"{\\pict\\pngblip");
writer.WriteString(L"\\picw" + itow(run->size.x) + L"\\pich" + itow(run->size.y));
writer.WriteString(L"\\picwgoal" + itow(run->size.x * 15) + L"\\pichgoal" + itow(run->size.y * 15) + L" ");
MemoryStream memoryStream;
run->image->SaveToStream(memoryStream, INativeImage::Png);
vint count = (vint)memoryStream.Size();
vuint8_t* buffer = (vuint8_t*)memoryStream.GetInternalBuffer();
for (vint i = 0; i < count; i++)
{
writer.WriteChar(L"0123456789abcdef"[buffer[i] / 16]);
writer.WriteChar(L"0123456789abcdef"[buffer[i] % 16]);
}
writer.WriteString(L"}");
}
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
}
using namespace document_clipboard_visitors;
void SaveDocumentToRtf(Ptr<DocumentModel> model, AString& rtf)
{
List<WString> fontTable;
List<Color> colorTable;
MemoryStream bodyStream;
{
StreamWriter writer(bodyStream);
GenerateRtfVisitor visitor(model.Obj(), fontTable, colorTable, writer);
for (auto paragraph : model->paragraphs)
{
if (paragraph->alignment)
{
switch (paragraph->alignment.Value())
{
case Alignment::Left: writer.WriteString(L"\\ql{"); break;
case Alignment::Center: writer.WriteString(L"\\qc{"); break;
case Alignment::Right: writer.WriteString(L"\\qr{"); break;
}
}
else
{
writer.WriteString(L"\\ql{");
}
paragraph->Accept(&visitor);
writer.WriteString(L"}\\par");
}
}
MemoryStream rtfStream;
{
Utf8Encoder encoder;
EncoderStream encoderStream(rtfStream, encoder);
StreamWriter writer(encoderStream);
writer.WriteString(L"{\\rtf1\\ansi\\deff0{\\fonttbl");
for (auto [fontName, index] : indexed(fontTable))
{
writer.WriteString(L"{\\f");
writer.WriteString(itow(index));
writer.WriteString(L" ");
writer.WriteString(fontName);
writer.WriteString(L";}");
}
writer.WriteString(L"}{\\colortbl");
for (auto [color, index] : indexed(colorTable))
{
writer.WriteString(L";\\red");
writer.WriteString(itow(color.r));
writer.WriteString(L"\\green");
writer.WriteString(itow(color.g));
writer.WriteString(L"\\blue");
writer.WriteString(itow(color.b));
}
writer.WriteString(L";}{\\*\\generator GacUI Document 1.0}\\uc0");
{
bodyStream.SeekFromBegin(0);
StreamReader reader(bodyStream);
writer.WriteString(reader.ReadToEnd());
}
writer.WriteString(L"}");
}
char zero = 0;
rtfStream.Write(&zero, sizeof(zero));
rtf = (const char*)rtfStream.GetInternalBuffer();
}
void SaveDocumentToRtfStream(Ptr<DocumentModel> model, stream::IStream& rtfStream)
{
AString rtf;
SaveDocumentToRtf(model, rtf);
rtfStream.Write((void*)rtf.Buffer(), rtf.Length());
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENTEDITOR_ADDCONTAINER.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace document_editor;
/***********************************************************************
Insert container runs on top of all text ranges that intersect with the specified range
AddStyleVisitor : Apply a style on the specified range
AddHyperlinkVisitor : Apply a hyperlink on the specified range
AddStyleNameVisitor : Apply a style name on the specified range
***********************************************************************/
namespace document_operation_visitors
{
class AddContainerVisitor : public Object, public DocumentRun::IVisitor
{
public:
RunRangeMap& runRanges;
vint start;
vint end;
bool insertStyle;
virtual Ptr<DocumentContainerRun> CreateContainer() = 0;
AddContainerVisitor(RunRangeMap& _runRanges, vint _start, vint _end)
:runRanges(_runRanges)
, start(_start)
, end(_end)
, insertStyle(false)
{
}
void VisitContainer(DocumentContainerRun* run)
{
// TODO: (enumerable) foreach:indexed(alterable(reversed))
for (vint i = run->runs.Count() - 1; i >= 0; i--)
{
Ptr<DocumentRun> subRun = run->runs[i];
RunRange range = runRanges[subRun.Obj()];
if (range.start<end && start<range.end)
{
insertStyle = false;
subRun->Accept(this);
if (insertStyle)
{
Ptr<DocumentContainerRun> containerRun = CreateContainer();
run->runs.RemoveAt(i);
containerRun->runs.Add(subRun);
run->runs.Insert(i, containerRun);
}
}
}
insertStyle = false;
}
void Visit(DocumentTextRun* run)override
{
insertStyle = true;
}
void Visit(DocumentStylePropertiesRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentStyleApplicationRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentHyperlinkRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentImageRun* run)override
{
insertStyle = false;
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
insertStyle = false;
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
class AddStyleVisitor : public AddContainerVisitor
{
public:
Ptr<DocumentStyleProperties> style;
Ptr<DocumentContainerRun> CreateContainer()override
{
auto containerRun = Ptr(new DocumentStylePropertiesRun);
containerRun->style = CopyStyle(style);
return containerRun;
}
AddStyleVisitor(RunRangeMap& _runRanges, vint _start, vint _end, Ptr<DocumentStyleProperties> _style)
:AddContainerVisitor(_runRanges, _start, _end)
, style(_style)
{
}
};
class AddHyperlinkVisitor : public AddContainerVisitor
{
public:
WString reference;
WString normalStyleName;
WString activeStyleName;
Ptr<DocumentContainerRun> CreateContainer()override
{
auto containerRun = Ptr(new DocumentHyperlinkRun);
containerRun->reference = reference;
containerRun->normalStyleName = normalStyleName;
containerRun->activeStyleName = activeStyleName;
containerRun->styleName = normalStyleName;
return containerRun;
}
AddHyperlinkVisitor(RunRangeMap& _runRanges, vint _start, vint _end, const WString& _reference, const WString& _normalStyleName, const WString& _activeStyleName)
:AddContainerVisitor(_runRanges, _start, _end)
, reference(_reference)
, normalStyleName(_normalStyleName)
, activeStyleName(_activeStyleName)
{
}
};
class AddStyleNameVisitor : public AddContainerVisitor
{
public:
WString styleName;
Ptr<DocumentContainerRun> CreateContainer()override
{
auto containerRun = Ptr(new DocumentStyleApplicationRun);
containerRun->styleName = styleName;
return containerRun;
}
AddStyleNameVisitor(RunRangeMap& _runRanges, vint _start, vint _end, const WString& _styleName)
:AddContainerVisitor(_runRanges, _start, _end)
, styleName(_styleName)
{
}
};
}
using namespace document_operation_visitors;
namespace document_editor
{
void AddStyle(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end, Ptr<DocumentStyleProperties> style)
{
AddStyleVisitor visitor(runRanges, start, end, style);
run->Accept(&visitor);
}
void AddHyperlink(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end, const WString& reference, const WString& normalStyleName, const WString& activeStyleName)
{
AddHyperlinkVisitor visitor(runRanges, start, end, reference, normalStyleName, activeStyleName);
run->Accept(&visitor);
}
void AddStyleName(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end, const WString& styleName)
{
AddStyleNameVisitor visitor(runRanges, start, end, styleName);
run->Accept(&visitor);
}
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENTEDITOR_CLEARUNNECESSARYRUN.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace document_editor;
/***********************************************************************
Clear all runs that have an empty length
***********************************************************************/
namespace document_operation_visitors
{
class ClearRunVisitor : public Object, public DocumentRun::IVisitor
{
public:
vint start;
ClearRunVisitor()
:start(0)
{
}
void VisitContainer(DocumentContainerRun* run)
{
// TODO: (enumerable) foreach:indexed(alterable(reversed))
for (vint i = run->runs.Count() - 1; i >= 0; i--)
{
vint oldStart = start;
run->runs[i]->Accept(this);
if (oldStart == start)
{
run->runs.RemoveAt(i);
}
}
}
void VisitContent(DocumentContentRun* run)
{
start += run->GetRepresentationText().Length();
}
void Visit(DocumentTextRun* run)override
{
VisitContent(run);
}
void Visit(DocumentStylePropertiesRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentStyleApplicationRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentHyperlinkRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentImageRun* run)override
{
VisitContent(run);
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
VisitContent(run);
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
}
using namespace document_operation_visitors;
/***********************************************************************
Ensure DocumentStylePropertiesRun doesn't have a child which is another DocumentStylePropertiesRun
Remove DocumentStylePropertiesRun's property if it set a value but doesn't change the output
Remove DocumentStylePropertiesRun if it is empty or contains no text run
***********************************************************************/
namespace document_operation_visitors
{
class CompressStyleRunVisitor : public Object, public DocumentRun::IVisitor
{
public:
DocumentModel* model;
List<DocumentModel::ResolvedStyle> resolvedStyles;
List<Ptr<DocumentRun>> replacedRuns;
CompressStyleRunVisitor(DocumentModel* _model)
:model(_model)
{
DocumentModel::ResolvedStyle resolvedStyle;
resolvedStyle = model->GetStyle(DocumentModel::DefaultStyleName, resolvedStyle);
resolvedStyles.Add(resolvedStyle);
}
const DocumentModel::ResolvedStyle& GetCurrentResolvedStyle()
{
return resolvedStyles[resolvedStyles.Count() - 1];
}
void VisitContainer(DocumentContainerRun* run)
{
// TODO: (enumerable) foreach:indexed(alterable)
for (vint i = 0; i < run->runs.Count(); i++)
{
Ptr<DocumentRun> subRun = run->runs[i];
replacedRuns.Clear();
subRun->Accept(this);
if (replacedRuns.Count() > 0)
{
run->runs.RemoveAt(i);
// TODO: (enumerable) foreach
for (vint j = 0; j < replacedRuns.Count(); j++)
{
run->runs.Insert(i + j, replacedRuns[j]);
}
i--;
}
}
}
void Visit(DocumentTextRun* run)override
{
}
bool OnlyImageOrObject(DocumentContainerRun* run)
{
bool onlyImageOrObject = true;
for (auto subRun : run->runs)
{
if (!subRun.Cast<DocumentImageRun>() && !subRun.Cast<DocumentEmbeddedObjectRun>())
{
onlyImageOrObject = false;
break;
}
}
return onlyImageOrObject;
}
void Visit(DocumentStylePropertiesRun* run)override
{
if (OnlyImageOrObject(run))
{
CopyFrom(replacedRuns, run->runs);
return;
}
const DocumentModel::ResolvedStyle& currentResolvedStyle = GetCurrentResolvedStyle();
DocumentModel::ResolvedStyle resolvedStyle = model->GetStyle(run->style, currentResolvedStyle);
if (currentResolvedStyle.style.fontFamily == resolvedStyle.style.fontFamily) run->style->face = Nullable<WString>();
if (currentResolvedStyle.style.size == resolvedStyle.style.size) run->style->size = Nullable<DocumentFontSize>();
if (currentResolvedStyle.color == resolvedStyle.color) run->style->color = Nullable<Color>();
if (currentResolvedStyle.backgroundColor == resolvedStyle.backgroundColor) run->style->backgroundColor = Nullable<Color>();
if (currentResolvedStyle.style.bold == resolvedStyle.style.bold) run->style->bold = Nullable<bool>();
if (currentResolvedStyle.style.italic == resolvedStyle.style.italic) run->style->italic = Nullable<bool>();
if (currentResolvedStyle.style.underline == resolvedStyle.style.underline) run->style->underline = Nullable<bool>();
if (currentResolvedStyle.style.strikeline == resolvedStyle.style.strikeline) run->style->strikeline = Nullable<bool>();
if (currentResolvedStyle.style.antialias == resolvedStyle.style.antialias) run->style->antialias = Nullable<bool>();
if (currentResolvedStyle.style.verticalAntialias == resolvedStyle.style.verticalAntialias) run->style->verticalAntialias = Nullable<bool>();
if (run->style->face) goto CONTINUE_PROCESSING;
if (run->style->size) goto CONTINUE_PROCESSING;
if (run->style->color) goto CONTINUE_PROCESSING;
if (run->style->backgroundColor) goto CONTINUE_PROCESSING;
if (run->style->bold) goto CONTINUE_PROCESSING;
if (run->style->italic) goto CONTINUE_PROCESSING;
if (run->style->underline) goto CONTINUE_PROCESSING;
if (run->style->strikeline) goto CONTINUE_PROCESSING;
if (run->style->antialias) goto CONTINUE_PROCESSING;
if (run->style->verticalAntialias) goto CONTINUE_PROCESSING;
CopyFrom(replacedRuns, run->runs);
return;
CONTINUE_PROCESSING:
if (From(run->runs).Cast<DocumentStylePropertiesRun>().First(nullptr) != nullptr)
{
for (auto subRun : run->runs)
{
if (auto styleRun = subRun.Cast<DocumentStylePropertiesRun>())
{
DocumentModel::MergeStyle(styleRun->style, run->style);
replacedRuns.Add(styleRun);
}
else
{
auto parentRun = CopyRun(run).Cast<DocumentStylePropertiesRun>();
parentRun->runs.Add(subRun);
replacedRuns.Add(parentRun);
}
}
return;
}
resolvedStyles.Add(resolvedStyle);
VisitContainer(run);
resolvedStyles.RemoveAt(resolvedStyles.Count() - 1);
}
void Visit(DocumentStyleApplicationRun* run)override
{
if (OnlyImageOrObject(run))
{
CopyFrom(replacedRuns, run->runs);
return;
}
const DocumentModel::ResolvedStyle& currentResolvedStyle = GetCurrentResolvedStyle();
DocumentModel::ResolvedStyle resolvedStyle = model->GetStyle(run->styleName, currentResolvedStyle);
resolvedStyles.Add(resolvedStyle);
VisitContainer(run);
resolvedStyles.RemoveAt(resolvedStyles.Count() - 1);
}
void Visit(DocumentHyperlinkRun* run)override
{
const DocumentModel::ResolvedStyle& currentResolvedStyle = GetCurrentResolvedStyle();
DocumentModel::ResolvedStyle resolvedStyle = model->GetStyle(run->styleName, currentResolvedStyle);
resolvedStyles.Add(resolvedStyle);
VisitContainer(run);
resolvedStyles.RemoveAt(resolvedStyles.Count() - 1);
}
void Visit(DocumentImageRun* run)override
{
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
}
using namespace document_operation_visitors;
/***********************************************************************
Merge sibling runs if they are exactly the same
***********************************************************************/
namespace document_operation_visitors
{
class MergeSiblingRunVisitor : public Object, public DocumentRun::IVisitor
{
public:
Ptr<DocumentRun> nextRun;
Ptr<DocumentRun> replacedRun;
void Visit(DocumentTextRun* run)override
{
if (auto sibilingRun = nextRun.Cast<DocumentTextRun>())
{
run->text += sibilingRun->text;
replacedRun = Ptr(run);
}
}
void Visit(DocumentStylePropertiesRun* run)override
{
if (auto sibilingRun = nextRun.Cast<DocumentStylePropertiesRun>())
{
if (run->style->face != sibilingRun->style->face) return;
if (run->style->size != sibilingRun->style->size) return;
if (run->style->color != sibilingRun->style->color) return;
if (run->style->backgroundColor != sibilingRun->style->backgroundColor) return;
if (run->style->bold != sibilingRun->style->bold) return;
if (run->style->italic != sibilingRun->style->italic) return;
if (run->style->underline != sibilingRun->style->underline) return;
if (run->style->strikeline != sibilingRun->style->strikeline) return;
if (run->style->antialias != sibilingRun->style->antialias) return;
if (run->style->verticalAntialias != sibilingRun->style->verticalAntialias) return;
CopyFrom(run->runs, sibilingRun->runs, true);
replacedRun = Ptr(run);
}
}
void Visit(DocumentStyleApplicationRun* run)override
{
if (auto sibilingRun = nextRun.Cast<DocumentStyleApplicationRun>())
{
if (run->styleName == sibilingRun->styleName)
{
CopyFrom(run->runs, sibilingRun->runs, true);
replacedRun = Ptr(run);
}
}
}
void Visit(DocumentHyperlinkRun* run)override
{
if (auto sibilingRun = nextRun.Cast<DocumentHyperlinkRun>())
{
if (run->styleName == sibilingRun->styleName &&
run->normalStyleName == sibilingRun->normalStyleName &&
run->activeStyleName == sibilingRun->activeStyleName &&
run->reference == sibilingRun->reference)
{
CopyFrom(run->runs, sibilingRun->runs, true);
replacedRun = Ptr(run);
}
}
}
void Visit(DocumentImageRun* run)override
{
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
}
void Visit(DocumentParagraphRun* run)override
{
}
};
class MergeSiblingRunRecursivelyVisitor : public Object, public DocumentRun::IVisitor
{
public:
Ptr<DocumentRun> replacedRun;
Ptr<DocumentRun> nextRun;
void VisitContainer(DocumentContainerRun* run)
{
// TODO: (enumerable) foreach:indexed(alterable(reversed))
for (vint i = 0; i < run->runs.Count() - 1; i++)
{
auto currentRun = run->runs[i];
auto nextRun = run->runs[i + 1];
MergeSiblingRunVisitor visitor;
visitor.nextRun = nextRun;
currentRun->Accept(&visitor);
if (visitor.replacedRun)
{
run->runs.RemoveAt(i + 1);
run->runs[i] = visitor.replacedRun;
i--;
}
}
// TODO: (enumerable) foreach
for (vint i = 0; i < run->runs.Count() - 1; i++)
{
run->runs[i]->Accept(this);
}
}
void Visit(DocumentTextRun* run)override
{
}
void Visit(DocumentStylePropertiesRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentStyleApplicationRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentHyperlinkRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentImageRun* run)override
{
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
}
using namespace document_operation_visitors;
namespace document_editor
{
void ClearUnnecessaryRun(DocumentParagraphRun* run, DocumentModel* model)
{
{
ClearRunVisitor visitor;
run->Accept(&visitor);
}
{
CompressStyleRunVisitor visitor(model);
run->Accept(&visitor);
}
{
MergeSiblingRunRecursivelyVisitor visitor;
run->Accept(&visitor);
}
}
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENTEDITOR_CLONERUN.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace document_editor;
/***********************************************************************
Clone the current run without its children
If clonedRun field is assigned then it will be added to the cloned container run
***********************************************************************/
namespace document_operation_visitors
{
class CloneRunVisitor : public Object, public DocumentRun::IVisitor
{
public:
Ptr<DocumentRun> clonedRun;
CloneRunVisitor(Ptr<DocumentRun> subRun)
:clonedRun(subRun)
{
}
void VisitContainer(Ptr<DocumentContainerRun> cloned)
{
if (clonedRun)
{
cloned->runs.Add(clonedRun);
}
clonedRun = cloned;
}
void Visit(DocumentTextRun* run)override
{
auto cloned = Ptr(new DocumentTextRun);
cloned->text = run->text;
clonedRun = cloned;
}
void Visit(DocumentStylePropertiesRun* run)override
{
auto cloned = Ptr(new DocumentStylePropertiesRun);
cloned->style = CopyStyle(run->style);
VisitContainer(cloned);
}
void Visit(DocumentStyleApplicationRun* run)override
{
auto cloned = Ptr(new DocumentStyleApplicationRun);
cloned->styleName = run->styleName;
VisitContainer(cloned);
}
void Visit(DocumentHyperlinkRun* run)override
{
auto cloned = Ptr(new DocumentHyperlinkRun);
cloned->styleName = run->styleName;
cloned->normalStyleName = run->normalStyleName;
cloned->activeStyleName = run->activeStyleName;
cloned->reference = run->reference;
VisitContainer(cloned);
}
void Visit(DocumentImageRun* run)override
{
auto cloned = Ptr(new DocumentImageRun);
cloned->size = run->size;
cloned->baseline = run->baseline;
cloned->image = run->image;
cloned->frameIndex = run->frameIndex;
cloned->source = run->source;
clonedRun = cloned;
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
auto cloned = Ptr(new DocumentEmbeddedObjectRun);
cloned->name = run->name;
clonedRun = cloned;
}
void Visit(DocumentParagraphRun* run)override
{
auto cloned = Ptr(new DocumentParagraphRun);
cloned->alignment = run->alignment;
VisitContainer(cloned);
}
};
}
using namespace document_operation_visitors;
/***********************************************************************
Clone the current run with its children
***********************************************************************/
namespace document_operation_visitors
{
class CloneRunRecursivelyVisitor : public Object, public DocumentRun::IVisitor
{
public:
Ptr<DocumentRun> clonedRun;
RunRangeMap& runRanges;
vint start;
vint end;
bool deepCopy;
CloneRunRecursivelyVisitor(RunRangeMap& _runRanges, vint _start, vint _end, bool _deepCopy)
:runRanges(_runRanges)
, start(_start)
, end(_end)
, deepCopy(_deepCopy)
{
}
void VisitContainer(DocumentContainerRun* run)
{
clonedRun = 0;
RunRange range = runRanges[run];
if (range.start <= end && start <= range.end)
{
if (start <= range.start && range.end <= end && !deepCopy)
{
clonedRun = Ptr(run);
}
else
{
Ptr<DocumentContainerRun> containerRun = CopyRun(run).Cast<DocumentContainerRun>();
for (auto subRun : run->runs)
{
subRun->Accept(this);
if (clonedRun)
{
containerRun->runs.Add(clonedRun);
}
}
clonedRun = containerRun;
}
}
}
void Visit(DocumentTextRun* run)override
{
clonedRun = 0;
RunRange range = runRanges[run];
if (range.start<end && start<range.end)
{
if (start <= range.start && range.end <= end)
{
if (deepCopy)
{
clonedRun = CopyRun(run);
}
else
{
clonedRun = Ptr(run);
}
}
else
{
auto textRun = Ptr(new DocumentTextRun);
vint copyStart = start>range.start ? start : range.start;
vint copyEnd = end<range.end ? end : range.end;
if (copyStart<copyEnd)
{
textRun->text = run->text.Sub(copyStart - range.start, copyEnd - copyStart);
}
clonedRun = textRun;
}
}
}
void Visit(DocumentStylePropertiesRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentStyleApplicationRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentHyperlinkRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentImageRun* run)override
{
clonedRun = 0;
RunRange range = runRanges[run];
if (range.start<end && start<range.end)
{
if (deepCopy)
{
clonedRun = CopyRun(run);
}
else
{
clonedRun = Ptr(run);
}
}
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
clonedRun = 0;
RunRange range = runRanges[run];
if (range.start<end && start<range.end)
{
if (deepCopy)
{
clonedRun = CopyRun(run);
}
else
{
clonedRun = Ptr(run);
}
}
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
}
using namespace document_operation_visitors;
namespace document_editor
{
Ptr<DocumentStyleProperties> CopyStyle(Ptr<DocumentStyleProperties> style)
{
if (!style) return nullptr;
auto newStyle = Ptr(new DocumentStyleProperties);
newStyle->face = style->face;
newStyle->size = style->size;
newStyle->color = style->color;
newStyle->backgroundColor = style->backgroundColor;
newStyle->bold = style->bold;
newStyle->italic = style->italic;
newStyle->underline = style->underline;
newStyle->strikeline = style->strikeline;
newStyle->antialias = style->antialias;
newStyle->verticalAntialias = style->verticalAntialias;
return newStyle;
}
Ptr<DocumentRun> CopyRun(DocumentRun* run)
{
CloneRunVisitor visitor(0);
run->Accept(&visitor);
return visitor.clonedRun;
}
Ptr<DocumentRun> CopyStyledText(List<DocumentContainerRun*>& styleRuns, const WString& text)
{
auto textRun = Ptr(new DocumentTextRun);
textRun->text = text;
CloneRunVisitor visitor(textRun);
// TODO: (enumerable) foreach:reversed
for (vint i = styleRuns.Count() - 1; i >= 0; i--)
{
styleRuns[i]->Accept(&visitor);
}
return visitor.clonedRun;
}
Ptr<DocumentRun> CopyRunRecursively(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end, bool deepCopy)
{
CloneRunRecursivelyVisitor visitor(runRanges, start, end, deepCopy);
run->Accept(&visitor);
return visitor.clonedRun;
}
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENTEDITOR_COLLECTSTYLE.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
/***********************************************************************
Search all used style names
***********************************************************************/
namespace document_operation_visitors
{
class CollectStyleNameVisitor : public Object, public DocumentRun::IVisitor
{
public:
List<WString>& styleNames;
CollectStyleNameVisitor(List<WString>& _styleNames)
:styleNames(_styleNames)
{
}
void VisitContainer(DocumentContainerRun* run)
{
for (auto subRun : run->runs)
{
subRun->Accept(this);
}
}
void Visit(DocumentTextRun* run)override
{
}
void Visit(DocumentStylePropertiesRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentStyleApplicationRun* run)override
{
if (!styleNames.Contains(run->styleName))
{
styleNames.Add(run->styleName);
}
VisitContainer(run);
}
void Visit(DocumentHyperlinkRun* run)override
{
if (!styleNames.Contains(run->normalStyleName))
{
styleNames.Add(run->normalStyleName);
}
if (!styleNames.Contains(run->activeStyleName))
{
styleNames.Add(run->activeStyleName);
}
VisitContainer(run);
}
void Visit(DocumentImageRun* run)override
{
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
}
using namespace document_operation_visitors;
namespace document_editor
{
void CollectStyleName(DocumentParagraphRun* run, List<WString>& styleNames)
{
CollectStyleNameVisitor visitor(styleNames);
run->Accept(&visitor);
}
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENTEDITOR_CUTRUN.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace document_editor;
/***********************************************************************
Cut all runs into pieces so that a run either completely outside or inside the specified range
If a run decides that itself should be cut, then leftRun and rightRun contains new run that will be inserted before and after it
***********************************************************************/
namespace document_operation_visitors
{
class CutRunVisitor : public Object, public DocumentRun::IVisitor
{
public:
RunRangeMap& runRanges;
vint position;
Ptr<DocumentRun> leftRun;
Ptr<DocumentRun> rightRun;
CutRunVisitor(RunRangeMap& _runRanges, vint _position)
:runRanges(_runRanges)
, position(_position)
{
}
void VisitContainer(DocumentContainerRun* run)
{
vint leftCount = 0;
Ptr<DocumentRun> selectedRun;
for (auto subRun : run->runs)
{
RunRange range = runRanges[subRun.Obj()];
if (range.start<position)
{
leftCount++;
if (position<range.end)
{
selectedRun = subRun;
}
}
else
{
break;
}
}
if (selectedRun)
{
selectedRun->Accept(this);
if (leftRun && rightRun)
{
run->runs.RemoveAt(leftCount - 1);
run->runs.Insert(leftCount - 1, leftRun);
run->runs.Insert(leftCount, rightRun);
}
}
Ptr<DocumentContainerRun> leftContainer = CopyRun(run).Cast<DocumentContainerRun>();
Ptr<DocumentContainerRun> rightContainer = CopyRun(run).Cast<DocumentContainerRun>();
// TODO: (enumerable) foreach
for (vint i = 0; i<run->runs.Count(); i++)
{
(i<leftCount ? leftContainer : rightContainer)->runs.Add(run->runs[i]);
}
leftRun = leftContainer;
rightRun = rightContainer;
}
void Visit(DocumentTextRun* run)override
{
RunRange range = runRanges[run];
auto leftText = Ptr(new DocumentTextRun);
leftText->text = run->text.Sub(0, position - range.start);
auto rightText = Ptr(new DocumentTextRun);
rightText->text = run->text.Sub(position - range.start, range.end - position);
leftRun = leftText;
rightRun = rightText;
}
void Visit(DocumentStylePropertiesRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentStyleApplicationRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentHyperlinkRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentImageRun* run)override
{
leftRun = 0;
rightRun = 0;
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
leftRun = 0;
rightRun = 0;
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
}
using namespace document_operation_visitors;
namespace document_editor
{
void CutRun(DocumentParagraphRun* run, RunRangeMap& runRanges, vint position, Ptr<DocumentRun>& leftRun, Ptr<DocumentRun>& rightRun)
{
CutRunVisitor visitor(runRanges, position);
run->Accept(&visitor);
leftRun = visitor.leftRun;
rightRun = visitor.rightRun;
}
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENTEDITOR_GETRUNRANGE.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
/***********************************************************************
Calculate range informations for each run object
***********************************************************************/
namespace document_operation_visitors
{
class GetRunRangeVisitor : public Object, public DocumentRun::IVisitor
{
public:
RunRangeMap& runRanges;
vint start;
GetRunRangeVisitor(RunRangeMap& _runRanges)
:runRanges(_runRanges)
, start(0)
{
}
void VisitContainer(DocumentContainerRun* run)
{
RunRange range;
range.start = start;
for (auto subRun : run->runs)
{
subRun->Accept(this);
}
range.end = start;
runRanges.Add(run, range);
}
void VisitContent(DocumentContentRun* run)
{
RunRange range;
range.start = start;
start += run->GetRepresentationText().Length();
range.end = start;
runRanges.Add(run, range);
}
void Visit(DocumentTextRun* run)override
{
VisitContent(run);
}
void Visit(DocumentStylePropertiesRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentStyleApplicationRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentHyperlinkRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentImageRun* run)override
{
VisitContent(run);
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
VisitContent(run);
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
}
using namespace document_operation_visitors;
namespace document_editor
{
void GetRunRange(DocumentParagraphRun* run, RunRangeMap& runRanges)
{
GetRunRangeVisitor visitor(runRanges);
run->Accept(&visitor);
}
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENTEDITOR_LOCALEHYPERLINK.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
/***********************************************************************
Get the hyperlink run that contains the specified position
***********************************************************************/
namespace document_operation_visitors
{
class LocateHyperlinkVisitor : public Object, public DocumentRun::IVisitor
{
public:
Ptr<DocumentHyperlinkRun::Package> package;
RunRangeMap& runRanges;
vint start;
vint end;
LocateHyperlinkVisitor(RunRangeMap& _runRanges, Ptr<DocumentHyperlinkRun::Package> _package, vint _start, vint _end)
:runRanges(_runRanges)
, package(_package)
, start(_start)
, end(_end)
{
}
void VisitContainer(DocumentContainerRun* run)
{
Ptr<DocumentRun> selectedRun;
for (auto subRun : run->runs)
{
RunRange range = runRanges[subRun.Obj()];
if (range.start <= start && end <= range.end)
{
subRun->Accept(this);
break;
}
}
}
void Visit(DocumentTextRun* run)override
{
}
void Visit(DocumentStylePropertiesRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentStyleApplicationRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentHyperlinkRun* run)override
{
package->hyperlinks.Add(Ptr(run));
}
void Visit(DocumentImageRun* run)override
{
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
}
using namespace document_operation_visitors;
namespace document_editor
{
Ptr<DocumentHyperlinkRun::Package> LocateHyperlink(DocumentParagraphRun* run, RunRangeMap& runRanges, vint row, vint start, vint end)
{
auto package = Ptr(new DocumentHyperlinkRun::Package);
package->row = row;
{
LocateHyperlinkVisitor visitor(runRanges, package, start, end);
run->Accept(&visitor);
}
Ptr<DocumentHyperlinkRun> startRun, endRun;
for (auto run : package->hyperlinks)
{
auto range = runRanges[run.Obj()];
if (package->start == -1 || range.start < package->start)
{
package->start = range.start;
startRun = run;
}
if (package->end == -1 || range.end > package->end)
{
package->end = range.end;
endRun = run;
}
}
while (startRun)
{
vint pos = runRanges[startRun.Obj()].start;
if (pos == 0) break;
auto newPackage = Ptr(new DocumentHyperlinkRun::Package);
LocateHyperlinkVisitor visitor(runRanges, newPackage, pos - 1, pos);
run->Accept(&visitor);
if (newPackage->hyperlinks.Count() == 0) break;
auto newRun = newPackage->hyperlinks[0];
if (startRun->reference != newRun->reference) break;
auto range = runRanges[newRun.Obj()];
package->hyperlinks.Add(newRun);
package->start = range.start;
startRun = newRun;
}
vint length = runRanges[run].end;
while (endRun)
{
vint pos = runRanges[endRun.Obj()].end;
if (pos == length) break;
auto newPackage = Ptr(new DocumentHyperlinkRun::Package);
LocateHyperlinkVisitor visitor(runRanges, newPackage, pos, pos + 1);
run->Accept(&visitor);
if (newPackage->hyperlinks.Count() == 0) break;
auto newRun = newPackage->hyperlinks[0];
if (endRun->reference != newRun->reference) break;
auto range = runRanges[newRun.Obj()];
package->hyperlinks.Add(newRun);
package->end = range.end;
endRun = newRun;
}
return package;
}
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENTEDITOR_LOCALESTYLE.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
/***********************************************************************
Get all container runs that contain the specified position from top to bottom
***********************************************************************/
namespace document_operation_visitors
{
class LocateStyleVisitor : public Object, public DocumentRun::IVisitor
{
public:
List<DocumentContainerRun*>& locatedRuns;
RunRangeMap& runRanges;
vint position;
bool frontSide;
LocateStyleVisitor(List<DocumentContainerRun*>& _locatedRuns, RunRangeMap& _runRanges, vint _position, bool _frontSide)
:locatedRuns(_locatedRuns)
, runRanges(_runRanges)
, position(_position)
, frontSide(_frontSide)
{
}
void VisitContainer(DocumentContainerRun* run)
{
locatedRuns.Add(run);
Ptr<DocumentRun> selectedRun;
for (auto subRun : run->runs)
{
RunRange range = runRanges[subRun.Obj()];
if (position == range.start)
{
if (!frontSide)
{
selectedRun = subRun;
break;
}
}
else if (position == range.end)
{
if (frontSide)
{
selectedRun = subRun;
break;
}
}
else if (range.start<position && position<range.end)
{
selectedRun = subRun;
break;
}
}
if (selectedRun)
{
selectedRun->Accept(this);
}
}
void Visit(DocumentTextRun* run)override
{
}
void Visit(DocumentStylePropertiesRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentStyleApplicationRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentHyperlinkRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentImageRun* run)override
{
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
}
using namespace document_operation_visitors;
namespace document_editor
{
void LocateStyle(DocumentParagraphRun* run, RunRangeMap& runRanges, vint position, bool frontSide, List<DocumentContainerRun*>& locatedRuns)
{
LocateStyleVisitor visitor(locatedRuns, runRanges, position, frontSide);
run->Accept(&visitor);
}
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENTEDITOR_REMOVECONTAINER.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
/***********************************************************************
Remove some containers that intersect with the specified range
If a run decides that itself should be removed, then replacedRuns contains all runs to replace itself
RemoveHyperlinkVisitor : Remove all hyperlinks that intersect with the specified range
RemoveStyleNameVisitor : Remove all style names that intersect with the specified range
ClearStyleVisitor : Remove all styles that intersect with the specified range
***********************************************************************/
namespace document_operation_visitors
{
class RemoveContainerVisitor : public Object, public DocumentRun::IVisitor
{
public:
RunRangeMap& runRanges;
vint start;
vint end;
List<Ptr<DocumentRun>> replacedRuns;
RemoveContainerVisitor(RunRangeMap& _runRanges, vint _start, vint _end)
:runRanges(_runRanges)
, start(_start)
, end(_end)
{
}
void VisitContainer(DocumentContainerRun* run)
{
// TODO: (enumerable) foreach:indexed(alterable(reversed))
for (vint i = run->runs.Count() - 1; i >= 0; i--)
{
Ptr<DocumentRun> subRun = run->runs[i];
RunRange range = runRanges[subRun.Obj()];
if (range.start<end && start<range.end)
{
replacedRuns.Clear();
subRun->Accept(this);
if (replacedRuns.Count() != 1 || replacedRuns[0] != subRun)
{
run->runs.RemoveAt(i);
// TODO: (enumerable) foreach
for (vint j = 0; j<replacedRuns.Count(); j++)
{
run->runs.Insert(i + j, replacedRuns[j]);
}
i += replacedRuns.Count();
}
}
}
replacedRuns.Clear();
replacedRuns.Add(Ptr(run));
}
void VisitContent(DocumentContentRun* run)
{
replacedRuns.Add(Ptr(run));
}
void RemoveContainer(DocumentContainerRun* run)
{
CopyFrom(replacedRuns, run->runs);
}
void Visit(DocumentTextRun* run)override
{
VisitContent(run);
}
void Visit(DocumentStylePropertiesRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentStyleApplicationRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentHyperlinkRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentImageRun* run)override
{
VisitContent(run);
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
VisitContent(run);
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
class RemoveHyperlinkVisitor : public RemoveContainerVisitor
{
public:
RemoveHyperlinkVisitor(RunRangeMap& _runRanges, vint _start, vint _end)
:RemoveContainerVisitor(_runRanges, _start, _end)
{
}
void Visit(DocumentHyperlinkRun* run)override
{
RemoveContainer(run);
}
};
class RemoveStyleNameVisitor : public RemoveContainerVisitor
{
public:
RemoveStyleNameVisitor(RunRangeMap& _runRanges, vint _start, vint _end)
:RemoveContainerVisitor(_runRanges, _start, _end)
{
}
void Visit(DocumentStyleApplicationRun* run)override
{
RemoveContainer(run);
}
};
class ClearStyleVisitor : public RemoveContainerVisitor
{
public:
ClearStyleVisitor(RunRangeMap& _runRanges, vint _start, vint _end)
:RemoveContainerVisitor(_runRanges, _start, _end)
{
}
void Visit(DocumentStylePropertiesRun* run)override
{
RemoveContainer(run);
}
void Visit(DocumentStyleApplicationRun* run)override
{
RemoveContainer(run);
}
};
}
using namespace document_operation_visitors;
namespace document_editor
{
void RemoveHyperlink(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end)
{
RemoveHyperlinkVisitor visitor(runRanges, start, end);
run->Accept(&visitor);
}
void RemoveStyleName(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end)
{
RemoveStyleNameVisitor visitor(runRanges, start, end);
run->Accept(&visitor);
}
void ClearStyle(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end)
{
ClearStyleVisitor visitor(runRanges, start, end);
run->Accept(&visitor);
}
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENTEDITOR_REMOVERUN.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
/***********************************************************************
Remove text run contents with the specified range, or other content runs that intersect with the range
If a run decides that itself should be removed, then replacedRuns contains all runs to replace itself
***********************************************************************/
namespace document_operation_visitors
{
class RemoveRunVisitor : public Object, public DocumentRun::IVisitor
{
public:
RunRangeMap& runRanges;
vint start;
vint end;
List<Ptr<DocumentRun>> replacedRuns;
RemoveRunVisitor(RunRangeMap& _runRanges, vint _start, vint _end)
:runRanges(_runRanges)
, start(_start)
, end(_end)
{
}
void VisitContainer(DocumentContainerRun* run)
{
if (start == end) return;
// TODO: (enumerable) foreach:indexed(alterable(reversed))
for (vint i = run->runs.Count() - 1; i >= 0; i--)
{
Ptr<DocumentRun> subRun = run->runs[i];
RunRange range = runRanges[subRun.Obj()];
vint maxStart = range.start > start ? range.start : start;
vint minEnd = range.end < end ? range.end : end;
if (maxStart < minEnd)
{
subRun->Accept(this);
if (replacedRuns.Count() == 0 || subRun != replacedRuns[0])
{
run->runs.RemoveAt(i);
// TODO: (enumerable) foreach
for (vint j = 0; j<replacedRuns.Count(); j++)
{
run->runs.Insert(i + j, replacedRuns[j]);
}
}
}
}
replacedRuns.Clear();
replacedRuns.Add(Ptr(run));
}
void Visit(DocumentTextRun* run)override
{
replacedRuns.Clear();
RunRange range = runRanges[run];
if (start <= range.start)
{
if (end<range.end)
{
run->text = run->text.Sub(end - range.start, range.end - end);
replacedRuns.Add(Ptr(run));
}
}
else
{
if (end<range.end)
{
auto firstRun = Ptr(new DocumentTextRun);
auto secondRun = Ptr(new DocumentTextRun);
firstRun->text = run->text.Sub(0, start - range.start);
secondRun->text = run->text.Sub(end - range.start, range.end - end);
replacedRuns.Add(firstRun);
replacedRuns.Add(secondRun);
}
else
{
run->text = run->text.Sub(0, start - range.start);
replacedRuns.Add(Ptr(run));
}
}
}
void Visit(DocumentStylePropertiesRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentStyleApplicationRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentHyperlinkRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentImageRun* run)override
{
replacedRuns.Clear();
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
replacedRuns.Clear();
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
}
using namespace document_operation_visitors;
namespace document_editor
{
void RemoveRun(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end)
{
RemoveRunVisitor visitor(runRanges, start, end);
run->Accept(&visitor);
}
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENTEDITOR_REPLACESTYLENAME.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
/***********************************************************************
Replace a style name with another one
***********************************************************************/
namespace document_operation_visitors
{
class ReplaceStyleNameVisitor : public Object, public DocumentRun::IVisitor
{
public:
WString oldStyleName;
WString newStyleName;
ReplaceStyleNameVisitor(const WString& _oldStyleName, const WString& _newStyleName)
:oldStyleName(_oldStyleName)
, newStyleName(_newStyleName)
{
}
void VisitContainer(DocumentContainerRun* run)
{
for (auto subRun : run->runs)
{
subRun->Accept(this);
}
}
void Visit(DocumentTextRun* run)override
{
}
void Visit(DocumentStylePropertiesRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentStyleApplicationRun* run)override
{
if (run->styleName == oldStyleName) run->styleName = newStyleName;
VisitContainer(run);
}
void Visit(DocumentHyperlinkRun* run)override
{
if (run->styleName == oldStyleName) run->styleName = newStyleName;
if (run->normalStyleName == oldStyleName) run->normalStyleName = newStyleName;
if (run->activeStyleName == oldStyleName) run->activeStyleName = newStyleName;
VisitContainer(run);
}
void Visit(DocumentImageRun* run)override
{
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
}
using namespace document_operation_visitors;
namespace document_editor
{
void ReplaceStyleName(DocumentParagraphRun* run, const WString& oldStyleName, const WString& newStyleName)
{
ReplaceStyleNameVisitor visitor(oldStyleName, newStyleName);
run->Accept(&visitor);
}
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENTEDITOR_SUMMERIZESTYLE.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
namespace document_operation_visitors
{
/***********************************************************************
Calculate if all text in the specified range has some common styles
***********************************************************************/
class SummarizeStyleVisitor : public Object, public DocumentRun::IVisitor
{
public:
RunRangeMap& runRanges;
DocumentModel* model;
vint start;
vint end;
Ptr<DocumentStyleProperties> style;
List<DocumentModel::ResolvedStyle> resolvedStyles;
SummarizeStyleVisitor(RunRangeMap& _runRanges, DocumentModel* _model, vint _start, vint _end)
:runRanges(_runRanges)
, model(_model)
, start(_start)
, end(_end)
{
DocumentModel::ResolvedStyle resolvedStyle;
resolvedStyle = model->GetStyle(DocumentModel::DefaultStyleName, resolvedStyle);
resolvedStyles.Add(resolvedStyle);
}
const DocumentModel::ResolvedStyle& GetCurrentResolvedStyle()
{
return resolvedStyles[resolvedStyles.Count() - 1];
}
// ---------------------------------------------------------
template<typename T>
void SetStyleItem(Nullable<T> DocumentStyleProperties::* dstField, T FontProperties::* srcField)
{
const DocumentModel::ResolvedStyle& src = GetCurrentResolvedStyle();
if (style.Obj()->*dstField && (style.Obj()->*dstField).Value() != src.style.*srcField)
{
style.Obj()->*dstField = Nullable<T>();
}
}
template<typename T>
void SetStyleItem(Nullable<T> DocumentStyleProperties::* dstField, T DocumentModel::ResolvedStyle::* srcField)
{
const DocumentModel::ResolvedStyle& src = GetCurrentResolvedStyle();
if (style.Obj()->*dstField && (style.Obj()->*dstField).Value() != src.*srcField)
{
style.Obj()->*dstField = Nullable<T>();
}
}
void SetStyleItem(Nullable<DocumentFontSize> DocumentStyleProperties::* dstField, vint FontProperties::* srcField)
{
const DocumentModel::ResolvedStyle& src = GetCurrentResolvedStyle();
if (style.Obj()->*dstField)
{
auto dfs = (style.Obj()->*dstField).Value();
if (dfs.relative || dfs.size != src.style.*srcField)
{
style.Obj()->*dstField = Nullable<DocumentFontSize>();
}
}
}
// ---------------------------------------------------------
template<typename T>
void OverrideStyleItem(Nullable<T> DocumentStyleProperties::* dstField, T FontProperties::* srcField)
{
const DocumentModel::ResolvedStyle& src = GetCurrentResolvedStyle();
style.Obj()->*dstField = src.style.*srcField;
}
template<typename T>
void OverrideStyleItem(Nullable<T> DocumentStyleProperties::* dstField, T DocumentModel::ResolvedStyle::* srcField)
{
const DocumentModel::ResolvedStyle& src = GetCurrentResolvedStyle();
style.Obj()->*dstField = src.*srcField;
}
void OverrideStyleItem(Nullable<DocumentFontSize> DocumentStyleProperties::* dstField, vint FontProperties::* srcField)
{
const DocumentModel::ResolvedStyle& src = GetCurrentResolvedStyle();
style.Obj()->*dstField = DocumentFontSize((double)(src.style.*srcField), false);
}
// ---------------------------------------------------------
void VisitContainer(DocumentContainerRun* run)
{
// TODO: (enumerable) foreach:reversed
for (vint i = run->runs.Count() - 1; i >= 0; i--)
{
Ptr<DocumentRun> subRun = run->runs[i];
RunRange range = runRanges[subRun.Obj()];
if (range.start<end && start<range.end)
{
subRun->Accept(this);
}
}
}
void Visit(DocumentTextRun* run)override
{
const DocumentModel::ResolvedStyle& currentResolvedStyle = GetCurrentResolvedStyle();
if (style)
{
SetStyleItem(&DocumentStyleProperties::face, &FontProperties::fontFamily);
SetStyleItem(&DocumentStyleProperties::size, &FontProperties::size);
SetStyleItem(&DocumentStyleProperties::color, &DocumentModel::ResolvedStyle::color);
SetStyleItem(&DocumentStyleProperties::backgroundColor, &DocumentModel::ResolvedStyle::backgroundColor);
SetStyleItem(&DocumentStyleProperties::bold, &FontProperties::bold);
SetStyleItem(&DocumentStyleProperties::italic, &FontProperties::italic);
SetStyleItem(&DocumentStyleProperties::underline, &FontProperties::underline);
SetStyleItem(&DocumentStyleProperties::strikeline, &FontProperties::strikeline);
SetStyleItem(&DocumentStyleProperties::antialias, &FontProperties::antialias);
SetStyleItem(&DocumentStyleProperties::verticalAntialias, &FontProperties::verticalAntialias);
}
else
{
style = Ptr(new DocumentStyleProperties);
OverrideStyleItem(&DocumentStyleProperties::face, &FontProperties::fontFamily);
OverrideStyleItem(&DocumentStyleProperties::size, &FontProperties::size);
OverrideStyleItem(&DocumentStyleProperties::color, &DocumentModel::ResolvedStyle::color);
OverrideStyleItem(&DocumentStyleProperties::backgroundColor, &DocumentModel::ResolvedStyle::backgroundColor);
OverrideStyleItem(&DocumentStyleProperties::bold, &FontProperties::bold);
OverrideStyleItem(&DocumentStyleProperties::italic, &FontProperties::italic);
OverrideStyleItem(&DocumentStyleProperties::underline, &FontProperties::underline);
OverrideStyleItem(&DocumentStyleProperties::strikeline, &FontProperties::strikeline);
OverrideStyleItem(&DocumentStyleProperties::antialias, &FontProperties::antialias);
OverrideStyleItem(&DocumentStyleProperties::verticalAntialias, &FontProperties::verticalAntialias);
}
}
void Visit(DocumentStylePropertiesRun* run)override
{
const DocumentModel::ResolvedStyle& currentResolvedStyle = GetCurrentResolvedStyle();
DocumentModel::ResolvedStyle resolvedStyle = model->GetStyle(run->style, currentResolvedStyle);
resolvedStyles.Add(resolvedStyle);
VisitContainer(run);
resolvedStyles.RemoveAt(resolvedStyles.Count() - 1);
}
void Visit(DocumentStyleApplicationRun* run)override
{
const DocumentModel::ResolvedStyle& currentResolvedStyle = GetCurrentResolvedStyle();
DocumentModel::ResolvedStyle resolvedStyle = model->GetStyle(run->styleName, currentResolvedStyle);
resolvedStyles.Add(resolvedStyle);
VisitContainer(run);
resolvedStyles.RemoveAt(resolvedStyles.Count() - 1);
}
void Visit(DocumentHyperlinkRun* run)override
{
const DocumentModel::ResolvedStyle& currentResolvedStyle = GetCurrentResolvedStyle();
DocumentModel::ResolvedStyle resolvedStyle = model->GetStyle(run->styleName, currentResolvedStyle);
resolvedStyles.Add(resolvedStyle);
VisitContainer(run);
resolvedStyles.RemoveAt(resolvedStyles.Count() - 1);
}
void Visit(DocumentImageRun* run)override
{
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
/***********************************************************************
Calculate if all text in the specified range has a common style name
***********************************************************************/
class SummarizeStyleNameVisitor : public Object, public DocumentRun::IVisitor
{
public:
RunRangeMap& runRanges;
DocumentModel* model;
vint start;
vint end;
Nullable<WString> currentStyleName;
Nullable<WString> styleName;
bool assignedStyleName = false;
SummarizeStyleNameVisitor(RunRangeMap& _runRanges, DocumentModel* _model, vint _start, vint _end)
:runRanges(_runRanges)
, model(_model)
, start(_start)
, end(_end)
{
}
void VisitContentRun(DocumentContentRun* run)
{
if (!assignedStyleName)
{
styleName = currentStyleName;
assignedStyleName = true;
}
else if (styleName && (!currentStyleName || styleName.Value() != currentStyleName.Value()))
{
styleName = Nullable<WString>();
}
}
void VisitContainer(DocumentContainerRun* run)
{
// TODO: (enumerable) foreach:reversed
for (vint i = run->runs.Count() - 1; i >= 0; i--)
{
Ptr<DocumentRun> subRun = run->runs[i];
RunRange range = runRanges[subRun.Obj()];
if (range.start<end && start<range.end)
{
subRun->Accept(this);
}
}
}
void Visit(DocumentTextRun* run)override
{
VisitContentRun(run);
}
void Visit(DocumentStylePropertiesRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentStyleApplicationRun* run)override
{
auto oldStyleName = currentStyleName;
currentStyleName = run->styleName;
VisitContainer(run);
currentStyleName = oldStyleName;
}
void Visit(DocumentHyperlinkRun* run)override
{
VisitContainer(run);
}
void Visit(DocumentImageRun* run)override
{
VisitContentRun(run);
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
VisitContentRun(run);
}
void Visit(DocumentParagraphRun* run)override
{
VisitContainer(run);
}
};
}
using namespace document_operation_visitors;
namespace document_editor
{
Ptr<DocumentStyleProperties> SummarizeStyle(DocumentParagraphRun* run, RunRangeMap& runRanges, DocumentModel* model, vint start, vint end)
{
SummarizeStyleVisitor visitor(runRanges, model, start, end);
run->Accept(&visitor);
return visitor.style;
}
Nullable<WString> SummarizeStyleName(DocumentParagraphRun* run, RunRangeMap& runRanges, DocumentModel* model, vint start, vint end)
{
SummarizeStyleNameVisitor visitor(runRanges, model, start, end);
run->Accept(&visitor);
return visitor.styleName;
}
template<typename T>
void AggregateStyleItem(Ptr<DocumentStyleProperties>& dst, Ptr<DocumentStyleProperties> src, Nullable<T> DocumentStyleProperties::* field)
{
if (dst.Obj()->*field && (!(src.Obj()->*field) || (dst.Obj()->*field).Value() != (src.Obj()->*field).Value()))
{
dst.Obj()->*field = Nullable<T>();
}
}
void AggregateStyle(Ptr<DocumentStyleProperties>& dst, Ptr<DocumentStyleProperties> src)
{
AggregateStyleItem(dst, src, &DocumentStyleProperties::face);
AggregateStyleItem(dst, src, &DocumentStyleProperties::size);
AggregateStyleItem(dst, src, &DocumentStyleProperties::color);
AggregateStyleItem(dst, src, &DocumentStyleProperties::backgroundColor);
AggregateStyleItem(dst, src, &DocumentStyleProperties::bold);
AggregateStyleItem(dst, src, &DocumentStyleProperties::italic);
AggregateStyleItem(dst, src, &DocumentStyleProperties::underline);
AggregateStyleItem(dst, src, &DocumentStyleProperties::strikeline);
AggregateStyleItem(dst, src, &DocumentStyleProperties::antialias);
AggregateStyleItem(dst, src, &DocumentStyleProperties::verticalAntialias);
}
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENT_EDIT.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace document_editor;
/***********************************************************************
DocumentModel::EditRangeOperations
***********************************************************************/
bool DocumentModel::CheckEditRange(TextPos begin, TextPos end, RunRangeMap& relatedRanges)
{
// check caret range
if(begin>end) return false;
if(begin.row<0 || begin.row>=paragraphs.Count()) return false;
if(end.row<0 || end.row>=paragraphs.Count()) return false;
// determine run ranges
GetRunRange(paragraphs[begin.row].Obj(), relatedRanges);
if(begin.row!=end.row)
{
GetRunRange(paragraphs[end.row].Obj(), relatedRanges);
}
// check caret range
RunRange beginRange=relatedRanges[paragraphs[begin.row].Obj()];
RunRange endRange=relatedRanges[paragraphs[end.row].Obj()];
if(begin.column<0 || begin.column>beginRange.end) return false;
if(end.column<0 || end.column>endRange.end) return false;
return true;
}
Ptr<DocumentModel> DocumentModel::CopyDocument(TextPos begin, TextPos end, bool deepCopy)
{
// check caret range
RunRangeMap runRanges;
if(!CheckEditRange(begin, end, runRanges)) return nullptr;
// get ranges
for(vint i=begin.row+1;i<end.row;i++)
{
GetRunRange(paragraphs[i].Obj(), runRanges);
}
auto newDocument = Ptr(new DocumentModel);
// copy paragraphs
if(begin.row==end.row)
{
newDocument->paragraphs.Add(CopyRunRecursively(paragraphs[begin.row].Obj(), runRanges, begin.column, end.column, deepCopy).Cast<DocumentParagraphRun>());
}
else
{
for(vint i=begin.row;i<=end.row;i++)
{
Ptr<DocumentParagraphRun> paragraph=paragraphs[i];
RunRange range=runRanges[paragraph.Obj()];
if(i==begin.row)
{
newDocument->paragraphs.Add(CopyRunRecursively(paragraph.Obj(), runRanges, begin.column, range.end, deepCopy).Cast<DocumentParagraphRun>());
}
else if(i==end.row)
{
newDocument->paragraphs.Add(CopyRunRecursively(paragraph.Obj(), runRanges, range.start, end.column, deepCopy).Cast<DocumentParagraphRun>());
}
else if(deepCopy)
{
newDocument->paragraphs.Add(CopyRunRecursively(paragraph.Obj(), runRanges, range.start, range.end, deepCopy).Cast<DocumentParagraphRun>());
}
else
{
newDocument->paragraphs.Add(paragraph);
}
}
}
// copy styles
List<WString> styleNames;
for (auto paragraph : newDocument->paragraphs)
{
CollectStyleName(paragraph.Obj(), styleNames);
}
// TODO: (enumerable) foreach:alterable
for(vint i=0;i<styleNames.Count();i++)
{
WString styleName=styleNames[i];
if(!newDocument->styles.Keys().Contains(styleName))
{
Ptr<DocumentStyle> style=styles[styleName];
if(deepCopy)
{
auto newStyle = Ptr(new DocumentStyle);
newStyle->parentStyleName=style->parentStyleName;
newStyle->styles=CopyStyle(style->styles);
newStyle->resolvedStyles=CopyStyle(style->resolvedStyles);
newDocument->styles.Add(styleName, newStyle);
}
else
{
newDocument->styles.Add(styleName, style);
}
if(!styleNames.Contains(style->parentStyleName))
{
styleNames.Add(style->parentStyleName);
}
}
}
return newDocument;
}
Ptr<DocumentModel> DocumentModel::CopyDocument()
{
// determine run ranges
RunRangeMap runRanges;
vint lastParagraphIndex = paragraphs.Count() - 1;
GetRunRange(paragraphs[lastParagraphIndex].Obj(), runRanges);
TextPos begin(0, 0);
TextPos end(lastParagraphIndex, runRanges[paragraphs[lastParagraphIndex].Obj()].end);
return CopyDocument(begin, end, true);
}
bool DocumentModel::CutParagraph(TextPos position)
{
if(position.row<0 || position.row>=paragraphs.Count()) return false;
Ptr<DocumentParagraphRun> paragraph=paragraphs[position.row];
RunRangeMap runRanges;
Ptr<DocumentRun> leftRun, rightRun;
GetRunRange(paragraph.Obj(), runRanges);
CutRun(paragraph.Obj(), runRanges, position.column, leftRun, rightRun);
CopyFrom(paragraph->runs, leftRun.Cast<DocumentParagraphRun>()->runs);
CopyFrom(paragraph->runs, rightRun.Cast<DocumentParagraphRun>()->runs, true);
return true;
}
bool DocumentModel::CutEditRange(TextPos begin, TextPos end)
{
// check caret range
if(begin>end) return false;
if(begin.row<0 || begin.row>=paragraphs.Count()) return false;
if(end.row<0 || end.row>=paragraphs.Count()) return false;
// cut paragraphs
CutParagraph(begin);
if(begin!=end)
{
CutParagraph(end);
}
return true;
}
bool DocumentModel::EditContainer(TextPos begin, TextPos end, const Func<void(DocumentParagraphRun*, RunRangeMap&, vint, vint)>& editor)
{
if(begin==end) return false;
// cut paragraphs
if(!CutEditRange(begin, end)) return false;
// check caret range
RunRangeMap runRanges;
if(!CheckEditRange(begin, end, runRanges)) return false;
// edit container
if(begin.row==end.row)
{
editor(paragraphs[begin.row].Obj(), runRanges, begin.column, end.column);
}
else
{
for(vint i=begin.row;i<=end.row;i++)
{
Ptr<DocumentParagraphRun> paragraph=paragraphs[i];
if(begin.row<i && i<end.row)
{
GetRunRange(paragraph.Obj(), runRanges);
}
RunRange range=runRanges[paragraph.Obj()];
if(i==begin.row)
{
editor(paragraph.Obj(), runRanges, begin.column, range.end);
}
else if(i==end.row)
{
editor(paragraph.Obj(), runRanges, range.start, end.column);
}
else
{
editor(paragraph.Obj(), runRanges, range.start, range.end);
}
}
}
// clear paragraphs
for(vint i=begin.row;i<=end.row;i++)
{
ClearUnnecessaryRun(paragraphs[i].Obj(), this);
}
return true;
}
/***********************************************************************
DocumentModel::EditRun
***********************************************************************/
vint DocumentModel::EditRun(TextPos begin, TextPos end, Ptr<DocumentModel> replaceToModel, bool copy)
{
// check caret range
RunRangeMap runRanges;
if(!CheckEditRange(begin, end, runRanges)) return -1;
auto model = replaceToModel;
if (copy)
{
model = replaceToModel->CopyDocument();
}
// calculate new names for the model's styles to prevent conflicting
List<WString> oldNames, newNames;
CopyFrom(oldNames, model->styles.Keys());
CopyFrom(newNames, model->styles.Keys());
// TODO: (enumerable) foreach:indexed(allow-set)
for(vint i=0;i<newNames.Count();i++)
{
WString name=newNames[i];
if((name.Length()==0 || name[0]!=L'#') && styles.Keys().Contains(name))
{
vint index=2;
while(true)
{
WString newName=name+L"_"+itow(index++);
if(!styles.Keys().Contains(newName) && !model->styles.Keys().Contains(newName))
{
newNames[i]=newName;
break;
}
}
}
}
// rename model's styles
typedef Pair<WString, WString> NamePair;
for (auto name : From(oldNames).Pairwise(newNames))
{
model->RenameStyle(name.key, name.value);
}
for (auto name : newNames)
{
if((name.Length()==0 || name[0]!=L'#') && !styles.Keys().Contains(name))
{
styles.Add(name, model->styles[name]);
}
}
// edit runs
Array<Ptr<DocumentParagraphRun>> runs;
CopyFrom(runs, model->paragraphs);
return EditRunNoCopy(begin, end, runs);
}
vint DocumentModel::EditRunNoCopy(TextPos begin, TextPos end, const collections::Array<Ptr<DocumentParagraphRun>>& runs)
{
// check caret range
RunRangeMap runRanges;
if(!CheckEditRange(begin, end, runRanges)) return -1;
// remove unnecessary paragraphs
if(begin.row!=end.row)
{
for(vint i=end.row-1;i>begin.row;i--)
{
paragraphs.RemoveAt(i);
}
end.row=begin.row+1;
}
// remove unnecessary runs and ensure begin.row!=end.row
if(begin.row==end.row)
{
RemoveRun(paragraphs[begin.row].Obj(), runRanges, begin.column, end.column);
Ptr<DocumentRun> leftRun, rightRun;
runRanges.Clear();
GetRunRange(paragraphs[begin.row].Obj(), runRanges);
CutRun(paragraphs[begin.row].Obj(), runRanges, begin.column, leftRun, rightRun);
paragraphs.RemoveAt(begin.row);
paragraphs.Insert(begin.row, leftRun.Cast<DocumentParagraphRun>());
paragraphs.Insert(begin.row+1, rightRun.Cast<DocumentParagraphRun>());
end.row=begin.row+1;
}
else
{
RemoveRun(paragraphs[begin.row].Obj(), runRanges, begin.column, runRanges[paragraphs[begin.row].Obj()].end);
RemoveRun(paragraphs[end.row].Obj(), runRanges, 0, end.column);
}
// insert new paragraphs
Ptr<DocumentParagraphRun> beginParagraph=paragraphs[begin.row];
Ptr<DocumentParagraphRun> endParagraph=paragraphs[end.row];
if(runs.Count()==0)
{
CopyFrom(beginParagraph->runs, endParagraph->runs, true);
paragraphs.RemoveAt(end.row);
}
else if(runs.Count()==1)
{
CopyFrom(beginParagraph->runs, runs[0]->runs, true);
CopyFrom(beginParagraph->runs, endParagraph->runs, true);
paragraphs.RemoveAt(end.row);
}
else
{
Ptr<DocumentParagraphRun> newBeginRuns=runs[0];
CopyFrom(beginParagraph->runs, newBeginRuns->runs, true);
Ptr<DocumentParagraphRun> newEndRuns=runs[runs.Count()-1];
if (newEndRuns->alignment)
{
endParagraph->alignment = newEndRuns->alignment;
}
// TODO: (enumerable) foreach
for(vint i=0;i<newEndRuns->runs.Count();i++)
{
endParagraph->runs.Insert(i, newEndRuns->runs[i]);
}
// TODO: (enumerable) foreach:indexed
for(vint i=1;i<runs.Count()-1;i++)
{
paragraphs.Insert(begin.row+i, runs[i]);
}
}
// clear unnecessary runs
vint rows=runs.Count()==0?1:runs.Count();
for(vint i=0;i<rows;i++)
{
ClearUnnecessaryRun(paragraphs[begin.row+i].Obj(), this);
}
return rows;
}
/***********************************************************************
DocumentModel::EditText
***********************************************************************/
vint DocumentModel::EditText(TextPos begin, TextPos end, bool frontSide, const collections::Array<WString>& text)
{
// check caret range
RunRangeMap runRanges;
if(!CheckEditRange(begin, end, runRanges)) return -1;
// calcuate the position to get the text style
TextPos stylePosition;
if(frontSide)
{
stylePosition=begin;
if(stylePosition.column==0)
{
frontSide=false;
}
}
else
{
stylePosition=end;
if(stylePosition.column==runRanges[paragraphs[end.row].Obj()].end)
{
frontSide=true;
}
}
// copy runs that contains the target style for new text
List<DocumentContainerRun*> styleRuns;
LocateStyle(paragraphs[stylePosition.row].Obj(), runRanges, stylePosition.column, frontSide, styleRuns);
// create paragraphs
Array<Ptr<DocumentParagraphRun>> runs(text.Count());
// TODO: (enumerable) foreach:indexed
for(vint i=0;i<text.Count();i++)
{
Ptr<DocumentRun> paragraph=CopyStyledText(styleRuns, text[i]);
runs[i]=paragraph.Cast<DocumentParagraphRun>();
}
// replace the paragraphs
return EditRunNoCopy(begin, end, runs);
}
/***********************************************************************
DocumentModel::EditStyle
***********************************************************************/
bool DocumentModel::EditStyle(TextPos begin, TextPos end, Ptr<DocumentStyleProperties> style)
{
return EditContainer(begin, end, [=](DocumentParagraphRun* paragraph, RunRangeMap& runRanges, vint start, vint end)
{
AddStyle(paragraph, runRanges, start, end, style);
});
}
/***********************************************************************
DocumentModel::EditImage
***********************************************************************/
Ptr<DocumentImageRun> DocumentModel::EditImage(TextPos begin, TextPos end, Ptr<GuiImageData> image)
{
auto imageRun = Ptr(new DocumentImageRun);
imageRun->size=image->GetImage()->GetFrame(image->GetFrameIndex())->GetSize();
imageRun->baseline=imageRun->size.y;
imageRun->image=image->GetImage();
imageRun->frameIndex=image->GetFrameIndex();
auto paragraph = Ptr(new DocumentParagraphRun);
paragraph->runs.Add(imageRun);
Array<Ptr<DocumentParagraphRun>> runs(1);
runs[0]=paragraph;
if(EditRunNoCopy(begin, end, runs))
{
return imageRun;
}
else
{
return 0;
}
}
/***********************************************************************
DocumentModel::EditHyperlink
***********************************************************************/
bool DocumentModel::EditHyperlink(vint paragraphIndex, vint begin, vint end, const WString& reference, const WString& normalStyleName, const WString& activeStyleName)
{
auto package = GetHyperlink(paragraphIndex, begin, end);
if (package->hyperlinks.Count() > 0)
{
for (auto run : package->hyperlinks)
{
run->reference = reference;
run->normalStyleName = normalStyleName;
run->activeStyleName = activeStyleName;
run->styleName = normalStyleName;
}
return true;
}
else if (RemoveHyperlink(paragraphIndex, begin, end))
{
CutEditRange(TextPos(paragraphIndex, begin), TextPos(paragraphIndex, end));
RunRangeMap runRanges;
Ptr<DocumentParagraphRun> paragraph = paragraphs[paragraphIndex];
GetRunRange(paragraph.Obj(), runRanges);
AddHyperlink(paragraph.Obj(), runRanges, begin, end, reference, normalStyleName, activeStyleName);
ClearUnnecessaryRun(paragraph.Obj(), this);
return true;
}
return false;
}
bool DocumentModel::RemoveHyperlink(vint paragraphIndex, vint begin, vint end)
{
RunRangeMap runRanges;
if (!CheckEditRange(TextPos(paragraphIndex, begin), TextPos(paragraphIndex, end), runRanges)) return 0;
auto paragraph = paragraphs[paragraphIndex];
auto package = LocateHyperlink(paragraph.Obj(), runRanges, paragraphIndex, begin, end);
document_editor::RemoveHyperlink(paragraph.Obj(), runRanges, package->start, package->end);
ClearUnnecessaryRun(paragraph.Obj(), this);
return true;
}
Ptr<DocumentHyperlinkRun::Package> DocumentModel::GetHyperlink(vint paragraphIndex, vint begin, vint end)
{
RunRangeMap runRanges;
if (!CheckEditRange(TextPos(paragraphIndex, begin), TextPos(paragraphIndex, end), runRanges)) return 0;
auto paragraph = paragraphs[paragraphIndex];
return LocateHyperlink(paragraph.Obj(), runRanges, paragraphIndex, begin, end);
}
/***********************************************************************
DocumentModel::EditStyleName
***********************************************************************/
bool DocumentModel::EditStyleName(TextPos begin, TextPos end, const WString& styleName)
{
return EditContainer(begin, end, [=](DocumentParagraphRun* paragraph, RunRangeMap& runRanges, vint start, vint end)
{
AddStyleName(paragraph, runRanges, start, end, styleName);
});
}
bool DocumentModel::RemoveStyleName(TextPos begin, TextPos end)
{
return EditContainer(begin, end, [=](DocumentParagraphRun* paragraph, RunRangeMap& runRanges, vint start, vint end)
{
document_editor::RemoveStyleName(paragraph, runRanges, start, end);
});
}
bool DocumentModel::RenameStyle(const WString& oldStyleName, const WString& newStyleName)
{
vint index=styles.Keys().IndexOf(oldStyleName);
if(index==-1) return false;
if(styles.Keys().Contains(newStyleName)) return false;
Ptr<DocumentStyle> style=styles.Values()[index];
styles.Remove(oldStyleName);
styles.Add(newStyleName, style);
for (auto subStyle : styles.Values())
{
if(subStyle->parentStyleName==oldStyleName)
{
subStyle->parentStyleName=newStyleName;
}
}
for (auto paragraph : paragraphs)
{
ReplaceStyleName(paragraph.Obj(), oldStyleName, newStyleName);
}
return true;
}
/***********************************************************************
DocumentModel::ClearStyle
***********************************************************************/
bool DocumentModel::ClearStyle(TextPos begin, TextPos end)
{
return EditContainer(begin, end, [=](DocumentParagraphRun* paragraph, RunRangeMap& runRanges, vint start, vint end)
{
document_editor::ClearStyle(paragraph, runRanges, start, end);
});
}
/***********************************************************************
DocumentModel::ClearStyle
***********************************************************************/
Ptr<DocumentStyleProperties> DocumentModel::SummarizeStyle(TextPos begin, TextPos end)
{
Ptr<DocumentStyleProperties> style;
RunRangeMap runRanges;
if (begin == end) goto END_OF_SUMMERIZING;
// check caret range
if (!CheckEditRange(begin, end, runRanges)) return nullptr;
// Summarize container
if (begin.row == end.row)
{
style = document_editor::SummarizeStyle(paragraphs[begin.row].Obj(), runRanges, this, begin.column, end.column);
}
else
{
for (vint i = begin.row; i <= end.row; i++)
{
Ptr<DocumentParagraphRun> paragraph = paragraphs[i];
if (begin.row < i && i < end.row)
{
GetRunRange(paragraph.Obj(), runRanges);
}
RunRange range = runRanges[paragraph.Obj()];
Ptr<DocumentStyleProperties> paragraphStyle;
if (i == begin.row)
{
paragraphStyle = document_editor::SummarizeStyle(paragraph.Obj(), runRanges, this, begin.column, range.end);
}
else if (i == end.row)
{
paragraphStyle = document_editor::SummarizeStyle(paragraph.Obj(), runRanges, this, range.start, end.column);
}
else
{
paragraphStyle = document_editor::SummarizeStyle(paragraph.Obj(), runRanges, this, range.start, range.end);
}
if (!style)
{
style = paragraphStyle;
}
else if (paragraphStyle)
{
AggregateStyle(style, paragraphStyle);
}
}
}
END_OF_SUMMERIZING:
if (!style)
{
style = Ptr(new DocumentStyleProperties);
}
return style;
}
Nullable<WString> DocumentModel::SummarizeStyleName(TextPos begin, TextPos end)
{
if (begin == end) return {};
// check caret range
RunRangeMap runRanges;
if (!CheckEditRange(begin, end, runRanges)) return {};
// Summarize container
Nullable<WString> styleName;
if (begin.row == end.row)
{
styleName = document_editor::SummarizeStyleName(paragraphs[begin.row].Obj(), runRanges, this, begin.column, end.column);
}
else
{
for (vint i = begin.row; i <= end.row; i++)
{
Ptr<DocumentParagraphRun> paragraph = paragraphs[i];
if (begin.row < i && i < end.row)
{
GetRunRange(paragraph.Obj(), runRanges);
}
RunRange range = runRanges[paragraph.Obj()];
Nullable<WString> newStyleName;
if (i == begin.row)
{
newStyleName = document_editor::SummarizeStyleName(paragraph.Obj(), runRanges, this, begin.column, range.end);
}
else if (i == end.row)
{
newStyleName = document_editor::SummarizeStyleName(paragraph.Obj(), runRanges, this, range.start, end.column);
}
else
{
newStyleName = document_editor::SummarizeStyleName(paragraph.Obj(), runRanges, this, range.start, end.column);
}
if (i == begin.row)
{
styleName = newStyleName;
}
else if (!styleName || !newStyleName || styleName.Value() != newStyleName.Value())
{
styleName = Nullable<WString>();
}
}
}
return styleName;
}
Nullable<Alignment> DocumentModel::SummarizeParagraphAlignment(TextPos begin, TextPos end)
{
bool left = false;
bool center = false;
bool right = false;
RunRangeMap runRanges;
if (!CheckEditRange(begin, end, runRanges)) return {};
for (vint i = begin.row; i <= end.row; i++)
{
auto paragraph = paragraphs[i];
if (paragraph->alignment)
{
switch (paragraph->alignment.Value())
{
case Alignment::Left:
left = true;
break;
case Alignment::Center:
center = true;
break;
case Alignment::Right:
right = true;
break;
}
}
else
{
left = true;
}
}
if (left && !center && !right) return Alignment::Left;
if (!left && center && !right) return Alignment::Center;
if (!left && !center && right) return Alignment::Right;
return {};
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENT_LOAD.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace glr::xml;
using namespace regex;
/***********************************************************************
document_operation_visitors::DeserializeNodeVisitor
***********************************************************************/
namespace document_operation_visitors
{
class DeserializeNodeVisitor : public XmlNode::IVisitor
{
public:
Ptr<DocumentModel> model;
Ptr<DocumentContainerRun> container;
vint paragraphIndex;
Ptr<GuiResourceItem> resource;
Ptr<GuiResourcePathResolver> resolver;
Regex regexAttributeApply;
GuiResourceError::List& errors;
DeserializeNodeVisitor(Ptr<DocumentModel> _model, Ptr<DocumentParagraphRun> _paragraph, vint _paragraphIndex, Ptr<GuiResourceItem> _resource, Ptr<GuiResourcePathResolver> _resolver, GuiResourceError::List& _errors)
:model(_model)
, container(_paragraph)
, paragraphIndex(_paragraphIndex)
, resource(_resource)
, resolver(_resolver)
, regexAttributeApply(L"/{@(<value>[^{}]+)/}")
, errors(_errors)
{
}
void PrintText(const WString& text)
{
auto run = Ptr(new DocumentTextRun);
run->text = text;
container->runs.Add(run);
}
void Visit(XmlText* node)override
{
PrintText(node->content.value);
}
void Visit(XmlCData* node)override
{
PrintText(node->content.value);
}
void Visit(XmlComment* node)override
{
}
void Visit(XmlElement* node)override
{
Ptr<DocumentContainerRun> createdContainer;
bool useTemplateInfo = false;
XmlElement* subNodeContainer = node;
if (node->name.value == L"br")
{
PrintText(L"\r\n");
}
else if (node->name.value == L"sp")
{
PrintText(L" ");
}
else if (node->name.value == L"tab")
{
PrintText(L"\t");
}
else if (node->name.value == L"img")
{
auto run = Ptr(new DocumentImageRun);
run->baseline = -1;
if (Ptr<XmlAttribute> source = XmlGetAttribute(node, L"source"))
{
run->source = source->value.value;
WString protocol, path;
if (IsResourceUrl(run->source, protocol, path))
{
Ptr<GuiImageData> imageData = resolver->ResolveResource(protocol, path).Cast<GuiImageData>();
if (imageData)
{
run->image = imageData->GetImage();
}
if (run->image && run->image->GetFrameCount() > 0)
{
run->size = run->image->GetFrame(0)->GetSize();
run->frameIndex = 0;
}
}
for (auto att : node->attributes)
{
if (att->name.value == L"width")
{
run->size.x = wtoi(att->value.value);
}
else if (att->name.value == L"height")
{
run->size.y = wtoi(att->value.value);
}
else if (att->name.value == L"baseline")
{
run->baseline = wtoi(att->value.value);
}
else if (att->name.value == L"frameIndex")
{
run->frameIndex = wtoi(att->value.value);
}
else if (att->name.value != L"source")
{
errors.Add(GuiResourceError({ {resource},att->name.codeRange.start }, L"Unknown attribute in <img>: \"" + att->name.value + L"\"."));
}
}
container->runs.Add(run);
}
else
{
errors.Add(GuiResourceError({ {resource},node->codeRange.start }, L"Attribute \"source\" is missing in <img>."));
}
}
else if (node->name.value == L"object")
{
auto run = Ptr(new DocumentEmbeddedObjectRun);
run->baseline = -1;
if (auto name = XmlGetAttribute(node, L"name"))
{
run->name = name->value.value;
container->runs.Add(run);
}
else
{
errors.Add(GuiResourceError({ {resource},node->codeRange.start }, L"The \"name\" attribute in <object> is missing."));
}
}
else if (node->name.value == L"font")
{
auto run = Ptr(new DocumentStylePropertiesRun);
auto sp = Ptr(new DocumentStyleProperties);
run->style = sp;
for (auto att : node->attributes)
{
if (att->name.value == L"face")
{
sp->face = att->value.value;
}
else if (att->name.value == L"size")
{
sp->size = DocumentFontSize::Parse(att->value.value);
}
else if (att->name.value == L"color")
{
sp->color = Color::Parse(att->value.value);
}
else if (att->name.value == L"bkcolor")
{
sp->backgroundColor = Color::Parse(att->value.value);
}
else
{
errors.Add(GuiResourceError({ {resource},att->name.codeRange.start }, L"Unknown attribute in <font>: \"" + att->name.value + L"\"."));
}
}
container->runs.Add(run);
createdContainer = run;
}
else if (node->name.value == L"b" || node->name.value == L"b-")
{
auto run = Ptr(new DocumentStylePropertiesRun);
run->style = Ptr(new DocumentStyleProperties);
run->style->bold = node->name.value == L"b";
container->runs.Add(run);
createdContainer = run;
}
else if (node->name.value == L"i" || node->name.value == L"i-")
{
auto run = Ptr(new DocumentStylePropertiesRun);
run->style = Ptr(new DocumentStyleProperties);
run->style->italic = node->name.value == L"i";
container->runs.Add(run);
createdContainer = run;
}
else if (node->name.value == L"u" || node->name.value == L"u-")
{
auto run = Ptr(new DocumentStylePropertiesRun);
run->style = Ptr(new DocumentStyleProperties);
run->style->underline = node->name.value == L"u";
container->runs.Add(run);
createdContainer = run;
}
else if (node->name.value == L"s" || node->name.value == L"s-")
{
auto run = Ptr(new DocumentStylePropertiesRun);
run->style = Ptr(new DocumentStyleProperties);
run->style->strikeline = node->name.value == L"s";
container->runs.Add(run);
createdContainer = run;
}
else if (node->name.value == L"ha")
{
auto run = Ptr(new DocumentStylePropertiesRun);
run->style = Ptr(new DocumentStyleProperties);
run->style->antialias = true;
run->style->verticalAntialias = false;
container->runs.Add(run);
createdContainer = run;
}
else if (node->name.value == L"va")
{
auto run = Ptr(new DocumentStylePropertiesRun);
run->style = Ptr(new DocumentStyleProperties);
run->style->antialias = true;
run->style->verticalAntialias = true;
container->runs.Add(run);
createdContainer = run;
}
else if (node->name.value == L"na")
{
auto run = Ptr(new DocumentStylePropertiesRun);
run->style = Ptr(new DocumentStyleProperties);
run->style->antialias = false;
run->style->verticalAntialias = false;
container->runs.Add(run);
createdContainer = run;
}
else if (node->name.value == L"div")
{
if (Ptr<XmlAttribute> att = XmlGetAttribute(node, L"style"))
{
WString styleName = att->value.value;
auto run = Ptr(new DocumentStyleApplicationRun);
run->styleName = styleName;
container->runs.Add(run);
createdContainer = run;
}
else
{
createdContainer = container;
}
}
else if (node->name.value == L"a")
{
auto run = Ptr(new DocumentHyperlinkRun);
run->normalStyleName = L"#NormalLink";
run->activeStyleName = L"#ActiveLink";
if (Ptr<XmlAttribute> att = XmlGetAttribute(node, L"normal"))
{
run->normalStyleName = att->value.value;
}
if (Ptr<XmlAttribute> att = XmlGetAttribute(node, L"active"))
{
run->activeStyleName = att->value.value;
}
if (Ptr<XmlAttribute> att = XmlGetAttribute(node, L"href"))
{
run->reference = att->value.value;
}
run->styleName = run->normalStyleName;
container->runs.Add(run);
createdContainer = run;
}
else if (node->name.value == L"p")
{
for (auto sub : node->subNodes)
{
sub->Accept(this);
}
}
else
{
if (node->name.value != L"nop")
{
errors.Add(GuiResourceError({ {resource},node->codeRange.start }, L"Unknown element in <p>: \"" + node->name.value + L"\"."));
}
for (auto sub : node->subNodes)
{
sub->Accept(this);
}
}
if (createdContainer)
{
Ptr<DocumentContainerRun> oldContainer = container;
container = createdContainer;
for (auto subNode : subNodeContainer->subNodes)
{
subNode->Accept(this);
}
container = oldContainer;
}
}
void Visit(XmlInstruction* node)override
{
}
void Visit(XmlDocument* node)override
{
}
};
Ptr<DocumentStyle> ParseDocumentStyle(Ptr<GuiResourceItem> resource, Ptr<XmlElement> styleElement, GuiResourceError::List& errors)
{
auto style = Ptr(new DocumentStyle);
if(Ptr<XmlAttribute> parent=XmlGetAttribute(styleElement, L"parent"))
{
style->parentStyleName=parent->value.value;
}
auto sp = Ptr(new DocumentStyleProperties);
style->styles=sp;
for (auto att : XmlGetElements(styleElement))
{
if(att->name.value==L"face")
{
sp->face=XmlGetValue(att);
}
else if(att->name.value==L"size")
{
sp->size=DocumentFontSize::Parse(XmlGetValue(att));
}
else if(att->name.value==L"color")
{
sp->color=Color::Parse(XmlGetValue(att));
}
else if(att->name.value==L"bkcolor")
{
sp->backgroundColor=Color::Parse(XmlGetValue(att));
}
else if(att->name.value==L"b")
{
sp->bold=XmlGetValue(att)==L"true";
}
else if(att->name.value==L"i")
{
sp->italic=XmlGetValue(att)==L"true";
}
else if(att->name.value==L"u")
{
sp->underline=XmlGetValue(att)==L"true";
}
else if(att->name.value==L"s")
{
sp->strikeline=XmlGetValue(att)==L"true";
}
else if(att->name.value==L"antialias")
{
WString value=XmlGetValue(att);
if(value==L"horizontal" || value==L"default")
{
sp->antialias=true;
sp->verticalAntialias=false;
}
else if(value==L"no")
{
sp->antialias=false;
sp->verticalAntialias=false;
}
else if(value==L"vertical")
{
sp->antialias=true;
sp->verticalAntialias=true;
}
}
else
{
errors.Add(GuiResourceError({ {resource},att->codeRange.start }, L"Unknown element in <Style>: \"" + att->name.value + L"\"."));
}
}
return style;
}
}
using namespace document_operation_visitors;
/***********************************************************************
DocumentModel
***********************************************************************/
Ptr<DocumentModel> DocumentModel::LoadFromXml(Ptr<GuiResourceItem> resource, Ptr<glr::xml::XmlDocument> xml, Ptr<GuiResourcePathResolver> resolver, GuiResourceError::List& errors)
{
auto model = Ptr(new DocumentModel);
if (xml->rootElement->name.value == L"Doc")
{
for (auto partElement : XmlGetElements(xml->rootElement))
{
if (partElement->name.value == L"Styles")
{
for (auto styleElement : XmlGetElements(partElement))
{
if (styleElement->name.value == L"Style")
{
if (Ptr<XmlAttribute> name = XmlGetAttribute(styleElement, L"name"))
{
auto style = ParseDocumentStyle(resource, styleElement, errors);
auto styleName = name->value.value;
if (!model->styles.Keys().Contains(styleName))
{
model->styles.Add(styleName, style);
if (styleName.Length() > 9 && styleName.Right(9) == L"-Override")
{
auto overridedStyle = Ptr(new DocumentStyle);
overridedStyle->styles = Ptr(new DocumentStyleProperties);
MergeStyle(overridedStyle->styles, style->styles);
styleName = styleName.Left(styleName.Length() - 9);
auto index = model->styles.Keys().IndexOf(styleName);
if (index == -1)
{
model->styles.Add(styleName, overridedStyle);
}
else
{
auto originalStyle = model->styles.Values()[index];
MergeStyle(overridedStyle->styles, originalStyle->styles);
originalStyle->styles = overridedStyle->styles;
}
}
}
}
else
{
errors.Add(GuiResourceError({ {resource},styleElement->codeRange.start }, L"Attribute \"name\" is missing in <Style>."));
}
}
else
{
errors.Add(GuiResourceError({ {resource},styleElement->codeRange.start }, L"Unknown element in <Styles>: \"" + styleElement->name.value + L"\"."));
}
}
}
else if (partElement->name.value == L"Content")
{
for (auto [p, i] : indexed(XmlGetElements(partElement)))
{
if (p->name.value == L"p")
{
auto paragraph = Ptr(new DocumentParagraphRun);
if (Ptr<XmlAttribute> att = XmlGetAttribute(p, L"align"))
{
if (att->value.value == L"Left")
{
paragraph->alignment = Alignment::Left;
}
else if (att->value.value == L"Center")
{
paragraph->alignment = Alignment::Center;
}
else if (att->value.value == L"Right")
{
paragraph->alignment = Alignment::Right;
}
else
{
errors.Add(GuiResourceError({ {resource},att->value.codeRange.start }, L"Unknown value in align attribute \"" + att->value.value + L"\"."));
}
}
model->paragraphs.Add(paragraph);
DeserializeNodeVisitor visitor(model, paragraph, i, resource, resolver, errors);
p->Accept(&visitor);
}
else
{
errors.Add(GuiResourceError({ {resource},p->codeRange.start }, L"Unknown element in <Content>: \"" + p->name.value + L"\"."));
}
}
}
else
{
errors.Add(GuiResourceError({ {resource},partElement->codeRange.start }, L"Unknown element in <Doc>: \"" + partElement->name.value + L"\"."));
}
}
}
else
{
errors.Add(GuiResourceError({ {resource},xml->rootElement->codeRange.start }, L"The root element of document should be \"Doc\"."));
}
return model;
}
}
}
/***********************************************************************
.\RESOURCES\GUIDOCUMENT_SAVE.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace glr::xml;
/***********************************************************************
document_operation_visitors::SerializeRunVisitor
***********************************************************************/
namespace document_operation_visitors
{
class SerializeRunVisitor : public Object, public DocumentRun::IVisitor
{
protected:
Ptr<XmlElement> parent;
public:
SerializeRunVisitor(Ptr<XmlElement> _parent)
:parent(_parent)
{
}
void VisitContainer(Ptr<XmlElement> replacedParent, DocumentContainerRun* run)
{
if (replacedParent)
{
parent->subNodes.Add(replacedParent);
Ptr<XmlElement> oldParent = parent;
parent = replacedParent;
for (auto subRun : run->runs)
{
subRun->Accept(this);
}
parent = oldParent;
}
else
{
for (auto subRun : run->runs)
{
subRun->Accept(this);
}
}
}
void Visit(DocumentTextRun* run)override
{
if (run->text != L"")
{
auto writer = XmlElementWriter(parent).Element(L"nop");
auto begin = run->text.Buffer();
auto reading = begin;
auto last = reading;
while (true)
{
const wchar_t* tag = nullptr;
auto c = *reading;
switch (c)
{
case L'\n':
tag = L"br";
break;
case L' ':
tag = L"sp";
break;
case L'\t':
tag = L"tab";
break;
}
if (tag || c == 0)
{
if (reading > last)
{
auto end = reading[-1] == L'\r' ? reading - 1 : reading;
if (end > last)
{
writer.Text(run->text.Sub(last - begin, end - last));
}
last = reading;
}
}
if (tag)
{
writer.Element(tag);
}
else if (c == 0)
{
break;
}
reading++;
}
}
}
void Visit(DocumentStylePropertiesRun* run)override
{
Ptr<DocumentStyleProperties> sp = run->style;
Ptr<XmlElement> oldParent = parent;
if (sp->face || sp->size || sp->color)
{
auto element = Ptr(new XmlElement);
element->name.value = L"font";
parent->subNodes.Add(element);
XmlElementWriter writer(element);
if (sp->face)
{
writer.Attribute(L"face", sp->face.Value());
}
if (sp->size)
{
writer.Attribute(L"size", sp->size.Value().ToString());
}
if (sp->color)
{
writer.Attribute(L"color", sp->color.Value().ToString());
}
if (sp->backgroundColor)
{
writer.Attribute(L"bkcolor", sp->backgroundColor.Value().ToString());
}
parent = element;
}
if (sp->bold)
{
auto element = Ptr(new XmlElement);
element->name.value = sp->bold.Value() ? L"b" : L"b-";
parent->subNodes.Add(element);
parent = element;
}
if (sp->italic)
{
auto element = Ptr(new XmlElement);
element->name.value = sp->italic.Value() ? L"i" : L"i-";
parent->subNodes.Add(element);
parent = element;
}
if (sp->underline)
{
auto element = Ptr(new XmlElement);
element->name.value = sp->underline.Value() ? L"u" : L"u-";
parent->subNodes.Add(element);
parent = element;
}
if (sp->strikeline)
{
auto element = Ptr(new XmlElement);
element->name.value = sp->strikeline.Value() ? L"s" : L"s-";
parent->subNodes.Add(element);
parent = element;
}
if (sp->antialias || sp->verticalAntialias)
{
bool ha = sp->antialias ? sp->antialias.Value() : true;
bool va = sp->verticalAntialias ? sp->verticalAntialias.Value() : false;
if (!ha)
{
auto element = Ptr(new XmlElement);
element->name.value = L"ha";
parent->subNodes.Add(element);
parent = element;
}
else if (!va)
{
auto element = Ptr(new XmlElement);
element->name.value = L"va";
parent->subNodes.Add(element);
parent = element;
}
else
{
auto element = Ptr(new XmlElement);
element->name.value = L"na";
parent->subNodes.Add(element);
parent = element;
}
}
VisitContainer(0, run);
parent = oldParent;
}
void Visit(DocumentStyleApplicationRun* run)override
{
auto element = Ptr(new XmlElement);
element->name.value = L"div";
XmlElementWriter(element).Attribute(L"style", run->styleName);
VisitContainer(element, run);
}
void Visit(DocumentHyperlinkRun* run)override
{
auto element = Ptr(new XmlElement);
element->name.value = L"a";
XmlElementWriter writer(element);
if (run->normalStyleName != L"#NormalLink")
{
writer.Attribute(L"normal", run->normalStyleName);
}
if (run->activeStyleName != L"#ActiveLink")
{
writer.Attribute(L"active", run->activeStyleName);
}
if (run->reference != L"")
{
writer.Attribute(L"href", run->reference);
}
VisitContainer(element, run);
}
void Visit(DocumentImageRun* run)override
{
XmlElementWriter writer(parent);
writer
.Element(L"img")
.Attribute(L"width", itow(run->size.x))
.Attribute(L"height", itow(run->size.y))
.Attribute(L"baseline", itow(run->baseline))
.Attribute(L"frameIndex", itow(run->frameIndex))
.Attribute(L"source", run->source)
;
}
void Visit(DocumentEmbeddedObjectRun* run)override
{
XmlElementWriter writer(parent);
writer
.Element(L"object")
.Attribute(L"name", run->name)
;
}
void Visit(DocumentParagraphRun* run)override
{
auto element = Ptr(new XmlElement);
element->name.value = L"p";
XmlElementWriter writer(element);
if (run->alignment)
{
switch (run->alignment.Value())
{
case Alignment::Left:
writer.Attribute(L"align", L"Left");
break;
case Alignment::Center:
writer.Attribute(L"align", L"Center");
break;
case Alignment::Right:
writer.Attribute(L"align", L"Right");
break;
}
}
VisitContainer(element, run);
}
};
}
using namespace document_operation_visitors;
/***********************************************************************
DocumentModel
***********************************************************************/
Ptr<glr::xml::XmlDocument> DocumentModel::SaveToXml()
{
auto xml = Ptr(new XmlDocument);
auto doc = Ptr(new XmlElement);
doc->name.value=L"Doc";
xml->rootElement=doc;
{
auto content = Ptr(new XmlElement);
content->name.value=L"Content";
doc->subNodes.Add(content);
for (auto p : paragraphs)
{
SerializeRunVisitor visitor(content);
p->Accept(&visitor);
}
}
{
auto stylesElement = Ptr(new XmlElement);
stylesElement->name.value=L"Styles";
doc->subNodes.Add(stylesElement);
// TODO: (enumerable) foreach
for(vint i=0;i<styles.Count();i++)
{
WString name=styles.Keys()[i];
if (name.Length()>0 && name[0] == L'#' && (name.Length() <= 9 || name.Right(9) != L"-Override")) continue;
Ptr<DocumentStyle> style=styles.Values().Get(i);
Ptr<DocumentStyleProperties> sp=style->styles;
auto styleElement = Ptr(new XmlElement);
styleElement->name.value=L"Style";
stylesElement->subNodes.Add(styleElement);
XmlElementWriter(styleElement).Attribute(L"name", name);
if(style->parentStyleName!=L"")
{
XmlElementWriter(styleElement).Attribute(L"parent", style->parentStyleName);
}
if(sp->face) XmlElementWriter(styleElement).Element(L"face").Text( sp->face.Value() );
if(sp->size) XmlElementWriter(styleElement).Element(L"size").Text( sp->size.Value().ToString() );
if(sp->color) XmlElementWriter(styleElement).Element(L"color").Text( sp->color.Value().ToString() );
if(sp->backgroundColor) XmlElementWriter(styleElement).Element(L"bkcolor").Text( sp->backgroundColor.Value().ToString() );
if(sp->bold) XmlElementWriter(styleElement).Element(L"b").Text( sp->bold.Value()?L"true":L"false" );
if(sp->italic) XmlElementWriter(styleElement).Element(L"i").Text( sp->italic.Value()?L"true":L"false" );
if(sp->underline) XmlElementWriter(styleElement).Element(L"u").Text( sp->underline.Value()?L"true":L"false" );
if(sp->strikeline) XmlElementWriter(styleElement).Element(L"s").Text( sp->strikeline.Value()?L"true":L"false" );
if(sp->antialias && sp->verticalAntialias)
{
bool h=sp->antialias;
bool v=sp->verticalAntialias;
if(!h)
{
XmlElementWriter(styleElement).Element(L"antialias").Text(L"no");
}
else if(!v)
{
XmlElementWriter(styleElement).Element(L"antialias").Text(L"horizontal");
}
else
{
XmlElementWriter(styleElement).Element(L"antialias").Text(L"vertical");
}
}
}
}
return xml;
}
}
}
/***********************************************************************
.\RESOURCES\GUIPARSERMANAGER.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace glr::xml;
using namespace glr::json;
using namespace regex;
/***********************************************************************
IGuiParserManager
***********************************************************************/
IGuiParserManager* parserManager=0;
IGuiParserManager* GetParserManager()
{
return parserManager;
}
class GuiParser_Xml : public IGuiParser<XmlDocument>
{
protected:
glr::xml::Parser parser;
public:
Ptr<XmlDocument> ParseInternal(const WString& text, List<glr::ParsingError>& errors) override
{
auto handler = glr::InstallDefaultErrorMessageGenerator(parser, errors);
auto ast = XmlParseDocument(text, parser);
parser.OnError.Remove(handler);
return ast;
}
};
class GuiParser_Json : public IGuiParser<JsonNode>
{
protected:
glr::json::Parser parser;
public:
Ptr<JsonNode> ParseInternal(const WString& text, List<glr::ParsingError>& errors) override
{
auto handler = glr::InstallDefaultErrorMessageGenerator(parser, errors);
auto ast = JsonParse(text, parser);
parser.OnError.Remove(handler);
return ast;
}
};
class GuiParserManager : public Object, public IGuiParserManager, public IGuiPlugin
{
protected:
SpinLock lock;
Dictionary<WString, Ptr<IGuiGeneralParser>> parsers;
public:
GUI_PLUGIN_NAME(GacUI_Parser)
{
}
void Load(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override
{
if (controllerUnrelatedPlugins)
{
parserManager = this;
SetParser(L"XML", Ptr(new GuiParser_Xml()));
SetParser(L"JSON", Ptr(new GuiParser_Json()));
}
}
void Unload(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override
{
if (controllerUnrelatedPlugins)
{
parserManager = nullptr;
}
}
Ptr<IGuiGeneralParser> GetParser(const WString& name)override
{
vint index=parsers.Keys().IndexOf(name);
return index == -1 ? nullptr : parsers.Values()[index];
}
bool SetParser(const WString& name, Ptr<IGuiGeneralParser> parser)override
{
if(parsers.Keys().Contains(name)) return false;
parsers.Add(name, parser);
return true;
}
};
GUI_REGISTER_PLUGIN(GuiParserManager)
}
}
/***********************************************************************
.\RESOURCES\GUIPLUGINMANAGER.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
/***********************************************************************
GuiPluginManager
***********************************************************************/
class GuiPluginManager : public Object, public IGuiPluginManager
{
protected:
List<Ptr<IGuiPlugin>> plugins;
bool controllerRelatedLoaded = false;
bool controllerUnrelatedLoaded = false;
public:
GuiPluginManager()
{
}
~GuiPluginManager()
{
}
void AddPlugin(Ptr<IGuiPlugin> plugin)override
{
#define ERROR_MESSAGE_PREFIX L"GuiPluginManager::AddPlugin(Ptr<IGuiPlugin>)#"
CHECK_ERROR(!controllerUnrelatedLoaded, ERROR_MESSAGE_PREFIX L"Load function has already been executed.");
auto name = plugin->GetName();
if (name != L"")
{
for (auto plugin : plugins)
{
CHECK_ERROR(plugin->GetName() != name, ERROR_MESSAGE_PREFIX L"Duplicated plugin name.");
}
}
plugins.Add(plugin);
#undef ERROR_MESSAGE_PREFIX
}
void Load(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override
{
#define ERROR_MESSAGE_PREFIX L"GuiPluginManager::Load(bool, bool)#"
CHECK_ERROR(controllerUnrelatedPlugins || controllerRelatedPlugins, L"At least one of the parameters should be true.");
if (controllerUnrelatedPlugins)
{
CHECK_ERROR(!controllerUnrelatedLoaded, ERROR_MESSAGE_PREFIX L"A second Load(true, *) could only be called after Unload(true, *).");
controllerUnrelatedLoaded = true;
}
if (controllerRelatedPlugins)
{
CHECK_ERROR(controllerUnrelatedLoaded, ERROR_MESSAGE_PREFIX L"Load(*, true) could only be called between Load(true, *) and Unload(true, *).");
CHECK_ERROR(!controllerRelatedLoaded, ERROR_MESSAGE_PREFIX L"A second Load(*, true) could only be called after Unload(*, true).");
controllerRelatedLoaded = true;
}
SortedList<WString> loaded;
Group<WString, WString> loading;
Dictionary<WString, Ptr<IGuiPlugin>> pluginsToLoad;
for (auto plugin : plugins)
{
auto name = plugin->GetName();
pluginsToLoad.Add(name, plugin);
List<WString> dependencies;
plugin->GetDependencies(dependencies);
for (auto dependency : dependencies)
{
loading.Add(name, dependency);
}
}
while (pluginsToLoad.Count() > 0)
{
vint count = pluginsToLoad.Count();
{
// TODO: (enumerable) foreach:alterable(reversed) on dictionary
for (auto [name, index] : indexed(pluginsToLoad.Keys()))
{
if (!loading.Keys().Contains(name))
{
// TODO: (enumerable) foreach:alterable(reversed) on group
for (vint i = loading.Count() - 1; i >= 0; i--)
{
loading.Remove(loading.Keys()[i], name);
}
loaded.Add(name);
auto plugin = pluginsToLoad.Values()[index];
pluginsToLoad.Remove(name);
plugin->Load(controllerUnrelatedPlugins, controllerRelatedPlugins);
break;
}
}
}
if (count == pluginsToLoad.Count())
{
WString message;
for (auto plugin : pluginsToLoad.Values())
{
message += L"Cannot load plugin \"" + plugin->GetName() + L"\" because part of its dependencies are not ready:";
List<WString> dependencies;
plugin->GetDependencies(dependencies);
bool first = true;
for (auto dependency : dependencies)
{
if (!loaded.Contains(dependency))
{
message += L" \"" + dependency + L"\";";
}
}
message += L"\r\n";
}
throw Exception(message);
}
}
#undef ERROR_MESSAGE_PREFIX
}
void Unload(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override
{
#define ERROR_MESSAGE_PREFIX L"GuiPluginManager::Unload(bool, bool)#"
CHECK_ERROR(controllerUnrelatedPlugins || controllerRelatedPlugins, L"At least one of the parameters should be true.");
if (controllerRelatedPlugins)
{
CHECK_ERROR(controllerUnrelatedLoaded, ERROR_MESSAGE_PREFIX L"Unload(*, true) could only be called between Load(true, *) and Unload(true, *).");
CHECK_ERROR(controllerRelatedLoaded, ERROR_MESSAGE_PREFIX L"Unload(*, true) could only be called after Load(*, true).");
controllerRelatedLoaded = false;
}
if (controllerUnrelatedPlugins)
{
CHECK_ERROR(controllerUnrelatedLoaded, ERROR_MESSAGE_PREFIX L"Unload(true, *) could only be called after Load(true, *).");
CHECK_ERROR(!controllerRelatedLoaded, ERROR_MESSAGE_PREFIX L"Unload(true, *) could only be called after Load(*, true).");
controllerUnrelatedLoaded = false;
}
for (auto plugin : plugins)
{
plugin->Unload(controllerUnrelatedPlugins, controllerRelatedPlugins);
}
#undef ERROR_MESSAGE_PREFIX
}
bool IsControllerRelatedPluginsLoaded()override
{
return controllerRelatedLoaded;
}
bool IsControllerUnrelatedPluginsLoaded()override
{
return controllerUnrelatedLoaded;
}
};
/***********************************************************************
Helpers
***********************************************************************/
GuiPluginDescriptor* firstPluginDescriptor = nullptr;
GuiPluginDescriptor** lastPluginDescriptor = &firstPluginDescriptor;
IGuiPluginManager* pluginManager = nullptr;
IGuiPluginManager* GetPluginManager()
{
if (!pluginManager)
{
pluginManager = new GuiPluginManager;
auto current = firstPluginDescriptor;
while (current)
{
pluginManager->AddPlugin(current->CreatePlugin());
current = current->next;
}
}
return pluginManager;
}
void RegisterPluginDescriptor(GuiPluginDescriptor* pluginDescriptor)
{
CHECK_ERROR(!pluginManager, L"vl::presentation::RegisterPluginDescriptor(GuiPluginDescriptor*)#This function should be called before calling GetPluginManager.");
*lastPluginDescriptor = pluginDescriptor;
lastPluginDescriptor = &pluginDescriptor->next;
}
void DestroyPluginManager()
{
if (pluginManager)
{
CHECK_ERROR(
!pluginManager->IsControllerRelatedPluginsLoaded() && !pluginManager->IsControllerUnrelatedPluginsLoaded(),
L"vl::presentation::DestroyPluginManager()#Plugins have not been unloaded.");
delete pluginManager;
pluginManager = nullptr;
}
}
}
}
/***********************************************************************
.\RESOURCES\GUIRESOURCE.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace glr::xml;
using namespace stream;
using namespace filesystem;
WString GetFolderPath(const WString& filePath)
{
auto path = FilePath(filePath).GetFolder().GetFullPath();
if (path != L"")
{
if (path[path.Length() - 1] != FilePath::Delimiter)
{
path += WString::FromChar(FilePath::Delimiter);
}
}
return path;
}
WString GetFileName(const WString& filePath)
{
return FilePath(filePath).GetName();
}
bool LoadTextFile(const WString& filePath, WString& text)
{
BomEncoder::Encoding encoding;
bool bom;
return File(filePath).ReadAllTextWithEncodingTesting(text, encoding, bom);
}
bool IsResourceUrl(const WString& text, WString& protocol, WString& path)
{
Pair<vint, vint> index = INVLOC.FindFirst(text, L"://", Locale::None);
if (index.key != -1)
{
protocol = INVLOC.ToLower(text.Sub(0, index.key));
path = text.Sub(index.key + index.value, text.Length() - index.key - index.value);
return true;
}
else
{
return false;
}
}
vint HexToInt(wchar_t c)
{
if (L'0' <= c && c <= L'9')
{
return c - L'0';
}
else if (L'A' <= c && c <= L'F')
{
return c - L'A' + 10;
}
else
{
return 0;
}
}
void HexToBinary(stream::IStream& binaryStream, const WString& hexText)
{
const wchar_t* buffer = hexText.Buffer();
vint count = hexText.Length() / 2;
for (vint i = 0; i < count; i++)
{
vuint8_t byte = (vuint8_t)(HexToInt(buffer[0]) * 16 + HexToInt(buffer[1]));
buffer += 2;
binaryStream.Write(&byte, 1);
}
}
WString BinaryToHex(stream::IStream& binaryStream)
{
stream::MemoryStream memoryStream;
{
stream::StreamWriter writer(memoryStream);
vuint8_t byte;
while (binaryStream.Read(&byte, 1) == 1)
{
writer.WriteChar(L"0123456789ABCDEF"[byte / 16]);
writer.WriteChar(L"0123456789ABCDEF"[byte % 16]);
}
}
memoryStream.SeekFromBegin(0);
{
stream::StreamReader reader(memoryStream);
return reader.ReadToEnd();
}
}
/***********************************************************************
GlobalStringKey
***********************************************************************/
GlobalStringKey GlobalStringKey::Empty;
GlobalStringKey GlobalStringKey::_InferType;
GlobalStringKey GlobalStringKey::_Set;
GlobalStringKey GlobalStringKey::_Ref;
GlobalStringKey GlobalStringKey::_Bind;
GlobalStringKey GlobalStringKey::_Format;
GlobalStringKey GlobalStringKey::_Str;
GlobalStringKey GlobalStringKey::_Eval;
GlobalStringKey GlobalStringKey::_Uri;
GlobalStringKey GlobalStringKey::_ControlTemplate;
class GlobalStringKeyManager
{
public:
Dictionary<WString, vint> stoi;
List<WString> itos;
void InitializeConstants()
{
GlobalStringKey::_Set = GlobalStringKey::Get(L"set");
GlobalStringKey::_InferType = GlobalStringKey::Get(L"_");
GlobalStringKey::_Ref = GlobalStringKey::Get(L"ref");
GlobalStringKey::_Bind = GlobalStringKey::Get(L"bind");
GlobalStringKey::_Format = GlobalStringKey::Get(L"format");
GlobalStringKey::_Str = GlobalStringKey::Get(L"str");
GlobalStringKey::_Eval = GlobalStringKey::Get(L"eval");
GlobalStringKey::_Uri = GlobalStringKey::Get(L"uri");
GlobalStringKey::_ControlTemplate = GlobalStringKey::Get(L"ControlTemplate");
}
}*globalStringKeyManager = 0;
GlobalStringKey GlobalStringKey::Get(const WString& string)
{
GlobalStringKey key;
if (string != L"")
{
vint index = globalStringKeyManager->stoi.Keys().IndexOf(string);
if (index == -1)
{
key.key = globalStringKeyManager->itos.Add(string);
globalStringKeyManager->stoi.Add(string, key.key);
}
else
{
key.key = globalStringKeyManager->stoi.Values()[index];
}
}
return key;
}
vint GlobalStringKey::ToKey()const
{
return key;
}
WString GlobalStringKey::ToString()const
{
return *this == GlobalStringKey::Empty
? L""
: globalStringKeyManager->itos[key];
}
/***********************************************************************
GuiImageData
***********************************************************************/
GuiImageData::GuiImageData()
:frameIndex(-1)
{
}
GuiImageData::GuiImageData(Ptr<INativeImage> _image, vint _frameIndex)
: image(_image)
, frameIndex(_frameIndex)
{
}
GuiImageData::~GuiImageData()
{
}
Ptr<INativeImage> GuiImageData::GetImage()
{
return image;
}
vint GuiImageData::GetFrameIndex()
{
return frameIndex;
}
/***********************************************************************
GuiTextData
***********************************************************************/
GuiTextData::GuiTextData()
{
}
GuiTextData::GuiTextData(const WString& _text)
:text(_text)
{
}
WString GuiTextData::GetText()
{
return text;
}
/***********************************************************************
GuiResourceNodeBase
***********************************************************************/
GuiResourceNodeBase::GuiResourceNodeBase()
:parent(0)
{
}
GuiResourceNodeBase::~GuiResourceNodeBase()
{
}
const WString& GuiResourceNodeBase::GetName()
{
return name;
}
WString GuiResourceNodeBase::GetResourcePath()
{
auto resourcePath = name;
auto current = parent;
while (current && current->GetParent())
{
resourcePath = current->GetName() + L"/" + resourcePath;
current = current->GetParent();
}
return resourcePath;
}
const WString& GuiResourceNodeBase::GetFileContentPath()
{
return fileContentPath;
}
const WString& GuiResourceNodeBase::GetFileAbsolutePath()
{
return fileAbsolutePath;
}
void GuiResourceNodeBase::SetFileContentPath(const WString& content, const WString& absolute)
{
fileContentPath = content;
fileAbsolutePath = absolute;
}
GuiResourceFolder* GuiResourceNodeBase::GetParent()
{
return parent;
}
/***********************************************************************
GuiResourceLocation
***********************************************************************/
GuiResourceLocation::GuiResourceLocation(const WString& _resourcePath, const WString& _filePath)
:resourcePath(_resourcePath)
, filePath(_filePath)
{
}
GuiResourceLocation::GuiResourceLocation(Ptr<GuiResourceNodeBase> node)
{
if (node)
{
resourcePath = node->GetResourcePath();
auto current = node.Obj();
while (current)
{
if (current->GetFileContentPath() != L"")
{
filePath = current->GetFileAbsolutePath();
break;
}
current = current->GetParent();
}
}
}
/***********************************************************************
GuiResourceTextPos
***********************************************************************/
GuiResourceTextPos::GuiResourceTextPos(GuiResourceLocation location, glr::ParsingTextPos position)
:originalLocation(location)
, row(position.row)
, column(position.column)
{
}
/***********************************************************************
GuiResourceError
***********************************************************************/
GuiResourceError::GuiResourceError(GuiResourceTextPos _position, const WString& _message)
:location(_position.originalLocation)
, position(_position)
, message(_message)
{
}
GuiResourceError::GuiResourceError(GuiResourceLocation _location, const WString& _message)
:location(_location)
, position(_location, {})
, message(_message)
{
}
GuiResourceError::GuiResourceError(GuiResourceLocation _location, GuiResourceTextPos _position, const WString& _message)
:location(_location)
, position(_position)
, message(_message)
{
}
template<typename TCallback>
void TransformErrors(GuiResourceError::List& errors, collections::List<glr::ParsingError>& parsingErrors, GuiResourceTextPos offset, const TCallback& callback)
{
if (offset.row < 0 || offset.column < 0)
{
offset.row = 0;
offset.column = 0;
}
for (auto error : parsingErrors)
{
auto pos = error.codeRange.start;
if (pos.row < 0 || pos.column < 0)
{
pos = { offset.row,offset.column };
}
else
{
if (pos.row == 0)
{
pos.column += offset.column;
}
pos.row += offset.row;
}
errors.Add(callback({ offset.originalLocation,pos }, error.message));
}
}
void GuiResourceError::Transform(GuiResourceLocation _location, GuiResourceError::List& errors, collections::List<glr::ParsingError>& parsingErrors)
{
Transform(_location, errors, parsingErrors, { _location,{ 0,0 } });
}
void GuiResourceError::Transform(GuiResourceLocation _location, GuiResourceError::List& errors, collections::List<glr::ParsingError>& parsingErrors, glr::ParsingTextPos offset)
{
Transform(_location, errors, parsingErrors, { _location,offset });
}
void GuiResourceError::Transform(GuiResourceLocation _location, GuiResourceError::List& errors, collections::List<glr::ParsingError>& parsingErrors, GuiResourceTextPos offset)
{
TransformErrors(errors, parsingErrors, offset, [&](GuiResourceTextPos pos, const WString& message)
{
return GuiResourceError(_location, pos, message);
});
}
void GuiResourceError::SortAndLog(List& errors, collections::List<WString>& output, const WString& workingDirectory)
{
if (errors.Count() == 0) return;
Sort(&errors[0], errors.Count());
for (vint index = 0; index < errors.Count(); index++)
{
auto& error = errors[index];
bool needHeader = index == 0;
if (index > 0)
{
auto previousError = errors[index - 1];
if (error.location != previousError.location || error.position.originalLocation != previousError.position.originalLocation)
{
needHeader = true;
}
}
#define CONVERT_FILEPATH(FILEPATH) (workingDirectory == L"" ? FILEPATH : filesystem::FilePath(workingDirectory).GetRelativePathFor(FILEPATH))
#define CONVERT_LOCATION(LOCATION) (LOCATION).resourcePath + L" # " + CONVERT_FILEPATH((LOCATION).filePath)
if (needHeader)
{
output.Add(CONVERT_LOCATION(error.location));
if (error.location != error.position.originalLocation)
{
output.Add(L" Original: " + CONVERT_LOCATION(error.position.originalLocation));
}
}
WString prefix = L"Failed to load file \"";
WString postfix = L"\".";
if (INVLOC.StartsWith(error.message, prefix, Locale::Normalization::None) && INVLOC.EndsWith(error.message, postfix, Locale::Normalization::None))
{
auto path = error.message.Sub(prefix.Length(), error.message.Length() - prefix.Length() - postfix.Length());
path = CONVERT_FILEPATH(path);
error.message = prefix + path + postfix;
}
auto row = error.position.row;
if (row >= 0) row++;
auto column = error.position.column;
if (column >= 0) column++;
output.Add(L"(" + itow(row) + L", " + itow(column) + L"): " + error.message);
#undef CONVERT_FILEPATH
#undef CONVERT_LOCATION
}
}
/***********************************************************************
GuiResourceItem
***********************************************************************/
GuiResourceItem::GuiResourceItem()
{
}
GuiResourceItem::~GuiResourceItem()
{
}
const WString& GuiResourceItem::GetTypeName()
{
return typeName;
}
Ptr<DescriptableObject> GuiResourceItem::GetContent()
{
return content;
}
void GuiResourceItem::SetContent(const WString& _typeName, Ptr<DescriptableObject> value)
{
typeName = _typeName;
content = value;
}
Ptr<GuiImageData> GuiResourceItem::AsImage()
{
return content.Cast<GuiImageData>();
}
Ptr<glr::xml::XmlDocument> GuiResourceItem::AsXml()
{
return content.Cast<XmlDocument>();
}
Ptr<GuiTextData> GuiResourceItem::AsString()
{
return content.Cast<GuiTextData>();
}
Ptr<DocumentModel> GuiResourceItem::AsDocument()
{
return content.Cast<DocumentModel>();
}
/***********************************************************************
GuiResourceFolder
***********************************************************************/
void GuiResourceFolder::LoadResourceFolderFromXml(DelayLoadingList& delayLoadings, const WString& containingFolder, Ptr<glr::xml::XmlElement> folderXml, GuiResourceError::List& errors)
{
ClearItems();
ClearFolders();
for (auto element : XmlGetElements(folderXml))
{
WString name;
if (Ptr<XmlAttribute> nameAtt = XmlGetAttribute(element, L"name"))
{
name = nameAtt->value.value;
}
if (element->name.value == L"Folder")
{
if (name == L"")
{
errors.Add(GuiResourceError({ {Ptr(this)},element->codeRange.start }, L"A resource folder should have a name."));
}
else
{
auto folder = Ptr(new GuiResourceFolder);
if (AddFolder(name, folder))
{
WString newContainingFolder = containingFolder;
Ptr<XmlElement> newFolderXml = element;
if (Ptr<XmlAttribute> contentAtt = XmlGetAttribute(element, L"content"))
{
if (contentAtt->value.value == L"Link")
{
auto fileContentPath = XmlGetValue(element);
auto fileAbsolutePath = containingFolder + fileContentPath;
folder->SetFileContentPath(fileContentPath, fileAbsolutePath);
WString text;
if (LoadTextFile(fileAbsolutePath, text))
{
if (auto parser = GetParserManager()->GetParser<XmlDocument>(L"XML"))
{
if (auto xml = parser->Parse({ WString::Empty,fileAbsolutePath }, text, errors))
{
newContainingFolder = GetFolderPath(fileAbsolutePath);
newFolderXml = xml->rootElement;
}
}
}
else
{
errors.Add(GuiResourceError({ {Ptr(this)},element->codeRange.start }, L"Failed to load file \"" + fileAbsolutePath + L"\"."));
}
}
else if (contentAtt->value.value == L"Import")
{
auto importUri = XmlGetValue(element);
folder->ImportFromUri(importUri, { {Ptr(this)},element->codeRange.start }, errors);
}
else
{
errors.Add(GuiResourceError({ {Ptr(this)},element->codeRange.start }, L"Folder's content attributes can only be \"Link\"."));
}
}
if (folder->GetImportUri() == L"")
{
folder->LoadResourceFolderFromXml(delayLoadings, newContainingFolder, newFolderXml, errors);
}
}
else
{
errors.Add(GuiResourceError({ {Ptr(this)},element->codeRange.start }, L"Duplicated resource folder name \"" + name + L"\"."));
}
}
}
else if (element->name.value.Length() <= 3 || element->name.value.Sub(0, 4) != L"ref.")
{
WString fileContentPath;
WString fileAbsolutePath;
if (Ptr<XmlAttribute> contentAtt = XmlGetAttribute(element, L"content"))
{
if (contentAtt->value.value == L"File")
{
fileContentPath = XmlGetValue(element);
fileAbsolutePath = containingFolder + fileContentPath;
if (name == L"")
{
name = GetFileName(fileAbsolutePath);
}
}
else
{
errors.Add(GuiResourceError({ {Ptr(this)},element->codeRange.start }, L"File's content attributes can only be \"File\"."));
}
}
auto item = Ptr(new GuiResourceItem);
if (AddItem(name, item))
{
WString type = element->name.value;
IGuiResourceTypeResolver* typeResolver = GetResourceResolverManager()->GetTypeResolver(type);
IGuiResourceTypeResolver* preloadResolver = typeResolver;
if (typeResolver)
{
if (!typeResolver->DirectLoadXml())
{
WString preloadType = typeResolver->IndirectLoad()->GetPreloadType();
preloadResolver = GetResourceResolverManager()->GetTypeResolver(preloadType);
if (!preloadResolver)
{
errors.Add(GuiResourceError({ {Ptr(this)}, element->codeRange.start }, L"[INTERNAL-ERROR] Unknown resource resolver \"" + preloadType + L"\" of resource type \"" + type + L"\"."));
}
}
}
else
{
errors.Add(GuiResourceError({ {Ptr(this)}, element->codeRange.start }, L"Unknown resource type \"" + type + L"\"."));
}
if (typeResolver && preloadResolver)
{
if (auto directLoad = preloadResolver->DirectLoadXml())
{
{
Ptr<DescriptableObject> resource;
if (fileAbsolutePath == L"")
{
resource = directLoad->ResolveResource(item, element, errors);
}
else
{
item->SetFileContentPath(fileContentPath, fileAbsolutePath);
resource = directLoad->ResolveResource(item, fileAbsolutePath, errors);
}
item->SetContent(preloadResolver->GetType(), resource);
}
if (typeResolver != preloadResolver)
{
if (auto indirectLoad = typeResolver->IndirectLoad())
{
if (indirectLoad->IsDelayLoad())
{
DelayLoading delayLoading;
delayLoading.type = type;
delayLoading.workingDirectory = containingFolder;
delayLoading.preloadResource = item;
delayLoadings.Add(delayLoading);
}
else if (item->GetContent())
{
auto resource = indirectLoad->ResolveResource(item, 0, errors);
item->SetContent(typeResolver->GetType(), resource);
}
}
else
{
item->SetContent(typeResolver->GetType(), nullptr);
errors.Add(GuiResourceError({ {Ptr(this)},element->codeRange.start }, L"[INTERNAL-ERROR] Resource type \"" + typeResolver->GetType() + L"\" is not a indirect load resource type.")); }
}
}
else
{
errors.Add(GuiResourceError({ {Ptr(this)},element->codeRange.start }, L"[INTERNAL-ERROR] Resource type \"" + preloadResolver->GetType() + L"\" is not a direct load resource type."));
}
}
if (!item->GetContent())
{
RemoveItem(name);
}
}
else
{
errors.Add(GuiResourceError({ {Ptr(this)},element->codeRange.start }, L"Duplicated resource item name \"" + name + L"\"."));
}
}
}
}
void GuiResourceFolder::SaveResourceFolderToXml(Ptr<glr::xml::XmlElement> xmlParent)
{
for (auto item : items.Values())
{
auto resolver = GetResourceResolverManager()->GetTypeResolver(item->GetTypeName());
if (resolver->XmlSerializable())
{
auto attName = Ptr(new XmlAttribute);
attName->name.value = L"name";
attName->value.value = item->GetName();
if (item->GetFileContentPath() == L"")
{
Ptr<XmlElement> xmlElement;
if (auto directLoad = resolver->DirectLoadXml())
{
xmlElement = directLoad->Serialize(item, item->GetContent());
}
else if (auto indirectLoad = resolver->IndirectLoad())
{
if (auto preloadResolver = GetResourceResolverManager()->GetTypeResolver(indirectLoad->GetPreloadType()))
{
if (auto directLoad = preloadResolver->DirectLoadXml())
{
if (auto resource = indirectLoad->Serialize(item, item->GetContent()))
{
xmlElement = directLoad->Serialize(item, resource);
xmlElement->name.value = resolver->GetType();
}
}
}
}
if (xmlElement)
{
xmlElement->attributes.Add(attName);
xmlParent->subNodes.Add(xmlElement);
}
}
else
{
auto xmlElement = Ptr(new XmlElement);
xmlElement->name.value = item->GetTypeName();
xmlParent->subNodes.Add(xmlElement);
auto attContent = Ptr(new XmlAttribute);
attContent->name.value = L"content";
attContent->value.value = L"File";
xmlElement->attributes.Add(attContent);
auto xmlText = Ptr(new XmlText);
xmlText->content.value = item->GetFileContentPath();
xmlElement->subNodes.Add(xmlText);
}
}
}
for (auto folder : folders.Values())
{
auto attName = Ptr(new XmlAttribute);
attName->name.value = L"name";
attName->value.value = folder->GetName();
auto xmlFolder = Ptr(new XmlElement);
xmlFolder->name.value = L"Folder";
xmlFolder->attributes.Add(attName);
xmlParent->subNodes.Add(xmlFolder);
if (folder->GetImportUri() != L"")
{
auto attContent = Ptr(new XmlAttribute);
attContent->name.value = L"content";
attContent->value.value = L"Import";
xmlFolder->attributes.Add(attContent);
auto xmlText = Ptr(new XmlText);
xmlText->content.value = folder->GetImportUri();
xmlFolder->subNodes.Add(xmlText);
}
else if (folder->GetFileContentPath() != L"")
{
auto attContent = Ptr(new XmlAttribute);
attContent->name.value = L"content";
attContent->value.value = L"Link";
xmlFolder->attributes.Add(attContent);
auto xmlText = Ptr(new XmlText);
xmlText->content.value = folder->GetFileContentPath();
xmlFolder->subNodes.Add(xmlText);
}
else
{
folder->SaveResourceFolderToXml(xmlFolder);
}
}
}
void GuiResourceFolder::CollectTypeNames(collections::List<WString>& typeNames)
{
if (importUri != L"") return;
for (auto item : items.Values())
{
if (!typeNames.Contains(item->GetTypeName()))
{
typeNames.Add(item->GetTypeName());
}
}
for (auto folder : folders.Values())
{
folder->CollectTypeNames(typeNames);
}
}
void GuiResourceFolder::LoadResourceFolderFromBinary(DelayLoadingList& delayLoadings, stream::internal::ContextFreeReader& reader, collections::List<WString>& typeNames, GuiResourceError::List& errors)
{
vint count = 0;
reader << count;
for (vint i = 0; i < count; i++)
{
vint typeName = 0;
WString name;
reader << typeName << name;
auto resolver = GetResourceResolverManager()->GetTypeResolver(typeNames[typeName]);
auto item = Ptr(new GuiResourceItem);
if(AddItem(name, item))
{
WString type = typeNames[typeName];
IGuiResourceTypeResolver* typeResolver = GetResourceResolverManager()->GetTypeResolver(type);
IGuiResourceTypeResolver* preloadResolver = typeResolver;
if(typeResolver)
{
if (!typeResolver->DirectLoadStream())
{
WString preloadType = typeResolver->IndirectLoad()->GetPreloadType();
if (preloadType != L"")
{
preloadResolver = GetResourceResolverManager()->GetTypeResolver(preloadType);
if (!preloadResolver)
{
errors.Add(GuiResourceError({ item }, L"[INTERNAL-ERROR] Unknown resource resolver \"" + preloadType + L"\" of resource type \"" + type + L"\"."));
}
}
}
}
else
{
errors.Add(GuiResourceError({ item }, L"[BINARY] Unknown resource type \"" + type + L"\"."));
}
if(typeResolver && preloadResolver)
{
if (auto directLoad = preloadResolver->DirectLoadStream())
{
{
auto resource = directLoad->ResolveResourcePrecompiled(item, reader.input, errors);
item->SetContent(preloadResolver->GetType(), resource);
}
if (typeResolver != preloadResolver)
{
if (auto indirectLoad = typeResolver->IndirectLoad())
{
if(indirectLoad->IsDelayLoad())
{
DelayLoading delayLoading;
delayLoading.type = type;
delayLoading.preloadResource = item;
delayLoadings.Add(delayLoading);
}
else if(item->GetContent())
{
auto resource = indirectLoad->ResolveResource(item, nullptr, errors);
item->SetContent(typeResolver->GetType(), resource);
}
}
else
{
item->SetContent(typeResolver->GetType(), nullptr);
errors.Add(GuiResourceError({ item }, L"[INTERNAL-ERROR] Resource type \"" + typeResolver->GetType() + L"\" is not a indirect load resource type."));
}
}
}
else
{
errors.Add(GuiResourceError({ item }, L"[INTERNAL-ERROR] Resource type \"" + preloadResolver->GetType() + L"\" is not a direct load resource type."));
}
}
if(!item->GetContent())
{
RemoveItem(name);
}
}
else
{
errors.Add(GuiResourceError({Ptr(this)}, L"[BINARY] Duplicated resource item name \"" + name + L"\"."));
}
}
reader << count;
for (vint i = 0; i < count; i++)
{
WString name, importUri;
reader << name << importUri;
auto folder = Ptr(new GuiResourceFolder);
if (importUri == L"")
{
folder->LoadResourceFolderFromBinary(delayLoadings, reader, typeNames, errors);
}
else
{
folder->ImportFromUri(importUri, { {Ptr(this)},{0,0} }, errors);
}
AddFolder(name, folder);
}
}
void GuiResourceFolder::SaveResourceFolderToBinary(stream::internal::ContextFreeWriter& writer, collections::List<WString>& typeNames)
{
typedef Tuple<vint, WString, IGuiResourceTypeResolver_DirectLoadStream*, Ptr<GuiResourceItem>, Ptr<DescriptableObject>> ItemTuple;
List<ItemTuple> itemTuples;
for (auto item : items.Values())
{
auto resolver = GetResourceResolverManager()->GetTypeResolver(item->GetTypeName());
if (resolver->StreamSerializable())
{
vint typeName = typeNames.IndexOf(item->GetTypeName());
WString name = item->GetName();
if (auto directLoad = resolver->DirectLoadStream())
{
itemTuples.Add(ItemTuple(typeName, name, directLoad, item, item->GetContent()));
}
else if (auto indirectLoad = resolver->IndirectLoad())
{
if (auto preloadResolver = GetResourceResolverManager()->GetTypeResolver(indirectLoad->GetPreloadType()))
{
if (auto directLoad = preloadResolver->DirectLoadStream())
{
if (auto resource = indirectLoad->Serialize(item, item->GetContent()))
{
itemTuples.Add(ItemTuple(typeName, name, directLoad, item, resource));
}
}
}
}
}
}
vint count = itemTuples.Count();
writer << count;
for (auto [typeName, name, directLoad, resource, content] : itemTuples)
{
writer << typeName << name;
directLoad->SerializePrecompiled(resource, content, writer.output);
}
count = folders.Count();
writer << count;
for (auto folder : folders.Values())
{
WString name = folder->GetName();
WString importUri = folder->GetImportUri();
writer << name << importUri;
if (importUri == L"")
{
folder->SaveResourceFolderToBinary(writer, typeNames);
}
}
}
void GuiResourceFolder::PrecompileResourceFolder(GuiResourcePrecompileContext& context, IGuiResourcePrecompileCallback* callback, GuiResourceError::List& errors)
{
if (importUri != L"") return;
for (auto item : items.Values())
{
auto typeResolver = GetResourceResolverManager()->GetTypeResolver(item->GetTypeName());
if (auto precompile = typeResolver->Precompile())
{
if (precompile->GetPrecompilePassSupport(context.passIndex) == IGuiResourceTypeResolver_Precompile::PerResource)
{
if (callback)
{
callback->OnPerResource(context.passIndex, item);
}
precompile->PerResourcePrecompile(item, context, errors);
}
}
}
for (auto folder : folders.Values())
{
folder->PrecompileResourceFolder(context, callback, errors);
}
}
void GuiResourceFolder::InitializeResourceFolder(GuiResourceInitializeContext& context, GuiResourceError::List& errors)
{
if (importUri != L"") return;
for (auto item : items.Values())
{
auto typeResolver = GetResourceResolverManager()->GetTypeResolver(item->GetTypeName());
if (auto initialize = typeResolver->Initialize())
{
if (initialize->GetInitializePassSupport(context.passIndex))
{
initialize->Initialize(item, context, errors);
}
}
}
for (auto folder : folders.Values())
{
folder->InitializeResourceFolder(context, errors);
}
}
void GuiResourceFolder::ImportFromUri(const WString& uri, GuiResourceTextPos position, GuiResourceError::List& errors)
{
SetImportUri(uri);
if (importUri.Length() == 0 || importUri[importUri.Length() - 1] != L'/')
{
errors.Add(GuiResourceError(position, L"Path of imported folder should ends with L\"/\"."));
}
else
{
WString protocol, path;
if (IsResourceUrl(importUri, protocol, path))
{
if (protocol == L"import-res")
{
auto factory = GetResourceResolverManager()->GetPathResolverFactory(protocol);
auto resolver = factory->CreateResolver(nullptr, L"");
if (auto sourceFolder = resolver->ResolveResource(path).Cast<GuiResourceFolder>())
{
CopyFrom(items, sourceFolder->items);
CopyFrom(folders, sourceFolder->folders);
}
else
{
errors.Add(GuiResourceError(position, L"Path of imported folder does not exist: \"" + importUri + L"\"."));
}
}
else
{
errors.Add(GuiResourceError(position, L"Path of imported folder should begin with \"import-res://\"."));
}
}
else
{
errors.Add(GuiResourceError(position, L"Invalid path of imported folder : \"" + importUri + L"\"."));
}
}
}
GuiResourceFolder::GuiResourceFolder()
{
}
GuiResourceFolder::~GuiResourceFolder()
{
}
const WString& GuiResourceFolder::GetImportUri()
{
return importUri;
}
void GuiResourceFolder::SetImportUri(const WString& uri)
{
importUri = uri;
}
const GuiResourceFolder::ItemList& GuiResourceFolder::GetItems()
{
return items.Values();
}
Ptr<GuiResourceItem> GuiResourceFolder::GetItem(const WString& name)
{
vint index=items.Keys().IndexOf(name);
return index == -1 ? nullptr : items.Values().Get(index);
}
bool GuiResourceFolder::AddItem(const WString& name, Ptr<GuiResourceItem> item)
{
if (item->GetParent() != 0 || items.Keys().Contains(name)) return false;
items.Add(name, item);
item->parent = this;
item->name = name;
return true;
}
Ptr<GuiResourceItem> GuiResourceFolder::RemoveItem(const WString& name)
{
Ptr<GuiResourceItem> item = GetItem(name);
if (!item) return 0;
items.Remove(name);
item->parent = nullptr;
item->name = L"";
return item;
}
void GuiResourceFolder::ClearItems()
{
items.Clear();
}
const GuiResourceFolder::FolderList& GuiResourceFolder::GetFolders()
{
return folders.Values();
}
Ptr<GuiResourceFolder> GuiResourceFolder::GetFolder(const WString& name)
{
vint index=folders.Keys().IndexOf(name);
return index == -1 ? nullptr : folders.Values().Get(index);
}
bool GuiResourceFolder::AddFolder(const WString& name, Ptr<GuiResourceFolder> folder)
{
if (folder->GetParent() != 0 || folders.Keys().Contains(name)) return false;
folders.Add(name, folder);
folder->parent = this;
folder->name = name;
return true;
}
Ptr<GuiResourceFolder> GuiResourceFolder::RemoveFolder(const WString& name)
{
Ptr<GuiResourceFolder> folder = GetFolder(name);
if (!folder) return 0;
folders.Remove(name);
folder->parent = nullptr;
folder->name = L"";
return folder;
}
void GuiResourceFolder::ClearFolders()
{
folders.Clear();
}
Ptr<DescriptableObject> GuiResourceFolder::GetValueByPath(const WString& path)
{
const wchar_t* buffer=path.Buffer();
const wchar_t* index=wcschr(buffer, L'\\');
if(!index) index=wcschr(buffer, '/');
if(index)
{
WString name=path.Sub(0, index-buffer);
Ptr<GuiResourceFolder> folder=GetFolder(name);
if(folder)
{
vint start=index-buffer+1;
return folder->GetValueByPath(path.Sub(start, path.Length()-start));
}
}
else
{
Ptr<GuiResourceItem> item=GetItem(path);
if(item)
{
return item->GetContent();
}
}
return 0;
}
Ptr<GuiResourceFolder> GuiResourceFolder::GetFolderByPath(const WString& path)
{
const wchar_t* buffer=path.Buffer();
const wchar_t* index=wcschr(buffer, L'\\');
if(!index) index=wcschr(buffer, '/');
if(!index) return 0;
WString name=path.Sub(0, index-buffer);
Ptr<GuiResourceFolder> folder=GetFolder(name);
if(index-buffer==path.Length()-1)
{
return folder;
}
if(folder)
{
vint start=index-buffer+1;
return folder->GetFolderByPath(path.Sub(start, path.Length()-start));
}
return 0;
}
bool GuiResourceFolder::CreateValueByPath(const WString& path, const WString& typeName, Ptr<DescriptableObject> value)
{
const wchar_t* buffer = path.Buffer();
const wchar_t* index = wcschr(buffer, L'\\');
if (!index) index = wcschr(buffer, '/');
if(index)
{
WString name = path.Sub(0, index - buffer);
Ptr<GuiResourceFolder> folder = GetFolder(name);
if (!folder)
{
folder = Ptr(new GuiResourceFolder);
AddFolder(name, folder);
}
vint start = index - buffer + 1;
return folder->CreateValueByPath(path.Sub(start, path.Length() - start), typeName, value);
}
else
{
if(GetItem(path))
{
return false;
}
auto item = Ptr(new GuiResourceItem);
item->SetContent(typeName, value);
return AddItem(path, item);
}
}
/***********************************************************************
GuiResourceMetadata
***********************************************************************/
void GuiResourceMetadata::LoadFromXml(Ptr<glr::xml::XmlDocument> xml, GuiResourceLocation location, GuiResourceError::List& errors)
{
auto attrName = XmlGetAttribute(xml->rootElement, L"Name");
auto attrVersion = XmlGetAttribute(xml->rootElement, L"Version");
if (!attrName || !attrVersion)
{
errors.Add(GuiResourceError(location, L"[INTERNAL-ERROR] Resource metadata lacks of Name or Version attribute."));
return;
}
name = attrName->value.value;
version = attrVersion->value.value;
dependencies.Clear();
if (auto xmlDeps = XmlGetElement(xml->rootElement, L"Dependencies"))
{
for (auto xmlDep : XmlGetElements(xmlDeps, L"Resource"))
{
auto attrDep = XmlGetAttribute(xmlDep, L"Name");
if (!attrDep)
{
errors.Add(GuiResourceError(location, L"[INTERNAL-ERROR] Resource dependency lacks of Name attribute."));
}
dependencies.Add(attrDep->value.value);
}
}
}
Ptr<glr::xml::XmlDocument> GuiResourceMetadata::SaveToXml()
{
auto root = Ptr(new XmlElement);
root->name.value = L"ResourceMetadata";
{
auto attr = Ptr(new XmlAttribute);
attr->name.value = L"Name";
attr->value.value = name;
root->attributes.Add(attr);
}
{
auto attr = Ptr(new XmlAttribute);
attr->name.value = L"Version";
attr->value.value = version;
root->attributes.Add(attr);
}
{
auto xmlDeps = Ptr(new XmlElement);
xmlDeps->name.value = L"Dependencies";
root->subNodes.Add(xmlDeps);
for (auto dep : dependencies)
{
auto xmlDep = Ptr(new XmlElement);
xmlDep->name.value = L"Resource";
xmlDeps->subNodes.Add(xmlDep);
{
auto attr = Ptr(new XmlAttribute);
attr->name.value = L"Name";
attr->value.value = dep;
xmlDep->attributes.Add(attr);
}
}
}
auto doc = Ptr(new XmlDocument);
doc->rootElement = root;
return doc;
}
/***********************************************************************
GuiResource
***********************************************************************/
const wchar_t* GuiResource::CurrentVersionString = L"1.0";
void GuiResource::ProcessDelayLoading(Ptr<GuiResource> resource, DelayLoadingList& delayLoadings, GuiResourceError::List& errors)
{
for (auto delay : delayLoadings)
{
WString type = delay.type;
WString folder = delay.workingDirectory;
Ptr<GuiResourceItem> item = delay.preloadResource;
if (auto typeResolver = GetResourceResolverManager()->GetTypeResolver(type))
{
if (auto indirectLoad = typeResolver->IndirectLoad())
{
if (item->GetContent())
{
auto pathResolver = Ptr(new GuiResourcePathResolver(resource, folder));
Ptr<DescriptableObject> resource = indirectLoad->ResolveResource(item, pathResolver, errors);
if (resource)
{
item->SetContent(typeResolver->GetType(), resource);
}
}
}
else
{
errors.Add(GuiResourceError({ item }, L"[INTERNAL-ERROR] Resource type \"" + type + L"\" is not a indirect load resource type."));
}
}
else
{
errors.Add(GuiResourceError({ item }, L"[INTERNAL-ERROR] Unknown resource type \"" + type + L"\"."));
}
}
}
GuiResource::GuiResource()
{
metadata = Ptr(new GuiResourceMetadata);
metadata->version = WString::Unmanaged(CurrentVersionString);
}
GuiResource::~GuiResource()
{
}
Ptr<GuiResourceMetadata> GuiResource::GetMetadata()
{
return metadata;
}
WString GuiResource::GetWorkingDirectory()
{
return workingDirectory;
}
Ptr<GuiResource> GuiResource::LoadFromXml(Ptr<glr::xml::XmlDocument> xml, const WString& filePath, const WString& workingDirectory, GuiResourceError::List& errors)
{
auto resource = Ptr(new GuiResource);
resource->SetFileContentPath(filePath, filePath);
resource->workingDirectory = workingDirectory;
DelayLoadingList delayLoadings;
resource->LoadResourceFolderFromXml(delayLoadings, resource->workingDirectory, xml->rootElement, errors);
ProcessDelayLoading(resource, delayLoadings, errors);
return resource;
}
Ptr<GuiResource> GuiResource::LoadFromXml(const WString& filePath, GuiResourceError::List& errors)
{
Ptr<XmlDocument> xml;
if(auto parser=GetParserManager()->GetParser<XmlDocument>(L"XML"))
{
WString text;
if(LoadTextFile(filePath, text))
{
xml = parser->Parse({ WString::Empty,filePath }, text, errors);
}
else
{
errors.Add(GuiResourceError({ WString::Empty,filePath }, L"Failed to load file \"" + filePath + L"\"."));
}
}
if(xml)
{
return LoadFromXml(xml, filePath, GetFolderPath(filePath), errors);
}
return 0;
}
Ptr<glr::xml::XmlDocument> GuiResource::SaveToXml()
{
auto xmlRoot = Ptr(new XmlElement);
xmlRoot->name.value = L"Resource";
SaveResourceFolderToXml(xmlRoot);
auto doc = Ptr(new XmlDocument);
doc->rootElement = xmlRoot;
return doc;
}
Ptr<GuiResource> GuiResource::LoadPrecompiledBinary(stream::IStream& binaryStream, GuiResourceError::List& errors)
{
stream::internal::ContextFreeReader reader(binaryStream);
auto resource = Ptr(new GuiResource);
{
WString metadata;
reader << metadata;
auto parser = GetParserManager()->GetParser<XmlDocument>(L"XML");
auto xmlMetadata = parser->Parse({ resource }, metadata, errors);
if (!xmlMetadata) return nullptr;
resource->metadata->LoadFromXml(xmlMetadata, { resource }, errors);
if (errors.Count() != 0) return nullptr;
if (resource->metadata->version != CurrentVersionString)
{
errors.Add(GuiResourceError({ resource }, L"Only resource binary of version \"" + WString::Unmanaged(CurrentVersionString) + L"\" is accepted. Please recompile the resource before loading it."));
return nullptr;
}
}
List<WString> typeNames;
reader << typeNames;
DelayLoadingList delayLoadings;
resource->LoadResourceFolderFromBinary(delayLoadings, reader, typeNames, errors);
ProcessDelayLoading(resource, delayLoadings, errors);
return resource;
}
Ptr<GuiResource> GuiResource::LoadPrecompiledBinary(stream::IStream& binaryStream)
{
GuiResourceError::List errors;
auto resource = LoadPrecompiledBinary(binaryStream, errors);
CHECK_ERROR(errors.Count() == 0, L"GuiResource::LoadPrecompiledBinary(IStream&)#There are errors.");
return resource;
}
void GuiResource::SavePrecompiledBinary(stream::IStream& binaryStream)
{
stream::internal::ContextFreeWriter writer(binaryStream);
{
auto xmlMetadata = metadata->SaveToXml();
WString xml = GenerateToStream([&](StreamWriter& writer)
{
XmlPrint(xmlMetadata, writer);
});
writer << xml;
}
List<WString> typeNames;
CollectTypeNames(typeNames);
writer << typeNames;
SaveResourceFolderToBinary(writer, typeNames);
}
Ptr<GuiResourceFolder> GuiResource::Precompile(GuiResourceCpuArchitecture targetCpuArchitecture, IGuiResourcePrecompileCallback* callback, GuiResourceError::List& errors)
{
if (targetCpuArchitecture == GuiResourceCpuArchitecture::Unspecified)
{
#ifdef VCZH_64
targetCpuArchitecture = GuiResourceCpuArchitecture::x64;
#else
targetCpuArchitecture = GuiResourceCpuArchitecture::x86;
#endif
}
if (GetFolder(L"Precompiled"))
{
errors.Add(GuiResourceError({Ptr(this)}, L"A precompiled resource cannot be compiled again."));
return nullptr;
}
GuiResourcePrecompileContext context;
context.targetCpuArchitecture = targetCpuArchitecture;
context.compilerCallback = callback ? callback->GetCompilerCallback() : nullptr;
context.rootResource = this;
context.resolver = Ptr(new GuiResourcePathResolver(Ptr(this), workingDirectory));
context.targetFolder = Ptr(new GuiResourceFolder);
auto manager = GetResourceResolverManager();
List<WString> resolvers;
for (vint i = 0; i <= IGuiResourceTypeResolver_Precompile::Everything_Max; i++)
{
context.passIndex = i;
{
manager->GetPerResourceResolverNames(i, resolvers);
if (resolvers.Count() > 0)
{
PrecompileResourceFolder(context, callback, errors);
}
}
{
manager->GetPerPassResolverNames(i, resolvers);
if (resolvers.Count() > 0)
{
if (callback)
{
callback->OnPerPass(i);
}
for (auto name : resolvers)
{
auto resolver = manager->GetTypeResolver(name);
resolver->Precompile()->PerPassPrecompile(context, errors);
}
}
}
if (errors.Count() > 0)
{
return context.targetFolder;
}
}
AddFolder(L"Precompiled", context.targetFolder);
return context.targetFolder;
}
void GuiResource::Initialize(GuiResourceUsage usage, GuiResourceError::List& errors)
{
auto precompiledFolder = GetFolder(L"Precompiled");
if (!precompiledFolder)
{
CHECK_FAIL(L"GuiResource::Initialize()#Cannot initialize a non-precompiled resource.");
return;
}
GuiResourceInitializeContext context;
context.rootResource = this;
context.resolver = Ptr(new GuiResourcePathResolver(Ptr(this), workingDirectory));
context.targetFolder = precompiledFolder;
context.usage = usage;
for (vint i = 0; i <= IGuiResourceTypeResolver_Initialize::Everything_Max; i++)
{
context.passIndex = i;
InitializeResourceFolder(context, errors);
}
}
Ptr<DocumentModel> GuiResource::GetDocumentByPath(const WString& path)
{
Ptr<DocumentModel> result=GetValueByPath(path).Cast<DocumentModel>();
if(!result) throw ArgumentException(L"Path not exists.", L"GuiResource::GetDocumentByPath", L"path");
return result;
}
Ptr<GuiImageData> GuiResource::GetImageByPath(const WString& path)
{
Ptr<GuiImageData> result=GetValueByPath(path).Cast<GuiImageData>();
if(!result) throw ArgumentException(L"Path not exists.", L"GuiResource::GetImageByPath", L"path");
return result;
}
Ptr<glr::xml::XmlDocument> GuiResource::GetXmlByPath(const WString& path)
{
Ptr<XmlDocument> result=GetValueByPath(path).Cast<XmlDocument>();
if(!result) throw ArgumentException(L"Path not exists.", L"GuiResource::GetXmlByPath", L"path");
return result;
}
WString GuiResource::GetStringByPath(const WString& path)
{
Ptr<GuiTextData> result=GetValueByPath(path).Cast<GuiTextData>();
if(!result) throw ArgumentException(L"Path not exists.", L"GuiResource::GetStringByPath", L"path");
return result->GetText();
}
/***********************************************************************
GuiResourcePathResolver
***********************************************************************/
GuiResourcePathResolver::GuiResourcePathResolver(Ptr<GuiResource> _resource, const WString& _workingDirectory)
:resource(_resource)
,workingDirectory(_workingDirectory)
{
}
GuiResourcePathResolver::~GuiResourcePathResolver()
{
}
Ptr<DescriptableObject> GuiResourcePathResolver::ResolveResource(const WString& protocol, const WString& path)
{
Ptr<IGuiResourcePathResolver> resolver;
vint index=resolvers.Keys().IndexOf(protocol);
if(index==-1)
{
IGuiResourcePathResolverFactory* factory=GetResourceResolverManager()->GetPathResolverFactory(protocol);
if(factory)
{
resolver=factory->CreateResolver(resource, workingDirectory);
}
resolvers.Add(protocol, resolver);
}
else
{
resolver=resolvers.Values()[index];
}
if(resolver)
{
return resolver->ResolveResource(path);
}
else
{
return 0;
}
}
/***********************************************************************
GuiResourcePathResResolver
***********************************************************************/
class GuiResourcePathResResolver : public Object, public IGuiResourcePathResolver
{
protected:
Ptr<GuiResource> resource;
public:
GuiResourcePathResResolver(Ptr<GuiResource> _resource)
:resource(_resource)
{
}
Ptr<DescriptableObject> ResolveResource(const WString& path)
{
if (resource)
{
if (path.Length() > 0)
{
switch (path[path.Length() - 1])
{
case L'\\':case L'/':
return resource->GetFolderByPath(path);
default:
return resource->GetValueByPath(path);
}
}
}
return nullptr;
}
class Factory : public Object, public IGuiResourcePathResolverFactory
{
public:
WString GetProtocol()override
{
return L"res";
}
Ptr<IGuiResourcePathResolver> CreateResolver(Ptr<GuiResource> resource, const WString& workingDirectory)override
{
return Ptr(new GuiResourcePathResResolver(resource));
}
};
};
/***********************************************************************
GuiImportResourcePathResResolver
***********************************************************************/
class GuiImportResourcePathResResolver : public Object, public IGuiResourcePathResolver
{
public:
GuiImportResourcePathResResolver()
{
}
Ptr<DescriptableObject> ResolveResource(const WString& path)
{
const wchar_t* buffer = path.Buffer();
const wchar_t* d1 = wcschr(buffer, L'\\');
const wchar_t* d2 = wcschr(buffer, L'/');
const wchar_t* d =
d1 == nullptr&&d2 == nullptr ? nullptr :
d1 == nullptr ? d2 :
d2 == nullptr ? d1 :
d1 < d2 ? d1 : d2;
if (!d) return nullptr;
WString resourceName = WString::CopyFrom(buffer, d - buffer);
WString resourcePath(path.Right(path.Length() - resourceName.Length() - 1));
if (auto resource = GetResourceManager()->GetResource(resourceName))
{
switch (path[path.Length() - 1])
{
case L'\\':case L'/':
return resource->GetFolderByPath(resourcePath);
default:
return resource->GetValueByPath(resourcePath);
}
}
return nullptr;
}
class Factory : public Object, public IGuiResourcePathResolverFactory
{
public:
WString GetProtocol()override
{
return L"import-res";
}
Ptr<IGuiResourcePathResolver> CreateResolver(Ptr<GuiResource> resource, const WString& workingDirectory)override
{
return Ptr(new GuiImportResourcePathResResolver);
}
};
};
/***********************************************************************
IGuiResourceResolverManager
***********************************************************************/
IGuiResourceResolverManager* resourceResolverManager=0;
IGuiResourceResolverManager* GetResourceResolverManager()
{
return resourceResolverManager;
}
class GuiResourceResolverManager : public Object, public IGuiResourceResolverManager, public IGuiPlugin
{
typedef Dictionary<WString, Ptr<IGuiResourcePathResolverFactory>> PathFactoryMap;
typedef Dictionary<WString, Ptr<IGuiResourceTypeResolver>> TypeResolverMap;
typedef Group<vint, WString> ResolverGroup;
protected:
PathFactoryMap pathFactories;
TypeResolverMap typeResolvers;
ResolverGroup perResourceResolvers;
ResolverGroup perPassResolvers;
public:
GUI_PLUGIN_NAME(GacUI_Res_ResourceResolver)
{
}
void Load(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override
{
if (controllerUnrelatedPlugins)
{
globalStringKeyManager = new GlobalStringKeyManager();
globalStringKeyManager->InitializeConstants();
resourceResolverManager = this;
SetPathResolverFactory(Ptr(new GuiResourcePathResResolver::Factory));
SetPathResolverFactory(Ptr(new GuiImportResourcePathResResolver::Factory));
}
}
void Unload(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override
{
if (controllerUnrelatedPlugins)
{
delete globalStringKeyManager;
globalStringKeyManager = nullptr;
resourceResolverManager = nullptr;
}
}
IGuiResourcePathResolverFactory* GetPathResolverFactory(const WString& protocol)override
{
vint index=pathFactories.Keys().IndexOf(protocol);
return index==-1?0:pathFactories.Values()[index].Obj();
}
bool SetPathResolverFactory(Ptr<IGuiResourcePathResolverFactory> factory)override
{
if(pathFactories.Keys().Contains(factory->GetProtocol())) return false;
pathFactories.Add(factory->GetProtocol(), factory);
return true;
}
IGuiResourceTypeResolver* GetTypeResolver(const WString& type)override
{
vint index=typeResolvers.Keys().IndexOf(type);
return index==-1?0:typeResolvers.Values()[index].Obj();
}
bool SetTypeResolver(Ptr<IGuiResourceTypeResolver> resolver)override
{
if(typeResolvers.Keys().Contains(resolver->GetType())) return false;
typeResolvers.Add(resolver->GetType(), resolver);
if (auto precompile = resolver->Precompile())
{
for (vint i = 0; i <= IGuiResourceTypeResolver_Precompile::Everything_Max; i++)
{
switch (precompile->GetPrecompilePassSupport(i))
{
case IGuiResourceTypeResolver_Precompile::PerResource:
perResourceResolvers.Add(i, resolver->GetType());
break;
case IGuiResourceTypeResolver_Precompile::PerPass:
perPassResolvers.Add(i, resolver->GetType());
break;
default:;
}
}
}
return true;
}
void GetPerResourceResolverNames(vint passIndex, collections::List<WString>& names)override
{
names.Clear();
vint index = perResourceResolvers.Keys().IndexOf(passIndex);
if (index != -1)
{
CopyFrom(names, perResourceResolvers.GetByIndex(index));
}
}
void GetPerPassResolverNames(vint passIndex, collections::List<WString>& names)override
{
names.Clear();
vint index = perPassResolvers.Keys().IndexOf(passIndex);
if (index != -1)
{
CopyFrom(names, perPassResolvers.GetByIndex(index));
}
}
};
GUI_REGISTER_PLUGIN(GuiResourceResolverManager)
/***********************************************************************
Helpers
***********************************************************************/
void DecompressStream(const char** buffer, bool decompress, vint rows, vint block, vint remain, stream::IStream& outputStream)
{
if (decompress)
{
MemoryStream compressedStream;
DecompressStream(buffer, false, rows, block, remain, compressedStream);
compressedStream.SeekFromBegin(0);
DecompressStream(compressedStream, outputStream);
}
else
{
for (vint i = 0; i < rows; i++)
{
vint size = (i == rows - 1 && remain > 0) ? remain : block;
outputStream.Write((void*)buffer[i], size);
}
}
}
}
}
/***********************************************************************
.\RESOURCES\GUIRESOURCEMANAGER.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace stream;
using namespace glr::xml;
using namespace reflection::description;
/***********************************************************************
Class Name Record (ClassNameRecord)
***********************************************************************/
class GuiResourceClassNameRecordTypeResolver
: public Object
, public IGuiResourceTypeResolver
, private IGuiResourceTypeResolver_DirectLoadStream
{
public:
WString GetType()override
{
return L"ClassNameRecord";
}
bool XmlSerializable()override
{
return false;
}
bool StreamSerializable()override
{
return true;
}
IGuiResourceTypeResolver_DirectLoadStream* DirectLoadStream()override
{
return this;
}
void SerializePrecompiled(Ptr<GuiResourceItem> resource, Ptr<DescriptableObject> content, stream::IStream& binaryStream)override
{
if (auto obj = content.Cast<GuiResourceClassNameRecord>())
{
internal::ContextFreeWriter writer(binaryStream);
writer << obj->classNames;
}
}
Ptr<DescriptableObject> ResolveResourcePrecompiled(Ptr<GuiResourceItem> resource, stream::IStream& binaryStream, GuiResourceError::List& errors)override
{
internal::ContextFreeReader reader(binaryStream);
auto obj = Ptr(new GuiResourceClassNameRecord);
reader << obj->classNames;
return obj;
}
};
/***********************************************************************
IGuiInstanceResourceManager
***********************************************************************/
IGuiResourceManager* resourceManager = nullptr;
IGuiResourceManager* GetResourceManager()
{
return resourceManager;
}
class GuiResourceManager : public Object, public IGuiResourceManager, public IGuiPlugin
{
protected:
typedef Dictionary<WString, Ptr<GuiResource>> ResourceMap;
List<Ptr<GuiResource>> anonymousResources;
ResourceMap resources;
ResourceMap instanceResources;
class PendingResource : public Object
{
public:
Ptr<GuiResourceMetadata> metadata;
GuiResourceUsage usage;
MemoryStream memoryStream;
SortedList<WString> dependencies;
Ptr<GuiResource> LoadResource()
{
memoryStream.SeekFromBegin(0);
List<GuiResourceError> errors;
auto resource = GuiResource::LoadPrecompiledBinary(memoryStream, errors);
CHECK_ERROR(errors.Count() == 0, L"PendingResource::LoadResource()#Failed to load the resource.");
return resource;
}
};
Group<WString, Ptr<PendingResource>> depToPendings;
SortedList<Ptr<PendingResource>> pendingResources;
public:
GUI_PLUGIN_NAME(GacUI_Res_Resource)
{
GUI_PLUGIN_DEPEND(GacUI_Res_ResourceResolver);
}
void Load(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override
{
if (controllerRelatedPlugins)
{
resourceManager = this;
IGuiResourceResolverManager* manager = GetResourceResolverManager();
manager->SetTypeResolver(Ptr(new GuiResourceClassNameRecordTypeResolver));
}
}
void Unload(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override
{
if (controllerRelatedPlugins)
{
anonymousResources.Clear();
resources.Clear();
instanceResources.Clear();
resourceManager = nullptr;
}
}
void SetResource(Ptr<GuiResource> resource, GuiResourceError::List& errors, GuiResourceUsage usage)override
{
auto metadata = resource->GetMetadata();
if (metadata->name == L"")
{
if (anonymousResources.Contains(resource.Obj())) return;
resource->Initialize(usage, errors);
if (errors.Count() > 0)
{
return;
}
anonymousResources.Add(resource);
}
else
{
CHECK_ERROR(!resources.Keys().Contains(metadata->name), L"GuiResourceManager::SetResource(Ptr<GuiResource>, GuiResourceUsage)#A resource with the same name has been loaded.");
resource->Initialize(usage, errors);
if (errors.Count() > 0)
{
return;
}
resources.Add(metadata->name, resource);
}
if (auto record = resource->GetValueByPath(L"Precompiled/ClassNameRecord").Cast<GuiResourceClassNameRecord>())
{
for (auto className : record->classNames)
{
instanceResources.Add(className, resource);
}
}
if (metadata->name != L"")
{
vint index = depToPendings.Keys().IndexOf(metadata->name);
if (index != -1)
{
List<Ptr<PendingResource>> prs;
CopyFrom(prs, depToPendings.GetByIndex(index));
depToPendings.Remove(metadata->name);
for (auto pr : prs)
{
pr->dependencies.Remove(metadata->name);
if (pr->dependencies.Count() == 0)
{
pendingResources.Remove(pr.Obj());
SetResource(pr->LoadResource(), errors, pr->usage);
}
}
}
}
}
Ptr<GuiResource> GetResource(const WString& name)override
{
vint index = resources.Keys().IndexOf(name);
if (index == -1) return nullptr;
return resources.Values()[index];
}
Ptr<GuiResource> GetResourceFromClassName(const WString& classFullName)override
{
vint index = instanceResources.Keys().IndexOf(classFullName);
if (index == -1) return nullptr;
return instanceResources.Values()[index];
}
LazyList<Ptr<GuiResource>> GetLoadedResources()override
{
return From(anonymousResources).Concat(resources.Values());
}
bool UnloadResource(const WString& name)override
{
return UnloadResource(GetResource(name));
}
bool UnloadResource(Ptr<GuiResource> resource)override
{
if (!resource) return false;
WString name;
if (auto metadata = resource->GetMetadata())
{
name = metadata->name;
}
if (name == WString::Empty)
{
vint index = anonymousResources.IndexOf(resource.Obj());
if (index == -1) return false;
anonymousResources.RemoveAt(index);
}
else
{
vint index = resources.Keys().IndexOf(name);
if (index == -1) return false;
auto resource = resources.Values()[index];
resources.Remove(name);
}
if (auto record = resource->GetValueByPath(L"Precompiled/ClassNameRecord").Cast<GuiResourceClassNameRecord>())
{
for (auto className : record->classNames)
{
instanceResources.Remove(className);
}
}
return true;
}
void LoadResourceOrPending(stream::IStream& resourceStream, GuiResourceError::List& errors, GuiResourceUsage usage)override
{
auto pr = Ptr(new PendingResource);
pr->usage = usage;
CopyStream(resourceStream, pr->memoryStream);
pr->metadata = Ptr(new GuiResourceMetadata);
{
pr->memoryStream.SeekFromBegin(0);
stream::internal::ContextFreeReader reader(pr->memoryStream);
WString metadata;
reader << metadata;
List<GuiResourceError> errors;
auto parser = GetParserManager()->GetParser<XmlDocument>(L"XML");
auto xmlMetadata = parser->Parse({}, metadata, errors);
CHECK_ERROR(xmlMetadata, L"GuiResourceManager::LoadResourceOrPending(stream::IStream&, GuiResourceUsage)#This resource does not contain a valid metadata.");
pr->metadata->LoadFromXml(xmlMetadata, {}, errors);
CHECK_ERROR(errors.Count() == 0, L"GuiResourceManager::LoadResourceOrPending(stream::IStream&, GuiResourceUsage)#This resource does not contain a valid metadata.");
}
CHECK_ERROR(
pr->metadata->name != L"" || pr->dependencies.Count() == 0,
L"GuiResourceManager::LoadResourceOrPending(stream::IStream&, GuiResourceUsage)#The name of this resource cannot be empty because it has dependencies."
);
CopyFrom(pr->dependencies, From(pr->metadata->dependencies).Except(resources.Keys()));
if (pr->dependencies.Count() == 0)
{
SetResource(pr->LoadResource(), errors, pr->usage);
}
else
{
pendingResources.Add(pr);
for (auto dep : pr->dependencies)
{
depToPendings.Add(dep, pr);
}
}
}
void LoadResourceOrPending(stream::IStream& resourceStream, GuiResourceUsage usage)override
{
GuiResourceError::List errors;
LoadResourceOrPending(resourceStream, errors, usage);
CHECK_ERROR(errors.Count() == 0, L"GuiResourceManager::LoadResourceOrPending(stream::IStream&, GuiResourceUsage)#Error happened.");
}
void GetPendingResourceNames(collections::List<WString>& names)override
{
CopyFrom(names, From(pendingResources).Select([](Ptr<PendingResource> pr) {return pr->metadata->name; }));
}
};
GUI_REGISTER_PLUGIN(GuiResourceManager)
}
}
/***********************************************************************
.\RESOURCES\GUIRESOURCETYPERESOLVERS.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace glr::xml;
using namespace stream;
/***********************************************************************
Image Type Resolver (Image)
***********************************************************************/
class GuiResourceImageTypeResolver
: public Object
, public IGuiResourceTypeResolver
, private IGuiResourceTypeResolver_DirectLoadXml
, private IGuiResourceTypeResolver_DirectLoadStream
{
public:
WString GetType()override
{
return L"Image";
}
bool XmlSerializable()override
{
return true;
}
bool StreamSerializable()override
{
return true;
}
IGuiResourceTypeResolver_DirectLoadXml* DirectLoadXml()override
{
return this;
}
IGuiResourceTypeResolver_DirectLoadStream* DirectLoadStream()override
{
return this;
}
Ptr<glr::xml::XmlElement> Serialize(Ptr<GuiResourceItem> resource, Ptr<DescriptableObject> content)override
{
return nullptr;
}
void SerializePrecompiled(Ptr<GuiResourceItem> resource, Ptr<DescriptableObject> content, stream::IStream& binaryStream)override
{
auto obj = content.Cast<GuiImageData>();
stream::internal::ContextFreeWriter writer(binaryStream);
FileStream fileStream(resource->GetFileAbsolutePath(), FileStream::ReadOnly);
writer << (stream::IStream&)fileStream;
}
Ptr<DescriptableObject> ResolveResource(Ptr<GuiResourceItem> resource, Ptr<glr::xml::XmlElement> element, GuiResourceError::List& errors)override
{
errors.Add(GuiResourceError({ resource }, L"Image should load from file."));
return nullptr;
}
Ptr<DescriptableObject> ResolveResource(Ptr<GuiResourceItem> resource, const WString& path, GuiResourceError::List& errors)override
{
Ptr<INativeImage> image = GetCurrentController()->ImageService()->CreateImageFromFile(path);
if(image)
{
return Ptr(new GuiImageData(image, 0));
}
else
{
errors.Add(GuiResourceError({ resource }, L"Failed to load file \"" + path + L"\"."));
return nullptr;
}
}
Ptr<DescriptableObject> ResolveResourcePrecompiled(Ptr<GuiResourceItem> resource, stream::IStream& binaryStream, GuiResourceError::List& errors)override
{
stream::internal::ContextFreeReader reader(binaryStream);
MemoryStream memoryStream;
reader << (stream::IStream&)memoryStream;
auto image = GetCurrentController()->ImageService()->CreateImageFromStream(memoryStream);
if (image)
{
return Ptr(new GuiImageData(image, 0));
}
else
{
errors.Add(GuiResourceError({ resource }, L"[BINARY] Failed to load an image from binary data in a stream."));
return nullptr;
}
}
};
/***********************************************************************
Text Type Resolver (Text)
***********************************************************************/
class GuiResourceTextTypeResolver
: public Object
, public IGuiResourceTypeResolver
, private IGuiResourceTypeResolver_DirectLoadXml
, private IGuiResourceTypeResolver_DirectLoadStream
{
public:
WString GetType()override
{
return L"Text";
}
bool XmlSerializable()override
{
return true;
}
bool StreamSerializable()override
{
return true;
}
IGuiResourceTypeResolver_DirectLoadXml* DirectLoadXml()override
{
return this;
}
IGuiResourceTypeResolver_DirectLoadStream* DirectLoadStream()override
{
return this;
}
Ptr<glr::xml::XmlElement> Serialize(Ptr<GuiResourceItem> resource, Ptr<DescriptableObject> content)override
{
if (auto obj = content.Cast<GuiTextData>())
{
auto xmlContent = Ptr(new XmlText);
xmlContent->content.value = obj->GetText();
auto xmlText = Ptr(new XmlElement);
xmlText->name.value = L"Text";
xmlText->subNodes.Add(xmlContent);
return xmlText;
}
return 0;
}
void SerializePrecompiled(Ptr<GuiResourceItem> resource, Ptr<DescriptableObject> content, stream::IStream& binaryStream)override
{
auto obj = content.Cast<GuiTextData>();
stream::internal::ContextFreeWriter writer(binaryStream);
WString text = obj->GetText();
writer << text;
}
Ptr<DescriptableObject> ResolveResource(Ptr<GuiResourceItem> resource, Ptr<glr::xml::XmlElement> element, GuiResourceError::List& errors)override
{
return Ptr(new GuiTextData(XmlGetValue(element)));
}
Ptr<DescriptableObject> ResolveResource(Ptr<GuiResourceItem> resource, const WString& path, GuiResourceError::List& errors)override
{
WString text;
if(LoadTextFile(path, text))
{
return Ptr(new GuiTextData(text));
}
else
{
errors.Add(GuiResourceError({ resource }, L"Failed to load file \"" + path + L"\"."));
return nullptr;
}
}
Ptr<DescriptableObject> ResolveResourcePrecompiled(Ptr<GuiResourceItem> resource, stream::IStream& binaryStream, GuiResourceError::List& errors)override
{
stream::internal::ContextFreeReader reader(binaryStream);
WString text;
reader << text;
return Ptr(new GuiTextData(text));
}
};
/***********************************************************************
Xml Type Resolver (Xml)
***********************************************************************/
class GuiResourceXmlTypeResolver
: public Object
, public IGuiResourceTypeResolver
, private IGuiResourceTypeResolver_DirectLoadXml
, private IGuiResourceTypeResolver_DirectLoadStream
{
public:
WString GetType()override
{
return L"Xml";
}
bool XmlSerializable()override
{
return true;
}
bool StreamSerializable()override
{
return true;
}
IGuiResourceTypeResolver_DirectLoadXml* DirectLoadXml()override
{
return this;
}
IGuiResourceTypeResolver_DirectLoadStream* DirectLoadStream()override
{
return this;
}
Ptr<glr::xml::XmlElement> Serialize(Ptr<GuiResourceItem> resource, Ptr<DescriptableObject> content)override
{
if (auto obj = content.Cast<XmlDocument>())
{
auto xmlXml = Ptr(new XmlElement());
xmlXml->name.value = L"Xml";
xmlXml->subNodes.Add(obj->rootElement);
return xmlXml;
}
return nullptr;
}
void SerializePrecompiled(Ptr<GuiResourceItem> resource, Ptr<DescriptableObject> content, stream::IStream& binaryStream)override
{
auto obj = content.Cast<XmlDocument>();
WString text = GenerateToStream([&](StreamWriter& writer)
{
XmlPrint(obj, writer);
});
stream::internal::ContextFreeWriter writer(binaryStream);
writer << text;
}
Ptr<DescriptableObject> ResolveResource(Ptr<GuiResourceItem> resource, Ptr<glr::xml::XmlElement> element, GuiResourceError::List& errors)override
{
Ptr<XmlElement> root = XmlGetElements(element).First(0);
if(root)
{
auto xml = Ptr(new XmlDocument);
xml->rootElement=root;
return xml;
}
return nullptr;
}
Ptr<DescriptableObject> ResolveResource(Ptr<GuiResourceItem> resource, const WString& path, GuiResourceError::List& errors)override
{
if (auto parser = GetParserManager()->GetParser<XmlDocument>(L"XML"))
{
WString text;
if (LoadTextFile(path, text))
{
return parser->Parse({ resource }, text, errors);
}
else
{
errors.Add(GuiResourceError({ resource }, L"Failed to load file \"" + path + L"\"."));
}
}
return nullptr;
}
Ptr<DescriptableObject> ResolveResourcePrecompiled(Ptr<GuiResourceItem> resource, stream::IStream& binaryStream, GuiResourceError::List& errors)override
{
if (auto parser = GetParserManager()->GetParser<XmlDocument>(L"XML"))
{
stream::internal::ContextFreeReader reader(binaryStream);
WString text;
reader << text;
return parser->Parse({ resource }, text, errors);
}
return nullptr;
}
};
/***********************************************************************
Doc Type Resolver (Doc)
***********************************************************************/
class GuiResourceDocTypeResolver
: public Object
, public IGuiResourceTypeResolver
, private IGuiResourceTypeResolver_IndirectLoad
{
public:
WString GetType()override
{
return L"Doc";
}
bool XmlSerializable()override
{
return true;
}
bool StreamSerializable()override
{
return true;
}
WString GetPreloadType()override
{
return L"Xml";
}
bool IsDelayLoad()override
{
return true;
}
IGuiResourceTypeResolver_IndirectLoad* IndirectLoad()override
{
return this;
}
Ptr<DescriptableObject> Serialize(Ptr<GuiResourceItem> resource, Ptr<DescriptableObject> content)override
{
if (auto obj = content.Cast<DocumentModel>())
{
return obj->SaveToXml();
}
return nullptr;
}
Ptr<DescriptableObject> ResolveResource(Ptr<GuiResourceItem> resource, Ptr<GuiResourcePathResolver> resolver, GuiResourceError::List& errors)override
{
if(auto xml = resource->GetContent().Cast<XmlDocument>())
{
Ptr<DocumentModel> model = DocumentModel::LoadFromXml(resource, xml, resolver, errors);
return model;
}
return nullptr;
}
};
/***********************************************************************
Type Resolver Plugin
***********************************************************************/
class GuiResourceTypeResolversPlugin : public Object, public IGuiPlugin
{
public:
GUI_PLUGIN_NAME(GacUI_Res_TypeResolvers)
{
GUI_PLUGIN_DEPEND(GacUI_Res_ResourceResolver);
}
void Load(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override
{
if (controllerUnrelatedPlugins)
{
IGuiResourceResolverManager* manager = GetResourceResolverManager();
manager->SetTypeResolver(Ptr(new GuiResourceImageTypeResolver));
manager->SetTypeResolver(Ptr(new GuiResourceTextTypeResolver));
manager->SetTypeResolver(Ptr(new GuiResourceXmlTypeResolver));
manager->SetTypeResolver(Ptr(new GuiResourceDocTypeResolver));
}
}
void Unload(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override
{
}
};
GUI_REGISTER_PLUGIN(GuiResourceTypeResolversPlugin)
}
}
/***********************************************************************
.\UTILITIES\GUIUTILITIESREGISTRATION.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
/***********************************************************************
Utilities Registration
***********************************************************************/
FakeClipboardService* fakeClipboardService = nullptr;
FakeDialogService* fakeDialogService = nullptr;
void GuiInitializeUtilities()
{
if (!fakeClipboardService)
{
fakeClipboardService = new FakeClipboardService;
GetNativeServiceSubstitution()->Substitute(fakeClipboardService, true);
}
if (!fakeDialogService)
{
fakeDialogService = new FakeDialogService;
GetNativeServiceSubstitution()->Substitute(fakeDialogService, true);
}
}
void GuiFinalizeUtilities()
{
if (fakeClipboardService)
{
GetNativeServiceSubstitution()->Unsubstitute(fakeClipboardService);
delete fakeClipboardService;
fakeClipboardService = nullptr;
}
if (fakeDialogService)
{
GetNativeServiceSubstitution()->Unsubstitute(fakeDialogService);
delete fakeDialogService;
fakeDialogService = nullptr;
}
}
}
}
/***********************************************************************
.\UTILITIES\FAKESERVICES\GUIFAKECLIPBOARDSERVICE.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
/***********************************************************************
FakeClipboardReader
***********************************************************************/
class FakeClipboardReader : public Object, public INativeClipboardReader
{
public:
Nullable<WString> text;
Ptr<DocumentModel> document;
Ptr<INativeImage> image;
bool ContainsText() override
{
return text;
}
WString GetText() override
{
return text ? text.Value() : WString();
}
bool ContainsDocument() override
{
return document;
}
Ptr<DocumentModel> GetDocument() override
{
return document;
}
bool ContainsImage() override
{
return image;
}
Ptr<INativeImage> GetImage() override
{
return image;
}
};
/***********************************************************************
FakeClipboardWriter
***********************************************************************/
class FakeClipboardWriter : public Object, public INativeClipboardWriter
{
public:
FakeClipboardService* service;
Ptr<FakeClipboardReader> reader;
FakeClipboardWriter(FakeClipboardService* _service)
: service(_service)
{
}
void SetText(const WString& value) override
{
if (reader) reader->text = value;
}
void SetDocument(Ptr<DocumentModel> value) override
{
if (reader) reader->document = value;
}
void SetImage(Ptr<INativeImage> value) override
{
if (reader) reader->image = value;
}
bool Submit() override
{
if (!reader) return false;
service->reader = reader;
reader = nullptr;
service = nullptr;
GetCurrentController()->CallbackService()->Invoker()->InvokeClipboardUpdated();
return true;
}
};
/***********************************************************************
FakeClipboardService
***********************************************************************/
FakeClipboardService::FakeClipboardService()
: reader(Ptr(new FakeClipboardReader))
{
}
FakeClipboardService::~FakeClipboardService()
{
}
Ptr<INativeClipboardReader> FakeClipboardService::ReadClipboard()
{
return reader;
}
Ptr<INativeClipboardWriter> FakeClipboardService::WriteClipboard()
{
return Ptr(new FakeClipboardWriter(this));
}
}
}
/***********************************************************************
.\UTILITIES\FAKESERVICES\GUIFAKEDIALOGSERVICEBASE.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace compositions;
using namespace controls;
/***********************************************************************
FakeDialogServiceBase
***********************************************************************/
void FakeDialogServiceBase::ShowModalDialogAndDelete(Ptr<IDescriptable> viewModel, controls::GuiWindow* owner, controls::GuiWindow* dialog)
{
auto app = GetApplication();
bool exit = false;
dialog->WindowOpened.AttachLambda([=](GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
dialog->ForceCalculateSizeImmediately();
dialog->MoveToScreenCenter();
});
auto movingFlag = Ptr(new bool(false));
dialog->ControlSignalTrigerred.AttachLambda([=](GuiGraphicsComposition* sender, GuiControlSignalEventArgs& arguments)
{
if (arguments.controlSignal == ControlSignal::UpdateFullfilled)
{
if (!*movingFlag.Obj())
{
*movingFlag.Obj() = true;
dialog->MoveToScreenCenter();
}
}
});
dialog->ShowModalAndDelete(owner, [&exit]() { exit = true; }, [viewModel]() { (void)viewModel; });
while (!exit && app->RunOneCycle());
}
FakeDialogServiceBase::FakeDialogServiceBase()
{
}
FakeDialogServiceBase::~FakeDialogServiceBase()
{
}
}
}
/***********************************************************************
.\UTILITIES\FAKESERVICES\GUIFAKEDIALOGSERVICEBASE_COLORDIALOG.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace controls;
/***********************************************************************
View Model (IColorDialogViewModel)
***********************************************************************/
class FakeColorDialogViewModel : public Object, public virtual IColorDialogViewModel
{
public:
bool confirmed = false;
Color color;
bool GetConfirmed() override { return confirmed; }
void SetConfirmed(bool value) override { confirmed = value; }
Color GetColor() override { return color; }
void SetColor(Color value) override { color = value; }
};
/***********************************************************************
FakeDialogServiceBase
***********************************************************************/
bool FakeDialogServiceBase::ShowColorDialog(
INativeWindow* window,
Color& selection,
bool selected,
ColorDialogCustomColorOptions customColorOptions,
Color* customColors
)
{
auto vm = Ptr(new FakeColorDialogViewModel);
vm->color = selection;
{
auto owner = GetApplication()->GetWindowFromNative(window);
auto dialog = CreateColorDialog(vm);
ShowModalDialogAndDelete(vm, owner, dialog);
}
if (vm->confirmed)
{
selection = vm->color;
}
return vm->confirmed;
}
}
}
/***********************************************************************
.\UTILITIES\FAKESERVICES\GUIFAKEDIALOGSERVICEBASE_FILEDIALOG.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace regex;
using namespace controls;
/***********************************************************************
View Model (IFileDialogFilter)
***********************************************************************/
class FileDialogFilter : public Object, public virtual IFileDialogFilter
{
public:
WString name;
WString filter;
Nullable<WString> defaultExtension;
Ptr<Regex> regexFilter;
WString GetName() override
{
return name;
}
WString GetFilter() override
{
return filter;
}
Nullable<WString> GetDefaultExtension() override
{
return defaultExtension;
}
bool FilterFile(Ptr<IFileDialogFile> file) override
{
if (file->GetType() != FileDialogFileType::File) return true;
auto name = file->GetName();
auto match = regexFilter->MatchHead(name);
return match && match->Result().Length() == name.Length();
}
};
/***********************************************************************
View Model (IFileDialogFolder)
***********************************************************************/
class FileDialogFolder : public Object, public virtual IFileDialogFolder
{
using FolderMap = Dictionary<WString, Ptr<FileDialogFolder>>;
protected:
vint taskId = 0;
bool taskFired = false;
public:
FileDialogFolder* parent = nullptr;
FileDialogFolderType type = FileDialogFolderType::Placeholder;
filesystem::Folder folder;
WString name;
vint index = -1;
WString textLoadingFolders;
// the placeholder node will always be the last one
Folders children;
FolderMap childrenByName;
void AddChild(Ptr<FileDialogFolder> child)
{
child->textLoadingFolders = textLoadingFolders;
child->parent = this;
if (child->type == FileDialogFolderType::Folder)
{
childrenByName.Add(child->name, child);
}
child->index = HasPlaceholderChild() ? children.Count() - 1 : children.Count();
children.Insert(child->index, child);
}
bool HasPlaceholderChild()
{
return children.Count() > 0 && children[children.Count() - 1]->GetType() == FileDialogFolderType::Placeholder;
}
void AddPlaceholderChild()
{
if (HasPlaceholderChild()) return;
CHECK_ERROR(textLoadingFolders.Length() > 0, L"vl::presentation::FileDialogFolder::AddPlaceholderChild()#textLoadingFolders is not initialized.");
auto child = Ptr(new FileDialogFolder);
child->name = textLoadingFolders;
AddChild(child);
}
void RemovePlaceholderChild()
{
if (HasPlaceholderChild())
{
children.RemoveAt(children.Count() - 1);
}
}
FileDialogFolder() = default;
FileDialogFolder(const filesystem::Folder& _folder)
: type(FileDialogFolderType::Folder)
, folder(_folder)
, name(_folder.GetFilePath().GetName())
{
}
Ptr<IFileDialogFolder> GetParent() override
{
return Ptr(static_cast<IFileDialogFolder*>(parent));
}
FileDialogFolderType GetType() override
{
if (type == FileDialogFolderType::Placeholder && !taskFired)
{
taskFired = true;
auto taskFolder = Ptr(parent);
vint taskFolderId = ++taskFolder->taskId;
GetApplication()->InvokeAsync([taskFolder, taskFolderId]()
{
auto subFolders = Ptr(new List<filesystem::Folder>);
if (!taskFolder->folder.GetFolders(*subFolders.Obj()))
{
subFolders->Clear();
}
GetApplication()->InvokeInMainThread(nullptr, [taskFolder, taskFolderId, subFolders]()
{
if (taskFolder->taskId == taskFolderId)
{
taskFolder->RemovePlaceholderChild();
for (auto subFolder : *subFolders.Obj())
{
if (!taskFolder->childrenByName.Keys().Contains(subFolder.GetFilePath().GetName()))
{
auto child = Ptr(new FileDialogFolder(subFolder));
taskFolder->AddChild(child);
child->AddPlaceholderChild();
}
}
}
});
});
}
return type;
}
WString GetFullPath() override
{
return folder.GetFilePath().GetFullPath();
}
WString GetName() override
{
return name;
}
vint GetIndex() override
{
return index;
}
Folders& GetFolders() override
{
return children;
}
Ptr<IFileDialogFolder> TryGetFolder(const WString& name) override
{
vint index = childrenByName.Keys().IndexOf(name);
if (index == -1) return {};
return childrenByName.Values()[index];
}
};
/***********************************************************************
View Model (IFileDialogFile)
***********************************************************************/
class FileDialogFile : public Object, public virtual IFileDialogFile
{
public:
FileDialogFileType type = FileDialogFileType::Placeholder;
Ptr<FileDialogFolder> associatedFolder;
WString name;
FileDialogFileType GetType() override
{
return type;
}
Ptr<IFileDialogFolder> GetAssociatedFolder() override
{
return associatedFolder;
}
WString GetName() override
{
return name;
}
};
/***********************************************************************
View Model (IFileDialogViewModel)
***********************************************************************/
class FileDialogViewModel : public Object, public virtual IFileDialogViewModel
{
using ConfirmedSelection = collections::List<WString>;
protected:
WString textLoadingFolders;
WString textLoadingFiles;
WString dialogErrorEmptySelection;
WString dialogErrorFileNotExist;
WString dialogErrorFileExpected;
WString dialogErrorFolderNotExist;
WString dialogErrorMultipleSelectionNotEnabled;
WString dialogAskCreateFile;
WString dialogAskOverrideFile;
bool isLoadingFiles = false;
filesystem::FilePath loadingPath;
vint loadingTaskId = 0;
Files files;
Regex regexDisplayString{ L";" };
public:
bool selectToSave = false;
bool confirmed = false;
ConfirmedSelection confirmedSelection;
WString title;
bool enabledMultipleSelection = false;
bool fileMustExist = false;
bool folderMustExist = false;
bool promptCreateFile = false;
bool promptOverriteFile = false;
WString defaultExtension;
Filters filters;
Ptr<FileDialogFilter> selectedFilter;
WString initialDirectory;
Ptr<FileDialogFolder> rootFolder;
Ptr<FileDialogFolder> selectedFolder;
WString GetTitle() override
{
return title;
}
bool GetEnabledMultipleSelection() override
{
return enabledMultipleSelection;
}
WString GetDefaultExtension() override
{
return defaultExtension;
}
const Filters& GetFilters() override
{
return filters;
}
Ptr<IFileDialogFilter> GetSelectedFilter() override
{
return selectedFilter;
}
void SetSelectedFilter(Ptr<IFileDialogFilter> value) override
{
if (auto filter = value.Cast<FileDialogFilter>())
{
if (selectedFilter != filter && filters.Contains(value.Obj()))
{
selectedFilter = filter;
SelectedFilterChanged();
}
}
}
Ptr<IFileDialogFolder> GetRootFolder() override
{
return rootFolder;
}
Ptr<IFileDialogFolder> GetSelectedFolder() override
{
return selectedFolder;
}
void SetSelectedFolderInternal(Ptr<IFileDialogFolder> value, bool refreshFile)
{
if (auto folder = value.Cast<FileDialogFolder>())
{
if (selectedFolder != folder)
{
selectedFolder = folder;
SelectedFolderChanged();
if (refreshFile && loadingPath != selectedFolder->folder.GetFilePath())
{
RefreshFiles();
}
}
}
}
void SetSelectedFolderInternal(filesystem::FilePath path, bool refreshFile)
{
List<filesystem::FilePath> fragments;
while (!path.IsRoot())
{
fragments.Add(path);
path = path.GetFolder();
}
auto folder = rootFolder;
// TODO: (enumerable) foreach:reversed
for (vint i = fragments.Count() - 1; i >= 0; i--)
{
auto fragment = fragments[i];
vint index = folder->childrenByName.Keys().IndexOf(fragment.GetName());
if (index == -1)
{
auto child = Ptr(new FileDialogFolder(fragment));
folder->AddChild(child);
child->AddPlaceholderChild();
folder = child;
}
else
{
folder = folder->childrenByName.Values()[index];
}
}
SetSelectedFolderInternal(folder, refreshFile);
}
void SetSelectedFolder(Ptr<IFileDialogFolder> value) override
{
SetSelectedFolderInternal(value, true);
}
bool GetIsLoadingFiles() override
{
return isLoadingFiles;
}
Files& GetFiles() override
{
return files;
}
void RefreshFiles() override
{
if (!selectedFolder) return;
vint taskId = ++loadingTaskId;
auto taskFolder = selectedFolder;
auto taskPath = (loadingPath = selectedFolder->folder.GetFilePath());
if (!isLoadingFiles)
{
isLoadingFiles = true;
IsLoadingFilesChanged();
files.Clear();
{
auto item = Ptr(new FileDialogFile);
item->name = textLoadingFiles;
files.Add(item);
}
}
auto vm = Ptr(this);
GetApplication()->InvokeAsync([taskId, taskFolder, taskPath, vm]()
{
auto folders = Ptr(new List<filesystem::Folder>);
auto files = Ptr(new List<filesystem::File>);
filesystem::Folder loadingFolder = taskPath;
if (!loadingFolder.GetFolders(*folders.Obj()) || !loadingFolder.GetFiles(*files.Obj()))
{
folders->Clear();
files->Clear();
}
GetApplication()->InvokeInMainThread(nullptr, [taskId, taskFolder, folders, files, vm]()
{
if (vm->loadingTaskId == taskId)
{
vm->files.Clear();
for (auto folder : *folders.Obj())
{
auto item = Ptr(new FileDialogFile);
item->type = FileDialogFileType::Folder;
item->name = folder.GetFilePath().GetName();
vint index = taskFolder->childrenByName.Keys().IndexOf(item->name);
if (index == -1)
{
auto associatedFolder = Ptr(new FileDialogFolder(folder));
taskFolder->AddChild(associatedFolder);
associatedFolder->AddPlaceholderChild();
item->associatedFolder = associatedFolder;
}
else
{
item->associatedFolder = taskFolder->childrenByName.Values()[index];
}
vm->files.Add(item);
}
for (auto file : *files.Obj())
{
auto item = Ptr(new FileDialogFile);
item->type = FileDialogFileType::File;
item->name = file.GetFilePath().GetName();
vm->files.Add(item);
}
vm->isLoadingFiles = false;
vm->IsLoadingFilesChanged();
}
});
});
}
WString GetDisplayString(collections::LazyList<Ptr<IFileDialogFile>> files) override
{
return From(files)
.FindType<FileDialogFile>()
.Where([](auto file) { return file->type != FileDialogFileType::Placeholder; })
.Select([](auto file) { return WString::Unmanaged(L"\"") + file->name + WString::Unmanaged(L"\""); })
.Aggregate(WString::Empty, [](auto&& a, auto&& b)
{
return a == WString::Empty ? b : a + WString::Unmanaged(L";") + b;
});
}
Selection ParseDisplayString(const WString& displayString) override
{
auto items = Ptr(new RegexMatch::List);
regexDisplayString.Split(displayString, false, *items.Obj());
return From(LazyList<Ptr<RegexMatch>>(items))
.Select([](auto item) { return item->Result().Value(); })
.Select([](auto item)
{
if (item.Length() >= 2 && item[0] == L'\"' && item[item.Length() - 1] == L'\"')
{
return item.Sub(1, item.Length() - 2);
}
else
{
return item;
}
});
}
bool TryConfirm(controls::GuiWindow* owner, Selection selectedPaths) override
{
auto wd = selectedFolder->folder.GetFilePath();
List<filesystem::FilePath> paths;
CopyFrom(
paths,
selectedPaths.Select([this, wd](auto path) { return wd / path; })
);
if (paths.Count() == 0)
{
GetCurrentController()->DialogService()->ShowMessageBox(
owner->GetNativeWindow(),
dialogErrorEmptySelection,
owner->GetText(),
INativeDialogService::DisplayOK,
INativeDialogService::DefaultFirst,
INativeDialogService::IconError
);
return false;
}
else if (paths.Count() == 1)
{
auto path = paths[0];
if (filesystem::Folder(path).Exists())
{
SetSelectedFolderInternal(path, true);
return false;
}
}
else
{
if (!enabledMultipleSelection)
{
GetCurrentController()->DialogService()->ShowMessageBox(
owner->GetNativeWindow(),
dialogErrorMultipleSelectionNotEnabled,
owner->GetText(),
INativeDialogService::DisplayOK,
INativeDialogService::DefaultFirst,
INativeDialogService::IconError
);
return false;
}
}
List<vint> files, folders, unexistings;
for (auto [path, index] : indexed(paths))
{
if (filesystem::File(path).Exists())
{
files.Add(index);
}
else if (filesystem::Folder(path).Exists())
{
folders.Add(index);
}
else
{
unexistings.Add(index);
}
}
if (folders.Count() > 0)
{
auto message = stream::GenerateToStream([&](stream::TextWriter& writer)
{
writer.WriteString(dialogErrorFileExpected);
for (vint index : folders)
{
writer.WriteLine(WString::Empty);
writer.WriteString(L" ");
writer.WriteString(wd.GetRelativePathFor(paths[index]));
}
});
GetCurrentController()->DialogService()->ShowMessageBox(
owner->GetNativeWindow(),
message,
owner->GetText(),
INativeDialogService::DisplayOK,
INativeDialogService::DefaultFirst,
INativeDialogService::IconError
);
return false;
}
if (unexistings.Count() > 0)
{
if (fileMustExist)
{
auto message = stream::GenerateToStream([&](stream::TextWriter& writer)
{
writer.WriteString(dialogErrorFileNotExist);
for (vint index : unexistings)
{
writer.WriteLine(WString::Empty);
writer.WriteString(L" ");
writer.WriteString(wd.GetRelativePathFor(paths[index]));
}
});
GetCurrentController()->DialogService()->ShowMessageBox(
owner->GetNativeWindow(),
message,
owner->GetText(),
INativeDialogService::DisplayOK,
INativeDialogService::DefaultFirst,
INativeDialogService::IconError
);
return false;
}
if (folderMustExist)
{
SortedList<filesystem::FilePath> folderOfUnexistings;
for (vint index : unexistings)
{
auto path = paths[index].GetFolder();
if(!folderOfUnexistings.Contains(path))
{
folderOfUnexistings.Add(path);
}
}
// TODO: (enumerable) foreach:indexed(alterable(reversed))
for (vint i = folderOfUnexistings.Count() - 1; i >= 0; i--)
{
if (filesystem::Folder(folderOfUnexistings[i]).Exists())
{
folderOfUnexistings.RemoveAt(i);
}
}
if (folderOfUnexistings.Count() > 0)
{
auto message = stream::GenerateToStream([&](stream::TextWriter& writer)
{
writer.WriteString(dialogErrorFolderNotExist);
for (auto path : folderOfUnexistings)
{
writer.WriteLine(WString::Empty);
writer.WriteString(L" ");
writer.WriteString(wd.GetRelativePathFor(path));
}
});
GetCurrentController()->DialogService()->ShowMessageBox(
owner->GetNativeWindow(),
message,
owner->GetText(),
INativeDialogService::DisplayOK,
INativeDialogService::DefaultFirst,
INativeDialogService::IconError
);
return false;
}
}
WString questionMessage;
List<vint>* questionFiles = nullptr;
if (selectToSave && promptOverriteFile)
{
questionMessage = dialogAskOverrideFile;
questionFiles = &files;
}
if (!selectToSave && promptCreateFile)
{
questionMessage = dialogAskCreateFile;
questionFiles = &unexistings;
}
if (questionFiles && questionFiles->Count() > 0)
{
auto message = stream::GenerateToStream([&](stream::TextWriter& writer)
{
writer.WriteString(questionMessage);
for (vint index : *questionFiles)
{
writer.WriteLine(WString::Empty);
writer.WriteString(L" ");
writer.WriteString(wd.GetRelativePathFor(paths[index]));
}
});
auto result = GetCurrentController()->DialogService()->ShowMessageBox(
owner->GetNativeWindow(),
message,
owner->GetText(),
INativeDialogService::DisplayOKCancel,
INativeDialogService::DefaultThird,
INativeDialogService::IconQuestion
);
if (result == INativeDialogService::SelectCancel)
{
return false;
}
}
}
CopyFrom(
confirmedSelection,
From(paths).Select([](auto path) { return path.GetFullPath(); })
);
Nullable<WString> extension;
bool extensionFromFilter = false;
if (selectedFilter)
{
extension = selectedFilter->GetDefaultExtension();
extensionFromFilter = extension;
}
if (!extensionFromFilter && defaultExtension != WString::Empty)
{
extension = defaultExtension;
}
if (extension)
{
auto&& sExt = WString::Unmanaged(L".") + extension.Value();
vint lExt = sExt.Length();
// TODO: (enumerable) foreach
for (vint i = 0; i < confirmedSelection.Count(); i++)
{
WString& selection = confirmedSelection[i];
if (extensionFromFilter)
{
if (selection.Length() >= lExt && selection.Right(lExt) == sExt)
{
continue;
}
}
else
{
auto selectedFileName = filesystem::FilePath(selection).GetName();
if (INVLOC.FindFirst(selectedFileName, WString::Unmanaged(L"."), Locale::None).key != -1)
{
continue;
}
}
selection += sExt;
}
}
confirmed = true;
return true;
}
void InitLocalizedText(
const WString& _textLoadingFolders,
const WString& _textLoadingFiles,
const WString& _dialogErrorEmptySelection,
const WString& _dialogErrorFileNotExist,
const WString& _dialogErrorFileExpected,
const WString& _dialogErrorFolderNotExist,
const WString& _dialogErrorMultipleSelectionNotEnabled,
const WString& _dialogAskCreateFile,
const WString& _dialogAskOverrideFile
) override
{
textLoadingFolders = _textLoadingFolders;
textLoadingFiles = _textLoadingFiles;
dialogErrorEmptySelection = _dialogErrorEmptySelection;
dialogErrorFileNotExist = _dialogErrorFileNotExist;
dialogErrorFileExpected = _dialogErrorFileExpected;
dialogErrorFolderNotExist = _dialogErrorFolderNotExist;
dialogErrorMultipleSelectionNotEnabled = _dialogErrorMultipleSelectionNotEnabled;
dialogAskCreateFile = _dialogAskCreateFile;
dialogAskOverrideFile = _dialogAskOverrideFile;
rootFolder->textLoadingFolders = textLoadingFolders;
rootFolder->AddPlaceholderChild();
if (initialDirectory != WString::Empty)
{
filesystem::FilePath path = initialDirectory;
if (filesystem::Folder(path).Exists())
{
SetSelectedFolderInternal(path, false);
return;
}
}
SetSelectedFolderInternal(rootFolder, false);
}
};
/***********************************************************************
FakeDialogServiceBase
***********************************************************************/
bool FakeDialogServiceBase::ShowFileDialog(
INativeWindow* window,
collections::List<WString>& selectionFileNames,
vint& selectionFilterIndex,
FileDialogTypes dialogType,
const WString& title,
const WString& initialFileName,
const WString& initialDirectory,
const WString& defaultExtension,
const WString& filter,
FileDialogOptions options
)
{
auto vm = Ptr(new FileDialogViewModel);
vm->title = title;
vm->enabledMultipleSelection = (options & INativeDialogService::FileDialogAllowMultipleSelection) != 0;
vm->fileMustExist = (options & INativeDialogService::FileDialogFileMustExist) != 0;
vm->folderMustExist = (options & INativeDialogService::FileDialogDirectoryMustExist) != 0;
vm->promptCreateFile = (options & INativeDialogService::FileDialogPromptCreateFile) != 0;
vm->promptOverriteFile = (options & INativeDialogService::FileDialogPromptOverwriteFile) != 0;
vm->defaultExtension = defaultExtension;
Regex regexFilterExt(L"/*.[^*?]+");
Regex regexWildcard(L"[*? ]");
vint filterStart = 0;
while (true)
{
vint first = -1;
vint second = -1;
vint count = filter.Length();
for (vint i = filterStart; i < count; i++)
{
if (filter[i] == L'|')
{
first = i;
break;
}
}
if (first == -1) break;
for (vint i = first + 1; i < count; i++)
{
if (filter[i] == L'|')
{
second = i;
break;
}
}
auto filterItem = Ptr(new FileDialogFilter);
filterItem->name = filter.Sub(filterStart, first - filterStart);
filterItem->filter = filter.Sub(first + 1, (second == -1 ? count : second) - first - 1);
if (auto match = regexFilterExt.MatchHead(filterItem->filter))
{
if (match->Result().Length() == filterItem->filter.Length())
{
filterItem->defaultExtension = filterItem->filter.Right(filterItem->filter.Length() - 2);
}
}
auto regexFilter = stream::GenerateToStream([&](stream::TextWriter& writer)
{
writer.WriteChar(L'^');
List<Ptr<RegexMatch>> matches;
regexWildcard.Cut(filterItem->filter, false, matches);
for (auto match : matches)
{
if (match->Success())
{
if (match->Result().Value() == WString::Unmanaged(L"*"))
{
writer.WriteString(WString::Unmanaged(L"/.*"));
}
else
{
writer.WriteString(WString::Unmanaged(L"/."));
}
}
else
{
writer.WriteString(u32tow(regex_internal::EscapeTextForRegex(wtou32(match->Result().Value()))));
}
}
writer.WriteChar(L'$');
});
filterItem->regexFilter = Ptr(new Regex(regexFilter));
vm->filters.Add(filterItem);
if (second == -1) break;
filterStart = second + 1;
}
if (vm->filters.Count() > 0)
{
if (selectionFilterIndex < 0 || vm->filters.Count() <= selectionFilterIndex)
{
selectionFilterIndex = 0;
}
vm->selectedFilter = vm->filters[selectionFilterIndex].Cast<FileDialogFilter>();
}
vm->initialDirectory = initialDirectory;
vm->rootFolder = Ptr(new FileDialogFolder);
vm->rootFolder->type = FileDialogFolderType::Root;
switch (dialogType)
{
case INativeDialogService::FileDialogOpen:
case INativeDialogService::FileDialogOpenPreview:
{
vm->selectToSave = false;
auto owner = GetApplication()->GetWindowFromNative(window);
auto dialog = CreateOpenFileDialog(vm);
ShowModalDialogAndDelete(vm, owner, dialog);
}
break;
case INativeDialogService::FileDialogSave:
case INativeDialogService::FileDialogSavePreview:
{
vm->selectToSave = true;
auto owner = GetApplication()->GetWindowFromNative(window);
auto dialog = CreateSaveFileDialog(vm);
ShowModalDialogAndDelete(vm, owner, dialog);
}
break;
}
if (vm->filters.Count() > 0)
{
selectionFilterIndex = vm->filters.IndexOf(vm->selectedFilter.Obj());
}
if (vm->confirmed)
{
CopyFrom(selectionFileNames, vm->confirmedSelection);
}
return vm->confirmed;
}
}
}
/***********************************************************************
.\UTILITIES\FAKESERVICES\GUIFAKEDIALOGSERVICEBASE_FONTDIALOG.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
using namespace controls;
/***********************************************************************
View Model (ICommonFontDialogViewModel)
***********************************************************************/
template<typename IViewModel>
class FakeFontDialogViewModel : public Object, public virtual IViewModel
{
public:
using FontList = collections::List<WString>;
bool confirmed = false;
bool fontMustExist = false;
FontList fontList;
bool GetConfirmed() override { return confirmed; }
void SetConfirmed(bool value) override { confirmed = value; }
bool GetFontMustExist() override { return fontMustExist; }
const FontList& GetFontList() override { return fontList; }
};
/***********************************************************************
View Model (ISimpleFontDialogViewModel)
***********************************************************************/
class FakeSimpleFontDialogViewModel : public FakeFontDialogViewModel<ISimpleFontDialogViewModel>
{
public:
WString fontFamily;
vint fontSize = 0;
WString GetFontFamily() override { return fontFamily; }
void SetFontFamily(const WString& value) override { fontFamily = value; }
vint GetFontSize() override { return fontSize; }
void SetFontSize(vint value) override { fontSize = value; }
};
/***********************************************************************
View Model (IFullFontDialogViewModel)
***********************************************************************/
class FakeFullFontDialogViewModel : public FakeFontDialogViewModel<IFullFontDialogViewModel>
{
public:
Color color;
FontProperties font;
Color GetColor() override { return color; }
void SetColor(Color value) override { color = value; }
FontProperties GetFont() override { return font; }
void SetFont(const FontProperties& value) override { font = value; }
bool SelectColor(controls::GuiWindow* owner) override
{
return GetCurrentController()->DialogService()->ShowColorDialog(
owner->GetNativeWindow(),
color
);
}
};
/***********************************************************************
FakeDialogServiceBase
***********************************************************************/
bool FakeDialogServiceBase::ShowFontDialog(
INativeWindow* window,
FontProperties& selectionFont,
Color& selectionColor,
bool selected,
bool showEffect,
bool forceFontExist
)
{
auto initVm = [=](auto vm)
{
vm->fontMustExist = forceFontExist;
GetCurrentController()->ResourceService()->EnumerateFonts(vm->fontList);
if (vm->fontList.Count() > 0)
{
Sort(&vm->fontList[0], vm->fontList.Count());
}
};
if (showEffect)
{
auto vm = Ptr(new FakeFullFontDialogViewModel);
initVm(vm);
vm->font = selectionFont;
vm->color = selectionColor;
{
auto owner = GetApplication()->GetWindowFromNative(window);
auto dialog = CreateFullFontDialog(vm);
ShowModalDialogAndDelete(vm, owner, dialog);
}
if (vm->confirmed)
{
selectionFont = vm->font;
selectionColor = vm->color;
}
return vm->confirmed;
}
else
{
auto vm = Ptr(new FakeSimpleFontDialogViewModel);
initVm(vm);
vm->fontFamily = selectionFont.fontFamily;
vm->fontSize = selectionFont.size;
{
auto owner = GetApplication()->GetWindowFromNative(window);
auto dialog = CreateSimpleFontDialog(vm);
ShowModalDialogAndDelete(vm, owner, dialog);
}
if (vm->confirmed)
{
selectionFont.fontFamily = vm->fontFamily;
selectionFont.size = vm->fontSize;
}
return vm->confirmed;
}
}
}
}
/***********************************************************************
.\UTILITIES\FAKESERVICES\GUIFAKEDIALOGSERVICEBASE_MESSAGEBOX.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace controls;
/***********************************************************************
View Model (IMessageBoxDialogViewModel)
***********************************************************************/
class FakeMessageBoxDialogViewModel : public Object, public virtual IMessageBoxDialogViewModel
{
public:
class Action : public Object, public virtual IMessageBoxDialogAction
{
public:
FakeMessageBoxDialogViewModel* viewModel;
ButtonItem button;
Action(FakeMessageBoxDialogViewModel* _viewModel, ButtonItem _button)
: viewModel(_viewModel)
, button(_button)
{
}
ButtonItem GetButton() override { return button; }
void PerformAction() override { viewModel->result = Ptr(this); }
};
WString text;
WString title;
Icon icon;
ButtonItemList buttons;
ButtonItem defaultButton;
ButtonItem result;
WString GetText() override { return text; }
WString GetTitle() override { return title; }
Icon GetIcon() override { return icon; }
const ButtonItemList& GetButtons() override { return buttons; }
ButtonItem GetDefaultButton() override { return defaultButton; }
ButtonItem GetResult() override { return result; }
};
/***********************************************************************
FakeDialogServiceBase
***********************************************************************/
FakeDialogServiceBase::MessageBoxButtonsOutput FakeDialogServiceBase::ShowMessageBox(
INativeWindow* window,
const WString& text,
const WString& title,
MessageBoxButtonsInput buttons,
MessageBoxDefaultButton defaultButton,
MessageBoxIcons icon,
MessageBoxModalOptions modal
)
{
auto vm = Ptr(new FakeMessageBoxDialogViewModel);
vm->text = text;
vm->title = title;
vm->icon = icon;
#define USE_BUTTON(NAME) vm->buttons.Add(Ptr(new FakeMessageBoxDialogViewModel::Action(vm.Obj(), INativeDialogService::Select##NAME)))
switch (buttons)
{
case DisplayOK: USE_BUTTON(OK); break;
case DisplayOKCancel: USE_BUTTON(OK); USE_BUTTON(Cancel); break;
case DisplayYesNo: USE_BUTTON(Yes); USE_BUTTON(No); break;
case DisplayYesNoCancel: USE_BUTTON(Yes); USE_BUTTON(No); USE_BUTTON(Cancel); break;
case DisplayRetryCancel: USE_BUTTON(Retry); USE_BUTTON(Cancel); break;
case DisplayAbortRetryIgnore: USE_BUTTON(Abort); USE_BUTTON(Retry); USE_BUTTON(Ignore); break;
case DisplayCancelTryAgainContinue: USE_BUTTON(Cancel); USE_BUTTON(TryAgain); USE_BUTTON(Continue); break;
default: USE_BUTTON(OK); break;
}
#undef USE_BUTTON
#define USE_DEFAULT_BUTTON(INDEX) if (vm->buttons.Count() > INDEX) vm->defaultButton = vm->buttons[INDEX]
USE_DEFAULT_BUTTON(0);
switch (defaultButton)
{
case DefaultSecond: USE_DEFAULT_BUTTON(1); break;
case DefaultThird: USE_DEFAULT_BUTTON(2); break;
default:;
}
#undef USE_DEFAULT_BUTTON
vm->result = vm->defaultButton;
{
auto owner = GetApplication()->GetWindowFromNative(window);
auto dialog = CreateMessageBoxDialog(vm);
ShowModalDialogAndDelete(vm, owner, dialog);
}
return vm->result->GetButton();
}
}
}
/***********************************************************************
.\UTILITIES\FAKESERVICES\DIALOGS\GUIFAKEDIALOGSERVICE.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace controls;
/***********************************************************************
FakeDialogService
***********************************************************************/
controls::GuiWindow* FakeDialogService::CreateMessageBoxDialog(Ptr< IMessageBoxDialogViewModel> viewModel)
{
return new gaclib_controls::MessageBoxWindow(viewModel);
}
controls::GuiWindow* FakeDialogService::CreateColorDialog(Ptr<IColorDialogViewModel> viewModel)
{
return new gaclib_controls::ColorDialogWindow(viewModel);
}
controls::GuiWindow* FakeDialogService::CreateSimpleFontDialog(Ptr<ISimpleFontDialogViewModel> viewModel)
{
return new gaclib_controls::SimpleFontDialogWindow(viewModel);
}
controls::GuiWindow* FakeDialogService::CreateFullFontDialog(Ptr<IFullFontDialogViewModel> viewModel)
{
return new gaclib_controls::FullFontDialogWindow(viewModel);
}
controls::GuiWindow* FakeDialogService::CreateOpenFileDialog(Ptr<IFileDialogViewModel> viewModel)
{
auto dialog = new gaclib_controls::FileDialogWindow(viewModel);
dialog->MakeOpenFileDialog();
return dialog;
}
controls::GuiWindow* FakeDialogService::CreateSaveFileDialog(Ptr<IFileDialogViewModel> viewModel)
{
auto dialog = new gaclib_controls::FileDialogWindow(viewModel);
dialog->MakeSaveFileDialog();
return dialog;
}
FakeDialogService::FakeDialogService()
{
}
FakeDialogService::~FakeDialogService()
{
}
}
}
/***********************************************************************
.\UTILITIES\FAKESERVICES\DIALOGS\SOURCE\GUIFAKEDIALOGSERVICEUI.CPP
***********************************************************************/
/***********************************************************************
!!!!!! DO NOT MODIFY !!!!!!
Source: GacUI FakeDialogServiceUI
This file is generated by Workflow compiler
https://github.com/vczh-libraries
***********************************************************************/
#if defined( _MSC_VER)
#pragma warning(push)
#pragma warning(disable:4250)
#elif defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wparentheses-equality"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#endif
#define GLOBAL_SYMBOL ::vl_workflow_global::GuiFakeDialogServiceUI::
#define GLOBAL_NAME ::vl_workflow_global::GuiFakeDialogServiceUI::Instance().
#define GLOBAL_OBJ &::vl_workflow_global::GuiFakeDialogServiceUI::Instance()
/***********************************************************************
Global Variables
***********************************************************************/
BEGIN_GLOBAL_STORAGE_CLASS(vl_workflow_global_GuiFakeDialogServiceUI)
vl_workflow_global::GuiFakeDialogServiceUI instance;
INITIALIZE_GLOBAL_STORAGE_CLASS
instance.__vwsn_ls_DialogStrings = ::vl::reflection::description::IValueDictionary::Create();
([]()
{
::gaclib_controls::DialogStrings::Install(::vl::__vwsn::Parse<::vl::Locale>(::vl::WString::Unmanaged(L"en-US")), ::gaclib_controls::DialogStrings::__vwsn_ls_en_US_BuildStrings(::vl::__vwsn::Parse<::vl::Locale>(::vl::WString::Unmanaged(L"en-US"))));
}
)();
FINALIZE_GLOBAL_STORAGE_CLASS
instance.__vwsn_ls_DialogStrings = nullptr;
END_GLOBAL_STORAGE_CLASS(vl_workflow_global_GuiFakeDialogServiceUI)
namespace vl_workflow_global
{
/***********************************************************************
Global Functions
***********************************************************************/
GuiFakeDialogServiceUI& GuiFakeDialogServiceUI::Instance()
{
return Getvl_workflow_global_GuiFakeDialogServiceUI().instance;
}
/***********************************************************************
Closures
***********************************************************************/
//-------------------------------------------------------------------
__vwsnf10_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_::__vwsnf10_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_(::gaclib_controls::ColorDialogControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf10_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetValue();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::presentation::Color>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetValue(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf11_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_::__vwsnf11_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_(::gaclib_controls::ColorDialogControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf11_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetStrings();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::Ptr<::gaclib_controls::IDialogStringsStrings>>(__vwsn_value_);
if ((__vwsn_old_.Obj() == __vwsn_new_.Obj()))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetStrings(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf12_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_::__vwsnf12_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_(::gaclib_controls::ColorDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf12_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_4)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_4)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf13_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_::__vwsnf13_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_(::gaclib_controls::ColorDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf13_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const
{
::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->SetConfirmed(true);
::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->SetColor(::vl::__vwsn::This(__vwsnthis_0->colorControl)->GetValue());
::vl::__vwsn::This(__vwsnthis_0->self)->Close();
}
//-------------------------------------------------------------------
__vwsnf14_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_::__vwsnf14_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_(::gaclib_controls::ColorDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf14_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_7)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_7)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf15_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_::__vwsnf15_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_(::gaclib_controls::ColorDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf15_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const
{
::vl::__vwsn::This(__vwsnthis_0->self)->Close();
}
//-------------------------------------------------------------------
__vwsnf16_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_::__vwsnf16_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_(::gaclib_controls::ColorDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf16_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf17_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_::__vwsnf17_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_(::gaclib_controls::ColorDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf17_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetStrings();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::Ptr<::gaclib_controls::IDialogStringsStrings>>(__vwsn_value_);
if ((__vwsn_old_.Obj() == __vwsn_new_.Obj()))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetStrings(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf18_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_::__vwsnf18_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_(::gaclib_controls::FileDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf18_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_::operator()() const
{
::vl::__vwsn::This(::vl::presentation::controls::GetApplication())->InvokeInMainThread(::vl::__vwsn::This(__vwsnthis_0->self)->GetRelatedControlHost(), vl::Func(::vl_workflow_global::__vwsnf19_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__(__vwsnthis_0)));
}
//-------------------------------------------------------------------
__vwsnf19_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__::__vwsnf19_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__(::gaclib_controls::FileDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf19_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__::operator()() const
{
::vl::__vwsn::This(__vwsnthis_0->self)->Close();
}
//-------------------------------------------------------------------
__vwsnf1_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize_::__vwsnf1_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize_(::gaclib_controls::ColorComponentControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf1_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->textBox)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->textBox)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf20_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_::__vwsnf20_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_(::gaclib_controls::FileDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf20_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->buttonOK)->GetEnabled();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<bool>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->buttonOK)->SetEnabled(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf21_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_::__vwsnf21_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_(::gaclib_controls::FileDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf21_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const
{
if (::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->TryConfirm(static_cast<::vl::presentation::controls::GuiWindow*>(__vwsnthis_0->self), ::vl::__vwsn::This(__vwsnthis_0->filePickerControl)->GetSelection()))
{
::vl::__vwsn::This(__vwsnthis_0->self)->Close();
}
}
//-------------------------------------------------------------------
__vwsnf22_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_::__vwsnf22_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_(::gaclib_controls::FileDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf22_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_6)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_6)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf23_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_::__vwsnf23_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_(::gaclib_controls::FileDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf23_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const
{
::vl::__vwsn::This(__vwsnthis_0->self)->Close();
}
//-------------------------------------------------------------------
__vwsnf24_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_::__vwsnf24_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_(::gaclib_controls::FileDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf24_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetStrings();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::Ptr<::gaclib_controls::IDialogStringsStrings>>(__vwsn_value_);
if ((__vwsn_old_.Obj() == __vwsn_new_.Obj()))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetStrings(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf25_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindow___vwsn_instance_ctor__::__vwsnf25_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindow___vwsn_instance_ctor__(::gaclib_controls::FileDialogWindow* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf25_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindow___vwsn_instance_ctor__::operator()() const
{
::vl::__vwsn::This(__vwsnthis_0->filePickerControl)->LocateSelectedFolderInTreeView();
}
//-------------------------------------------------------------------
__vwsnf26_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsnf26_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
::vl::Ptr<::vl::reflection::description::IValueEnumerable> __vwsnf26_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_item_) const
{
auto item = ::vl::__vwsn::Unbox<::vl::Ptr<::vl::presentation::IFileDialogFolder>>(__vwsn_item_);
return ::vl::Ptr<::vl::reflection::description::IValueEnumerable>(::vl::__vwsn::UnboxCollection<::vl::reflection::description::IValueObservableList>(::vl::__vwsn::This(item.Obj())->GetFolders()));
}
//-------------------------------------------------------------------
__vwsnf27_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsnf27_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
::vl::WString __vwsnf27_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_item_) const
{
auto item = ::vl::__vwsn::Unbox<::vl::Ptr<::vl::presentation::IFileDialogFolder>>(__vwsn_item_);
return ::vl::__vwsn::This(item.Obj())->GetName();
}
//-------------------------------------------------------------------
__vwsnf28_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsnf28_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
::vl::WString __vwsnf28_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_item_) const
{
auto item = ::vl::__vwsn::Unbox<::vl::Ptr<::vl::presentation::IFileDialogFile>>(__vwsn_item_);
return ::vl::__vwsn::This(item.Obj())->GetName();
}
//-------------------------------------------------------------------
__vwsnf29_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsnf29_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
::vl::WString __vwsnf29_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_item_) const
{
auto item = ::vl::__vwsn::Unbox<::vl::Ptr<::vl::presentation::IFileDialogFilter>>(__vwsn_item_);
return ::vl::__vwsn::This(item.Obj())->GetName();
}
//-------------------------------------------------------------------
__vwsnf2_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize_::__vwsnf2_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize_(::gaclib_controls::ColorComponentControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf2_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->textBox)->GetAlt();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->textBox)->SetAlt(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf30_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsnf30_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf30_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_2)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_2)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf32_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsnf32_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf32_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->dataGrid)->GetAdditionalFilter();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::Ptr<::vl::presentation::controls::list::IDataFilter>>(__vwsn_value_);
if ((__vwsn_old_.Obj() == __vwsn_new_.Obj()))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->dataGrid)->SetAdditionalFilter(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf33_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsnf33_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf33_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiKeyEventArgs* arguments) const
{
if (((((! ::vl::__vwsn::This(arguments)->ctrl) && (! ::vl::__vwsn::This(arguments)->shift)) && (! ::vl::__vwsn::This(arguments)->alt)) && (::vl::__vwsn::This(arguments)->code == ::vl::presentation::VKEY::KEY_RETURN)))
{
if (::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->TryConfirm(::vl::__vwsn::Ensure(::vl::__vwsn::RawPtrCast<::vl::presentation::controls::GuiWindow>(::vl::__vwsn::This(__vwsnthis_0->self)->GetRelatedControlHost())), ::vl::__vwsn::This(__vwsnthis_0->self)->GetSelection()))
{
::vl::__vwsn::EventInvoke(::vl::__vwsn::This(__vwsnthis_0->self)->RequestClose)();
}
}
}
//-------------------------------------------------------------------
__vwsnf35_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsnf35_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf35_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const
{
::vl::__vwsn::This(__vwsnthis_0->textBox)->SetText(::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->GetDisplayString(::vl::__vwsn::This(__vwsnthis_0->self)->GetSelectedFiles()));
::vl::__vwsn::This(__vwsnthis_0->textBox)->Select([&](){ ::vl::presentation::TextPos __vwsn_temp__; __vwsn_temp__.row = static_cast<::vl::vint>(0); __vwsn_temp__.column = static_cast<::vl::vint>(0); return __vwsn_temp__; }(), [&](){ ::vl::presentation::TextPos __vwsn_temp__; __vwsn_temp__.row = static_cast<::vl::vint>(0); __vwsn_temp__.column = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
//-------------------------------------------------------------------
__vwsnf36_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsnf36_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf36_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiItemMouseEventArgs* arguments) const
{
auto file = ::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->GetFiles()[::vl::__vwsn::This(arguments)->itemIndex];
auto selection = ::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->ParseDisplayString(::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->GetDisplayString(::vl::reflection::description::GetLazyList<::vl::Ptr<::vl::presentation::IFileDialogFile>>((::vl::__vwsn::CreateList().Add(file)).list)));
::vl::__vwsn::This(::vl::presentation::controls::GetApplication())->InvokeInMainThread(::vl::__vwsn::This(__vwsnthis_0->self)->GetRelatedControlHost(), vl::Func(::vl_workflow_global::__vwsnf37_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__(selection, __vwsnthis_0)));
}
//-------------------------------------------------------------------
__vwsnf37_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__::__vwsnf37_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__(::vl::collections::LazyList<::vl::WString> __vwsnctor_selection, ::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:selection(__vwsnctor_selection)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf37_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__::operator()() const
{
if (::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->TryConfirm(::vl::__vwsn::Ensure(::vl::__vwsn::RawPtrCast<::vl::presentation::controls::GuiWindow>(::vl::__vwsn::This(__vwsnthis_0->self)->GetRelatedControlHost())), this->selection))
{
::vl::__vwsn::EventInvoke(::vl::__vwsn::This(__vwsnthis_0->self)->RequestClose)();
}
}
//-------------------------------------------------------------------
__vwsnf38_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsnf38_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf38_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_17)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_17)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf39_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsnf39_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf39_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiKeyEventArgs* arguments) const
{
if (((((! ::vl::__vwsn::This(arguments)->ctrl) && (! ::vl::__vwsn::This(arguments)->shift)) && (! ::vl::__vwsn::This(arguments)->alt)) && (::vl::__vwsn::This(arguments)->code == ::vl::presentation::VKEY::KEY_RETURN)))
{
if (::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->TryConfirm(::vl::__vwsn::Ensure(::vl::__vwsn::RawPtrCast<::vl::presentation::controls::GuiWindow>(::vl::__vwsn::This(__vwsnthis_0->self)->GetRelatedControlHost())), ::vl::__vwsn::This(__vwsnthis_0->self)->GetSelection()))
{
::vl::__vwsn::EventInvoke(::vl::__vwsn::This(__vwsnthis_0->self)->RequestClose)();
}
}
}
//-------------------------------------------------------------------
__vwsnf3_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize_::__vwsnf3_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize_(::gaclib_controls::ColorComponentControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf3_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const
{
auto value = [&](){ try{ return ::vl::__vwsn::Parse<::vl::vint>(::vl::__vwsn::This(__vwsnthis_0->textBox)->GetText()); } catch(...){ return (- static_cast<::vl::vint>(1)); } }();
if ((value == (- static_cast<::vl::vint>(1))))
{
return;
}
else if ((value < static_cast<::vl::vint>(0)))
{
::vl::__vwsn::This(__vwsnthis_0->tracker)->SetPosition(static_cast<::vl::vint>(0));
}
else if ((value > static_cast<::vl::vint>(255)))
{
::vl::__vwsn::This(__vwsnthis_0->tracker)->SetPosition(static_cast<::vl::vint>(255));
}
else
{
::vl::__vwsn::This(__vwsnthis_0->tracker)->SetPosition(value);
}
}
//-------------------------------------------------------------------
__vwsnf40_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsnf40_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf40_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_24.Obj())->GetSelectedFilter();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::Ptr<::vl::presentation::IFileDialogFilter>>(__vwsn_value_);
if ((__vwsn_old_.Obj() == __vwsn_new_.Obj()))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_24.Obj())->SetSelectedFilter(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf41_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsnf41_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf41_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_24.Obj())->GetSelectedFolder();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::Ptr<::vl::presentation::IFileDialogFolder>>(__vwsn_value_);
if ((__vwsn_old_.Obj() == __vwsn_new_.Obj()))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_24.Obj())->SetSelectedFolder(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf42_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsnf42_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf42_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()() const
{
::vl::__vwsn::This(__vwsnthis_0->self)->LocateSelectedFolderInTreeView();
}
//-------------------------------------------------------------------
__vwsnf43_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsnf43_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf43_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetStrings();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::Ptr<::gaclib_controls::IDialogStringsStrings>>(__vwsn_value_);
if ((__vwsn_old_.Obj() == __vwsn_new_.Obj()))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetStrings(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf44_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_GetSelectedFiles_::__vwsnf44_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_GetSelectedFiles_(::gaclib_controls::FilePickerControl* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
::vl::Ptr<::vl::reflection::description::ICoroutine> __vwsnf44_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_GetSelectedFiles_::operator()(::vl::reflection::description::EnumerableCoroutine::IImpl* __vwsn_co_impl_) const
{
return ::vl::Ptr<::vl::reflection::description::ICoroutine>(new ::vl_workflow_global::__vwsnc24_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_GetSelectedFiles___vl_reflection_description_ICoroutine(__vwsn_co_impl_, __vwsnthis_0));
}
//-------------------------------------------------------------------
__vwsnf46_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_::__vwsnf46_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_(::gaclib_controls::FontNameControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf46_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const
{
if (((::vl::__vwsn::This(__vwsnthis_0->textList)->GetSelectedItemIndex() != (- static_cast<::vl::vint>(1))) && (::vl::__vwsn::This(__vwsnthis_0->textBox)->GetText() != ::vl::__vwsn::This(__vwsnthis_0->textList)->GetSelectedItemText())))
{
::vl::__vwsn::This(__vwsnthis_0->textBox)->SetText(::vl::__vwsn::This(__vwsnthis_0->textList)->GetSelectedItemText());
}
}
//-------------------------------------------------------------------
__vwsnf47_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_::__vwsnf47_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_(::gaclib_controls::FontNameControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf47_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_0)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_0)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf48_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_::__vwsnf48_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_(::gaclib_controls::FontNameControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf48_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetValue();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetValue(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf49_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_::__vwsnf49_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_(::gaclib_controls::FontNameControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf49_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetLegal();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<bool>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetLegal(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf4_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize_::__vwsnf4_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize_(::gaclib_controls::ColorComponentControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf4_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetValue();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::vint>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetValue(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf50_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_::__vwsnf50_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_(::gaclib_controls::FontNameControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf50_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_::operator()() const
{
::vl::__vwsn::This(__vwsnthis_0->self)->UpdateSelectedIndex();
}
//-------------------------------------------------------------------
__vwsnf51_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_::__vwsnf51_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_(::gaclib_controls::FontNameControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf51_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetStrings();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::Ptr<::gaclib_controls::IDialogStringsStrings>>(__vwsn_value_);
if ((__vwsn_old_.Obj() == __vwsn_new_.Obj()))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetStrings(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf53_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_::__vwsnf53_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_(::gaclib_controls::FontSizeControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf53_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const
{
if (((::vl::__vwsn::This(__vwsnthis_0->textList)->GetSelectedItemIndex() != (- static_cast<::vl::vint>(1))) && (::vl::__vwsn::This(__vwsnthis_0->textBox)->GetText() != ::vl::__vwsn::This(__vwsnthis_0->textList)->GetSelectedItemText())))
{
::vl::__vwsn::This(__vwsnthis_0->textBox)->SetText(::vl::__vwsn::This(__vwsnthis_0->textList)->GetSelectedItemText());
}
}
//-------------------------------------------------------------------
__vwsnf54_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_::__vwsnf54_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_(::gaclib_controls::FontSizeControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf54_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_0)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_0)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf55_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_::__vwsnf55_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_(::gaclib_controls::FontSizeControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf55_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetValue();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::vint>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetValue(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf56_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_::__vwsnf56_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_(::gaclib_controls::FontSizeControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf56_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetLegal();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<bool>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetLegal(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf57_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_::__vwsnf57_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_(::gaclib_controls::FontSizeControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf57_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_::operator()() const
{
::vl::__vwsn::This(__vwsnthis_0->self)->UpdateSelectedIndex();
}
//-------------------------------------------------------------------
__vwsnf58_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_::__vwsnf58_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_(::gaclib_controls::FontSizeControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf58_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetStrings();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::Ptr<::gaclib_controls::IDialogStringsStrings>>(__vwsn_value_);
if ((__vwsn_old_.Obj() == __vwsn_new_.Obj()))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetStrings(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf59_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf59_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf59_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->checkBold)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->checkBold)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf5_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_::__vwsnf5_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_(::gaclib_controls::ColorDialogControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf5_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_2)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_2)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf60_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf60_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf60_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->checkItalic)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->checkItalic)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf61_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf61_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf61_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->checkUnderline)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->checkUnderline)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf62_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf62_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf62_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->checkStrikeline)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->checkStrikeline)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf63_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf63_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf63_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->checkHAA)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->checkHAA)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf64_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf64_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf64_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->checkVAA)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->checkVAA)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf65_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf65_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf65_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_8)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_8)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf66_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf66_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf66_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiMouseEventArgs* arguments) const
{
if (::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->SelectColor(static_cast<::vl::presentation::controls::GuiWindow*>(__vwsnthis_0->self)))
{
::vl::__vwsn::This(__vwsnthis_0->colorBackground.Obj())->SetColor(::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->GetColor());
}
}
//-------------------------------------------------------------------
__vwsnf67_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf67_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf67_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_18)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_18)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf68_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf68_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf68_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_26)->GetFont();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::Nullable<::vl::presentation::FontProperties>>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_26)->SetFont(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf69_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf69_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf69_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_23)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_23)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf6_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_::__vwsnf6_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_(::gaclib_controls::ColorDialogControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf6_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_4)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_4)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf70_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf70_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf70_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_30)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_30)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf71_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf71_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf71_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_30)->GetEnabled();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<bool>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_30)->SetEnabled(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf72_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf72_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf72_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const
{
::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->SetConfirmed(true);
::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->SetFont([&](){ ::vl::presentation::FontProperties __vwsn_temp__; __vwsn_temp__.fontFamily = ::vl::__vwsn::This(__vwsnthis_0->nameControl)->GetValue(); __vwsn_temp__.size = ::vl::__vwsn::This(__vwsnthis_0->sizeControl)->GetValue(); __vwsn_temp__.bold = ::vl::__vwsn::This(__vwsnthis_0->checkBold)->GetSelected(); __vwsn_temp__.italic = ::vl::__vwsn::This(__vwsnthis_0->checkItalic)->GetSelected(); __vwsn_temp__.underline = ::vl::__vwsn::This(__vwsnthis_0->checkUnderline)->GetSelected(); __vwsn_temp__.strikeline = ::vl::__vwsn::This(__vwsnthis_0->checkStrikeline)->GetSelected(); __vwsn_temp__.antialias = ::vl::__vwsn::This(__vwsnthis_0->checkHAA)->GetSelected(); __vwsn_temp__.verticalAntialias = ::vl::__vwsn::This(__vwsnthis_0->checkVAA)->GetSelected(); return __vwsn_temp__; }());
::vl::__vwsn::This(__vwsnthis_0->self)->Close();
}
//-------------------------------------------------------------------
__vwsnf73_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf73_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf73_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_33)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_33)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf74_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf74_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf74_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const
{
::vl::__vwsn::This(__vwsnthis_0->self)->Close();
}
//-------------------------------------------------------------------
__vwsnf75_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf75_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf75_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf76_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::__vwsnf76_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf76_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetStrings();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::Ptr<::gaclib_controls::IDialogStringsStrings>>(__vwsn_value_);
if ((__vwsn_old_.Obj() == __vwsn_new_.Obj()))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetStrings(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf77_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::__vwsnf77_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(::gaclib_controls::SimpleFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf77_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_11)->GetFont();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::Nullable<::vl::presentation::FontProperties>>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_11)->SetFont(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf78_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::__vwsnf78_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(::gaclib_controls::SimpleFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf78_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_8)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_8)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf79_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::__vwsnf79_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(::gaclib_controls::SimpleFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf79_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_15)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_15)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf7_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_::__vwsnf7_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_(::gaclib_controls::ColorDialogControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf7_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_6)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_6)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf80_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::__vwsnf80_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(::gaclib_controls::SimpleFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf80_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_15)->GetEnabled();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<bool>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_15)->SetEnabled(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf81_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::__vwsnf81_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(::gaclib_controls::SimpleFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf81_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const
{
::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->SetConfirmed(true);
::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->SetFontFamily(::vl::__vwsn::This(__vwsnthis_0->nameControl)->GetValue());
::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->SetFontSize(::vl::__vwsn::This(__vwsnthis_0->sizeControl)->GetValue());
::vl::__vwsn::This(__vwsnthis_0->self)->Close();
}
//-------------------------------------------------------------------
__vwsnf82_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::__vwsnf82_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(::gaclib_controls::SimpleFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf82_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_18)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_18)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf83_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::__vwsnf83_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(::gaclib_controls::SimpleFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf83_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const
{
::vl::__vwsn::This(__vwsnthis_0->self)->Close();
}
//-------------------------------------------------------------------
__vwsnf84_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::__vwsnf84_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(::gaclib_controls::SimpleFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf84_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf85_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::__vwsnf85_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(::gaclib_controls::SimpleFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf85_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetStrings();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::Ptr<::gaclib_controls::IDialogStringsStrings>>(__vwsn_value_);
if ((__vwsn_old_.Obj() == __vwsn_new_.Obj()))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetStrings(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf86_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize_::__vwsnf86_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize_(::gaclib_controls::MessageBoxButtonTemplateConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf86_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->buttonControl)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->buttonControl)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf87_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize_::__vwsnf87_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize_(::gaclib_controls::MessageBoxButtonTemplateConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf87_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const
{
::vl::__vwsn::This(__vwsnthis_0->Action.Obj())->PerformAction();
::vl::__vwsn::This(::vl::__vwsn::This(__vwsnthis_0->self)->GetRelatedControlHost())->Close();
}
//-------------------------------------------------------------------
__vwsnf88_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize_::__vwsnf88_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize_(::gaclib_controls::MessageBoxButtonTemplateConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf88_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetStrings();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::Ptr<::gaclib_controls::IDialogStringsStrings>>(__vwsn_value_);
if ((__vwsn_old_.Obj() == __vwsn_new_.Obj()))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->self)->SetStrings(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf89_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxWindowConstructor___vwsn_gaclib_controls_MessageBoxWindow_Initialize_::__vwsnf89_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxWindowConstructor___vwsn_gaclib_controls_MessageBoxWindow_Initialize_(::gaclib_controls::MessageBoxWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
::vl::presentation::templates::GuiTemplate* __vwsnf89_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxWindowConstructor___vwsn_gaclib_controls_MessageBoxWindow_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_viewModel_) const
{
{
if ([&](){ auto __vwsn_temp__ = __vwsn_viewModel_; return __vwsn_temp__.GetSharedPtr() && ::vl::__vwsn::RawPtrCast<::vl::presentation::IMessageBoxDialogAction>(__vwsn_temp__.GetRawPtr()) != nullptr; }())
{
return static_cast<::vl::presentation::templates::GuiTemplate*>(new ::gaclib_controls::MessageBoxButtonTemplate(::vl::__vwsn::Unbox<::vl::Ptr<::vl::presentation::IMessageBoxDialogAction>>(__vwsn_viewModel_)));
}
}
throw ::vl::Exception(::vl::WString::Unmanaged(L"Cannot find a matched control template to create."));
}
//-------------------------------------------------------------------
__vwsnf8_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_::__vwsnf8_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_(::gaclib_controls::ColorDialogControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf8_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_8)->GetText();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::WString>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_8)->SetText(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsnf9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_::__vwsnf9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_(::gaclib_controls::ColorDialogControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnf9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsn_value_) const
{
auto __vwsn_old_ = ::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_16.Obj())->GetColor();
auto __vwsn_new_ = ::vl::__vwsn::Unbox<::vl::presentation::Color>(__vwsn_value_);
if ((__vwsn_old_ == __vwsn_new_))
{
return;
}
::vl::__vwsn::This(__vwsnthis_0->__vwsn_precompile_16.Obj())->SetColor(__vwsn_new_);
}
//-------------------------------------------------------------------
__vwsno31_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsno31_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
::vl::Ptr<::vl::presentation::GuiImageData> __vwsno31_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsno_1) const
{
return [&](auto node){ return ((::vl::__vwsn::This(node.Obj())->GetType() == ::vl::presentation::FileDialogFolderType::Folder) ? ::vl::__vwsn::This(__vwsnthis_0->self)->imageFolder : ::vl::Ptr<::vl::presentation::GuiImageData>()); }(::vl::__vwsn::Unbox<::vl::Ptr<::vl::presentation::IFileDialogFolder>>(__vwsno_1));
}
//-------------------------------------------------------------------
__vwsno34_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::__vwsno34_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
::vl::Ptr<::vl::presentation::GuiImageData> __vwsno34_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsno_1) const
{
return [&](auto node){ return ((::vl::__vwsn::This(node.Obj())->GetType() == ::vl::presentation::FileDialogFileType::Folder) ? ::vl::__vwsn::This(__vwsnthis_0->self)->imageFolder : ((::vl::__vwsn::This(node.Obj())->GetType() == ::vl::presentation::FileDialogFileType::File) ? ::vl::__vwsn::This(__vwsnthis_0->self)->imageFile : ::vl::Ptr<::vl::presentation::GuiImageData>())); }(::vl::__vwsn::Unbox<::vl::Ptr<::vl::presentation::IFileDialogFile>>(__vwsno_1));
}
//-------------------------------------------------------------------
__vwsno45_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_::__vwsno45_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_(::gaclib_controls::FontNameControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
::vl::WString __vwsno45_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsno_1) const
{
return ::vl::__vwsn::Unbox<::vl::WString>(__vwsno_1);
}
//-------------------------------------------------------------------
__vwsno52_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_::__vwsno52_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_(::gaclib_controls::FontSizeControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
::vl::WString __vwsno52_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_::operator()(const ::vl::reflection::description::Value& __vwsno_1) const
{
return ::vl::__vwsn::ToString(::vl::__vwsn::Unbox<::vl::vint>(__vwsno_1));
}
//-------------------------------------------------------------------
__vwsnc10_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc10_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::ColorDialogControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc10_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::gaclib_controls::DialogStrings::Get(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetLocale());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc10_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc10_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return ::vl::presentation::controls::GetApplication(); } catch(...){ return static_cast<::vl::presentation::controls::GuiApplication*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, ::vl::Func<void()>(this, &__vwsnc10_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc10_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc10_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc11_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc11_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::ColorDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::ColorDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc11_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->OK();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc11_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc11_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::ColorDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc11_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc11_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc11_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc12_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc12_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::ColorDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::ColorDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc12_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->Cancel();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc12_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc12_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::ColorDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc12_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc12_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc12_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc13_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc13_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::ColorDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::ColorDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc13_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->ColorDialogTitle();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc13_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc13_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::ColorDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc13_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc13_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc13_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc14_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc14_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::ColorDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc14_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::gaclib_controls::DialogStrings::Get(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetLocale());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc14_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc14_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return ::vl::presentation::controls::GetApplication(); } catch(...){ return static_cast<::vl::presentation::controls::GuiApplication*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, ::vl::Func<void()>(this, &__vwsnc14_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc14_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc14_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc15_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc15_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FileDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = ::vl::Ptr<::vl::presentation::IFileDialogViewModel>();
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc15_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = (! ::vl::__vwsn::This(__vwsn_bind_cache_0.Obj())->GetIsLoadingFiles());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc15_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc15_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->ViewModel; } catch(...){ return ::vl::Ptr<::vl::presentation::IFileDialogViewModel>(); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0.Obj())->IsLoadingFilesChanged, ::vl::Func<void()>(this, &__vwsnc15_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc15_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc15_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0.Obj())->IsLoadingFilesChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = ::vl::Ptr<::vl::presentation::IFileDialogViewModel>());
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc16_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc16_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FileDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::FileDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FileDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc16_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->Cancel();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc16_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc16_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::FileDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc16_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc16_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc16_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FileDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc17_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc17_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FileDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc17_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::gaclib_controls::DialogStrings::Get(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetLocale());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc17_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc17_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return ::vl::presentation::controls::GetApplication(); } catch(...){ return static_cast<::vl::presentation::controls::GuiApplication*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, ::vl::Func<void()>(this, &__vwsnc17_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc17_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc17_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc18_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc18_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = ::vl::Ptr<::vl::presentation::IFileDialogViewModel>();
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc18_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = [&](){ try{ return ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0.Obj())->GetSelectedFolder().Obj())->GetFullPath(); } catch(...){ return ::vl::WString::Unmanaged(L""); } }();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc18_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc18_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->ViewModel; } catch(...){ return ::vl::Ptr<::vl::presentation::IFileDialogViewModel>(); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0.Obj())->SelectedFolderChanged, ::vl::Func<void()>(this, &__vwsnc18_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc18_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc18_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0.Obj())->SelectedFolderChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = ::vl::Ptr<::vl::presentation::IFileDialogViewModel>());
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc19_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc19_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = ::vl::Ptr<::vl::presentation::IFileDialogViewModel>();
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc19_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(__vwsnthis_0->self)->CreateFileFilter(::vl::__vwsn::This(__vwsn_bind_cache_0.Obj())->GetSelectedFilter());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc19_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc19_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->ViewModel; } catch(...){ return ::vl::Ptr<::vl::presentation::IFileDialogViewModel>(); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0.Obj())->SelectedFilterChanged, ::vl::Func<void()>(this, &__vwsnc19_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc19_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc19_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0.Obj())->SelectedFilterChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = ::vl::Ptr<::vl::presentation::IFileDialogViewModel>());
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc1_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc1_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::ColorComponentControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorComponentControl*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc1_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::ToString(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetValue());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc1_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc1_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->self; } catch(...){ return static_cast<::gaclib_controls::ColorComponentControl*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->ValueChanged, ::vl::Func<void()>(this, &__vwsnc1_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc1_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc1_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->ValueChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorComponentControl*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc20_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc20_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FilePickerControl* __vwsnctor___vwsn_this_, ::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FilePickerControl*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc20_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->FileDialogFileName();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc20_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc20_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::FilePickerControl*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc20_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc20_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc20_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FilePickerControl*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc21_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc21_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiComboBoxListControl*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc21_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::UnboxWeak<::vl::Ptr<::vl::presentation::IFileDialogFilter>>(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetSelectedItem());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc21_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0(::vl::presentation::compositions::GuiGraphicsComposition* __vwsn_bind_callback_argument_0, ::vl::presentation::compositions::GuiEventArgs* __vwsn_bind_callback_argument_1)
{
this->__vwsn_bind_activator_();
}
bool __vwsnc21_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->comboBox; } catch(...){ return static_cast<::vl::presentation::controls::GuiComboBoxListControl*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->SelectedIndexChanged, ::vl::Func<void(::vl::presentation::compositions::GuiGraphicsComposition*, ::vl::presentation::compositions::GuiEventArgs*)>(this, &__vwsnc21_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc21_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc21_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->SelectedIndexChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiComboBoxListControl*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc22_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc22_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiBindableTreeView*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc22_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::UnboxWeak<::vl::Ptr<::vl::presentation::IFileDialogFolder>>(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetSelectedItem());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc22_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0(::vl::presentation::compositions::GuiGraphicsComposition* __vwsn_bind_callback_argument_0, ::vl::presentation::compositions::GuiEventArgs* __vwsn_bind_callback_argument_1)
{
this->__vwsn_bind_activator_();
}
bool __vwsnc22_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->treeView; } catch(...){ return static_cast<::vl::presentation::controls::GuiBindableTreeView*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->SelectionChanged, ::vl::Func<void(::vl::presentation::compositions::GuiGraphicsComposition*, ::vl::presentation::compositions::GuiEventArgs*)>(this, &__vwsnc22_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc22_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc22_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->SelectionChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiBindableTreeView*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc23_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc23_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FilePickerControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc23_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::gaclib_controls::DialogStrings::Get(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetLocale());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc23_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc23_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return ::vl::presentation::controls::GetApplication(); } catch(...){ return static_cast<::vl::presentation::controls::GuiApplication*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, ::vl::Func<void()>(this, &__vwsnc23_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc23_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc23_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc24_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_GetSelectedFiles___vl_reflection_description_ICoroutine::__vwsnc24_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_GetSelectedFiles___vl_reflection_description_ICoroutine(::vl::reflection::description::EnumerableCoroutine::IImpl* __vwsnctor___vwsn_co_impl_, ::gaclib_controls::FilePickerControl* __vwsnctorthis_0)
:__vwsn_co_impl_(__vwsnctor___vwsn_co_impl_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_co0_file = ::vl::Ptr<::vl::presentation::IFileDialogFile>();
this->__vwsn_co1_item = static_cast<::vl::vint>(0);
this->__vwsn_co2_for_enumerable_item = ::vl::Ptr<::vl::reflection::description::IValueEnumerable>();
this->__vwsn_co3_for_enumerator_item = ::vl::Ptr<::vl::reflection::description::IValueEnumerator>();
this->__vwsn_co_state_ = static_cast<::vl::vint>(0);
this->__vwsn_co_state_before_pause_ = (- static_cast<::vl::vint>(1));
this->__vwsn_prop_Failure = ::vl::Ptr<::vl::reflection::description::IValueException>();
this->__vwsn_prop_Status = ::vl::reflection::description::CoroutineStatus::Waiting;
}
::vl::Ptr<::vl::reflection::description::IValueException> __vwsnc24_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_GetSelectedFiles___vl_reflection_description_ICoroutine::GetFailure()
{
return __vwsn_prop_Failure;
}
void __vwsnc24_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_GetSelectedFiles___vl_reflection_description_ICoroutine::SetFailure(::vl::Ptr<::vl::reflection::description::IValueException> __vwsn_value_)
{
(__vwsn_prop_Failure = __vwsn_value_);
}
::vl::reflection::description::CoroutineStatus __vwsnc24_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_GetSelectedFiles___vl_reflection_description_ICoroutine::GetStatus()
{
return __vwsn_prop_Status;
}
void __vwsnc24_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_GetSelectedFiles___vl_reflection_description_ICoroutine::SetStatus(::vl::reflection::description::CoroutineStatus __vwsn_value_)
{
(__vwsn_prop_Status = __vwsn_value_);
}
void __vwsnc24_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_GetSelectedFiles___vl_reflection_description_ICoroutine::Resume(bool __vwsn_raise_exception_, ::vl::Ptr<::vl::reflection::description::CoroutineResult> __vwsn_co_result_)
{
if ((this->GetStatus() != ::vl::reflection::description::CoroutineStatus::Waiting))
{
throw ::vl::Exception(::vl::WString::Unmanaged(L"Resume should be called only when the coroutine is in the waiting status."));
}
this->SetStatus(::vl::reflection::description::CoroutineStatus::Executing);
try
{
{
if ((__vwsn_co_state_before_pause_ != (- static_cast<::vl::vint>(1))))
{
if ((! static_cast<bool>(__vwsn_co_result_)))
{
(__vwsn_co_state_before_pause_ = (- static_cast<::vl::vint>(1)));
}
else if ((! static_cast<bool>(::vl::__vwsn::This(__vwsn_co_result_.Obj())->GetFailure())))
{
(__vwsn_co_state_before_pause_ = (- static_cast<::vl::vint>(1)));
}
else
{
{
(__vwsn_co_state_before_pause_ = (- static_cast<::vl::vint>(1)));
throw ::vl::Exception(::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_co_result_.Obj())->GetFailure().Obj())->GetMessage());
}
}
}
while (true)
{
if ((__vwsn_co_state_ == static_cast<::vl::vint>(0)))
{
(__vwsn_co2_for_enumerable_item = ::vl::Ptr<::vl::reflection::description::IValueEnumerable>(::vl::__vwsn::UnboxCollection<::vl::reflection::description::IValueReadonlyList>(::vl::__vwsn::This(__vwsnthis_0->dataGrid)->GetSelectedItems())));
(__vwsn_co3_for_enumerator_item = ::vl::__vwsn::This(__vwsn_co2_for_enumerable_item.Obj())->CreateEnumerator());
if (::vl::__vwsn::This(__vwsn_co3_for_enumerator_item.Obj())->Next())
{
(__vwsn_co_state_ = static_cast<::vl::vint>(3));
continue;
}
(__vwsn_co_state_ = static_cast<::vl::vint>(1));
continue;
}
if ((__vwsn_co_state_ == static_cast<::vl::vint>(1)))
{
this->SetStatus(::vl::reflection::description::CoroutineStatus::Stopped);
return;
}
if ((__vwsn_co_state_ == static_cast<::vl::vint>(2)))
{
if (::vl::__vwsn::This(__vwsn_co3_for_enumerator_item.Obj())->Next())
{
(__vwsn_co_state_ = static_cast<::vl::vint>(3));
continue;
}
(__vwsn_co_state_ = static_cast<::vl::vint>(1));
continue;
}
if ((__vwsn_co_state_ == static_cast<::vl::vint>(3)))
{
(__vwsn_co1_item = ::vl::__vwsn::Unbox<::vl::vint>(::vl::__vwsn::This(__vwsn_co3_for_enumerator_item.Obj())->GetCurrent()));
(__vwsn_co0_file = ::vl::Ptr<::vl::presentation::IFileDialogFile>(::vl::__vwsn::This(__vwsnthis_0->GetViewModel().Obj())->GetFiles()[__vwsn_co1_item]));
if (static_cast<bool>(__vwsn_co0_file))
{
this->SetStatus(::vl::reflection::description::CoroutineStatus::Waiting);
(__vwsn_co_state_before_pause_ = __vwsn_co_state_);
(__vwsn_co_state_ = static_cast<::vl::vint>(4));
{
::vl::reflection::description::EnumerableCoroutine::YieldAndPause(__vwsn_co_impl_, ::vl::__vwsn::Box(__vwsn_co0_file));
}
return;
}
(__vwsn_co_state_ = static_cast<::vl::vint>(2));
continue;
}
if ((__vwsn_co_state_ == static_cast<::vl::vint>(4)))
{
if (static_cast<bool>(__vwsn_co_result_))
{
if (static_cast<bool>(::vl::__vwsn::This(__vwsn_co_result_.Obj())->GetFailure()))
{
throw ::vl::Exception(::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_co_result_.Obj())->GetFailure().Obj())->GetMessage());
}
}
(__vwsn_co_state_ = static_cast<::vl::vint>(2));
continue;
}
}
}
}
catch(const ::vl::Exception& __vwsne_0)
{
auto __vwsn_co_ex_ = ::vl::reflection::description::IValueException::Create(__vwsne_0.Message());
{
this->SetFailure(__vwsn_co_ex_);
this->SetStatus(::vl::reflection::description::CoroutineStatus::Stopped);
if (__vwsn_raise_exception_)
{
throw;
}
}
}
}
//-------------------------------------------------------------------
__vwsnc25_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_CreateFileFilter__vl_presentation_controls_list_IDataFilter::__vwsnc25_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_CreateFileFilter__vl_presentation_controls_list_IDataFilter(::vl::Ptr<::vl::presentation::IFileDialogFilter> __vwsnctor_filter, ::gaclib_controls::FilePickerControl* __vwsnctorthis_0)
:filter(__vwsnctor_filter)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
}
void __vwsnc25_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_CreateFileFilter__vl_presentation_controls_list_IDataFilter::SetCallback(::vl::presentation::controls::list::IDataProcessorCallback* value)
{
}
bool __vwsnc25_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_CreateFileFilter__vl_presentation_controls_list_IDataFilter::Filter(const ::vl::reflection::description::Value& row)
{
return ::vl::__vwsn::This(filter.Obj())->FilterFile(::vl::__vwsn::Unbox<::vl::Ptr<::vl::presentation::IFileDialogFile>>(row));
}
//-------------------------------------------------------------------
__vwsnc26_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc26_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FontNameControl* __vwsnctor___vwsn_this_, ::gaclib_controls::FontNameControlConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FontNameControl*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc26_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->FontNameGroup();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc26_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc26_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::FontNameControl*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc26_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc26_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc26_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FontNameControl*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc27_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc27_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FontNameControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiSinglelineTextBox*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc27_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(__vwsn_bind_cache_0)->GetText();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc27_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0(::vl::presentation::compositions::GuiGraphicsComposition* __vwsn_bind_callback_argument_0, ::vl::presentation::compositions::GuiEventArgs* __vwsn_bind_callback_argument_1)
{
this->__vwsn_bind_activator_();
}
bool __vwsnc27_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->textBox; } catch(...){ return static_cast<::vl::presentation::controls::GuiSinglelineTextBox*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->TextChanged, ::vl::Func<void(::vl::presentation::compositions::GuiGraphicsComposition*, ::vl::presentation::compositions::GuiEventArgs*)>(this, &__vwsnc27_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc27_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc27_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->TextChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiSinglelineTextBox*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc28_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc28_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FontNameControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiSinglelineTextBox*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc28_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ((! ::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->GetFontMustExist()) || (::vl::__vwsn::This(::vl::__vwsn::UnboxCollection<::vl::reflection::description::IValueReadonlyList>(::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->GetFontList()).Obj())->IndexOf(::vl::__vwsn::Box(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetText())) != (- static_cast<::vl::vint>(1))));
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc28_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0(::vl::presentation::compositions::GuiGraphicsComposition* __vwsn_bind_callback_argument_0, ::vl::presentation::compositions::GuiEventArgs* __vwsn_bind_callback_argument_1)
{
this->__vwsn_bind_activator_();
}
bool __vwsnc28_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->textBox; } catch(...){ return static_cast<::vl::presentation::controls::GuiSinglelineTextBox*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->TextChanged, ::vl::Func<void(::vl::presentation::compositions::GuiGraphicsComposition*, ::vl::presentation::compositions::GuiEventArgs*)>(this, &__vwsnc28_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc28_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc28_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->TextChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiSinglelineTextBox*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc29_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc29_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FontNameControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc29_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::gaclib_controls::DialogStrings::Get(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetLocale());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc29_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc29_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return ::vl::presentation::controls::GetApplication(); } catch(...){ return static_cast<::vl::presentation::controls::GuiApplication*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, ::vl::Func<void()>(this, &__vwsnc29_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc29_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc29_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc2_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc2_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::ColorComponentControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorComponentControl*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc2_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(__vwsn_bind_cache_0)->GetTextBoxAlt();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc2_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc2_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->self; } catch(...){ return static_cast<::gaclib_controls::ColorComponentControl*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->TextBoxAltChanged, ::vl::Func<void()>(this, &__vwsnc2_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc2_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc2_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->TextBoxAltChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorComponentControl*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc30_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc30_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FontSizeControl* __vwsnctor___vwsn_this_, ::gaclib_controls::FontSizeControlConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FontSizeControl*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc30_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->FontSizeGroup();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc30_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc30_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::FontSizeControl*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc30_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc30_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc30_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FontSizeControl*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc31_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc31_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FontSizeControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiSinglelineTextBox*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc31_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = [&](){ try{ return ::vl::__vwsn::Parse<::vl::vint>(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetText()); } catch(...){ return (- static_cast<::vl::vint>(1)); } }();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc31_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0(::vl::presentation::compositions::GuiGraphicsComposition* __vwsn_bind_callback_argument_0, ::vl::presentation::compositions::GuiEventArgs* __vwsn_bind_callback_argument_1)
{
this->__vwsn_bind_activator_();
}
bool __vwsnc31_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->textBox; } catch(...){ return static_cast<::vl::presentation::controls::GuiSinglelineTextBox*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->TextChanged, ::vl::Func<void(::vl::presentation::compositions::GuiGraphicsComposition*, ::vl::presentation::compositions::GuiEventArgs*)>(this, &__vwsnc31_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc31_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc31_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->TextChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiSinglelineTextBox*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc32_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc32_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FontSizeControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FontSizeControl*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc32_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = (::vl::__vwsn::This(__vwsn_bind_cache_0)->GetValue() > static_cast<::vl::vint>(0));
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc32_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc32_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->self; } catch(...){ return static_cast<::gaclib_controls::FontSizeControl*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->ValueChanged, ::vl::Func<void()>(this, &__vwsnc32_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc32_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc32_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->ValueChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FontSizeControl*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc33_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc33_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FontSizeControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc33_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::gaclib_controls::DialogStrings::Get(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetLocale());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc33_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc33_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return ::vl::presentation::controls::GetApplication(); } catch(...){ return static_cast<::vl::presentation::controls::GuiApplication*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, ::vl::Func<void()>(this, &__vwsnc33_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc33_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc33_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc34_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc34_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FullFontDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc34_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->Bold();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc34_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc34_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc34_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc34_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc34_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc35_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc35_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FullFontDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc35_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->Italic();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc35_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc35_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc35_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc35_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc35_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc36_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc36_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FullFontDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc36_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->Underline();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc36_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc36_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc36_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc36_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc36_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc37_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc37_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FullFontDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc37_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->Strikeline();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc37_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc37_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc37_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc37_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc37_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc38_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc38_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FullFontDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc38_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->HAA();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc38_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc38_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc38_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc38_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc38_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc39_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc39_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FullFontDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc39_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->VAA();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc39_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc39_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc39_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc39_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc39_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc3_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc3_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::ColorComponentControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiScroll*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc3_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(__vwsn_bind_cache_0)->GetPosition();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc3_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0(::vl::presentation::compositions::GuiGraphicsComposition* __vwsn_bind_callback_argument_0, ::vl::presentation::compositions::GuiEventArgs* __vwsn_bind_callback_argument_1)
{
this->__vwsn_bind_activator_();
}
bool __vwsnc3_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->tracker; } catch(...){ return static_cast<::vl::presentation::controls::GuiScroll*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->PositionChanged, ::vl::Func<void(::vl::presentation::compositions::GuiGraphicsComposition*, ::vl::presentation::compositions::GuiEventArgs*)>(this, &__vwsnc3_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc3_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc3_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->PositionChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiScroll*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc40_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc40_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FullFontDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc40_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->FontEffectGroup();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc40_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc40_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc40_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc40_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc40_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc41_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc41_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FullFontDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc41_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->FontColorGroup();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc41_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc41_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc41_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc41_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc41_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FontNameControl*>(nullptr);
this->__vwsn_bind_cache_1 = static_cast<::gaclib_controls::FontNameControl*>(nullptr);
this->__vwsn_bind_cache_2 = static_cast<::gaclib_controls::FontSizeControl*>(nullptr);
this->__vwsn_bind_cache_3 = static_cast<::gaclib_controls::FontSizeControl*>(nullptr);
this->__vwsn_bind_cache_4 = static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr);
this->__vwsn_bind_cache_5 = static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr);
this->__vwsn_bind_cache_6 = static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr);
this->__vwsn_bind_cache_7 = static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr);
this->__vwsn_bind_cache_8 = static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr);
this->__vwsn_bind_cache_9 = static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_handler_1_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_handler_2_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_handler_3_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_handler_4_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_handler_5_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_handler_6_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_handler_7_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_handler_8_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_handler_9_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = [&](auto defaultFont){ return [&](){ ::vl::presentation::FontProperties __vwsn_temp__; __vwsn_temp__.fontFamily = (::vl::__vwsn::This(::vl::__vwsn::UnboxCollection<::vl::reflection::description::IValueReadonlyList>(::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->GetFontList()).Obj())->Contains(::vl::__vwsn::Box(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetValue())) ? ::vl::__vwsn::This(__vwsn_bind_cache_1)->GetValue() : defaultFont.fontFamily); __vwsn_temp__.size = ((::vl::__vwsn::This(__vwsn_bind_cache_2)->GetValue() > static_cast<::vl::vint>(0)) ? ::vl::__vwsn::This(__vwsn_bind_cache_3)->GetValue() : defaultFont.size); __vwsn_temp__.bold = ::vl::__vwsn::This(__vwsn_bind_cache_4)->GetSelected(); __vwsn_temp__.italic = ::vl::__vwsn::This(__vwsn_bind_cache_5)->GetSelected(); __vwsn_temp__.underline = ::vl::__vwsn::This(__vwsn_bind_cache_6)->GetSelected(); __vwsn_temp__.strikeline = ::vl::__vwsn::This(__vwsn_bind_cache_7)->GetSelected(); __vwsn_temp__.antialias = ::vl::__vwsn::This(__vwsn_bind_cache_8)->GetSelected(); __vwsn_temp__.verticalAntialias = ::vl::__vwsn::This(__vwsn_bind_cache_9)->GetSelected(); return __vwsn_temp__; }(); }(::vl::__vwsn::This(::vl::__vwsn::This(::vl::presentation::GetCurrentController())->ResourceService())->GetDefaultFont());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
void __vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_1_0()
{
this->__vwsn_bind_activator_();
}
void __vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_2_0()
{
this->__vwsn_bind_activator_();
}
void __vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_3_0()
{
this->__vwsn_bind_activator_();
}
void __vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_4_0(::vl::presentation::compositions::GuiGraphicsComposition* __vwsn_bind_callback_argument_0, ::vl::presentation::compositions::GuiEventArgs* __vwsn_bind_callback_argument_1)
{
this->__vwsn_bind_activator_();
}
void __vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_5_0(::vl::presentation::compositions::GuiGraphicsComposition* __vwsn_bind_callback_argument_0, ::vl::presentation::compositions::GuiEventArgs* __vwsn_bind_callback_argument_1)
{
this->__vwsn_bind_activator_();
}
void __vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_6_0(::vl::presentation::compositions::GuiGraphicsComposition* __vwsn_bind_callback_argument_0, ::vl::presentation::compositions::GuiEventArgs* __vwsn_bind_callback_argument_1)
{
this->__vwsn_bind_activator_();
}
void __vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_7_0(::vl::presentation::compositions::GuiGraphicsComposition* __vwsn_bind_callback_argument_0, ::vl::presentation::compositions::GuiEventArgs* __vwsn_bind_callback_argument_1)
{
this->__vwsn_bind_activator_();
}
void __vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_8_0(::vl::presentation::compositions::GuiGraphicsComposition* __vwsn_bind_callback_argument_0, ::vl::presentation::compositions::GuiEventArgs* __vwsn_bind_callback_argument_1)
{
this->__vwsn_bind_activator_();
}
void __vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_9_0(::vl::presentation::compositions::GuiGraphicsComposition* __vwsn_bind_callback_argument_0, ::vl::presentation::compositions::GuiEventArgs* __vwsn_bind_callback_argument_1)
{
this->__vwsn_bind_activator_();
}
bool __vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->nameControl; } catch(...){ return static_cast<::gaclib_controls::FontNameControl*>(nullptr); } }());
(__vwsn_bind_cache_1 = [&](){ try{ return __vwsnthis_0->nameControl; } catch(...){ return static_cast<::gaclib_controls::FontNameControl*>(nullptr); } }());
(__vwsn_bind_cache_2 = [&](){ try{ return __vwsnthis_0->sizeControl; } catch(...){ return static_cast<::gaclib_controls::FontSizeControl*>(nullptr); } }());
(__vwsn_bind_cache_3 = [&](){ try{ return __vwsnthis_0->sizeControl; } catch(...){ return static_cast<::gaclib_controls::FontSizeControl*>(nullptr); } }());
(__vwsn_bind_cache_4 = [&](){ try{ return __vwsnthis_0->checkBold; } catch(...){ return static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr); } }());
(__vwsn_bind_cache_5 = [&](){ try{ return __vwsnthis_0->checkItalic; } catch(...){ return static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr); } }());
(__vwsn_bind_cache_6 = [&](){ try{ return __vwsnthis_0->checkUnderline; } catch(...){ return static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr); } }());
(__vwsn_bind_cache_7 = [&](){ try{ return __vwsnthis_0->checkStrikeline; } catch(...){ return static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr); } }());
(__vwsn_bind_cache_8 = [&](){ try{ return __vwsnthis_0->checkHAA; } catch(...){ return static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr); } }());
(__vwsn_bind_cache_9 = [&](){ try{ return __vwsnthis_0->checkVAA; } catch(...){ return static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->ValueChanged, ::vl::Func<void()>(this, &__vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
(__vwsn_bind_handler_1_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_1)->ValueChanged, ::vl::Func<void()>(this, &__vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_1_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
(__vwsn_bind_handler_2_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_2)->ValueChanged, ::vl::Func<void()>(this, &__vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_2_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
(__vwsn_bind_handler_3_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_3)->ValueChanged, ::vl::Func<void()>(this, &__vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_3_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
(__vwsn_bind_handler_4_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_4)->SelectedChanged, ::vl::Func<void(::vl::presentation::compositions::GuiGraphicsComposition*, ::vl::presentation::compositions::GuiEventArgs*)>(this, &__vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_4_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
(__vwsn_bind_handler_5_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_5)->SelectedChanged, ::vl::Func<void(::vl::presentation::compositions::GuiGraphicsComposition*, ::vl::presentation::compositions::GuiEventArgs*)>(this, &__vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_5_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
(__vwsn_bind_handler_6_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_6)->SelectedChanged, ::vl::Func<void(::vl::presentation::compositions::GuiGraphicsComposition*, ::vl::presentation::compositions::GuiEventArgs*)>(this, &__vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_6_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
(__vwsn_bind_handler_7_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_7)->SelectedChanged, ::vl::Func<void(::vl::presentation::compositions::GuiGraphicsComposition*, ::vl::presentation::compositions::GuiEventArgs*)>(this, &__vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_7_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
(__vwsn_bind_handler_8_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_8)->SelectedChanged, ::vl::Func<void(::vl::presentation::compositions::GuiGraphicsComposition*, ::vl::presentation::compositions::GuiEventArgs*)>(this, &__vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_8_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
(__vwsn_bind_handler_9_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_9)->SelectedChanged, ::vl::Func<void(::vl::presentation::compositions::GuiGraphicsComposition*, ::vl::presentation::compositions::GuiEventArgs*)>(this, &__vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_9_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->ValueChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
if (static_cast<bool>(__vwsn_bind_handler_1_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_1)->ValueChanged, __vwsn_bind_handler_1_0);
(__vwsn_bind_handler_1_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
if (static_cast<bool>(__vwsn_bind_handler_2_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_2)->ValueChanged, __vwsn_bind_handler_2_0);
(__vwsn_bind_handler_2_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
if (static_cast<bool>(__vwsn_bind_handler_3_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_3)->ValueChanged, __vwsn_bind_handler_3_0);
(__vwsn_bind_handler_3_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
if (static_cast<bool>(__vwsn_bind_handler_4_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_4)->SelectedChanged, __vwsn_bind_handler_4_0);
(__vwsn_bind_handler_4_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
if (static_cast<bool>(__vwsn_bind_handler_5_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_5)->SelectedChanged, __vwsn_bind_handler_5_0);
(__vwsn_bind_handler_5_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
if (static_cast<bool>(__vwsn_bind_handler_6_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_6)->SelectedChanged, __vwsn_bind_handler_6_0);
(__vwsn_bind_handler_6_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
if (static_cast<bool>(__vwsn_bind_handler_7_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_7)->SelectedChanged, __vwsn_bind_handler_7_0);
(__vwsn_bind_handler_7_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
if (static_cast<bool>(__vwsn_bind_handler_8_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_8)->SelectedChanged, __vwsn_bind_handler_8_0);
(__vwsn_bind_handler_8_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
if (static_cast<bool>(__vwsn_bind_handler_9_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_9)->SelectedChanged, __vwsn_bind_handler_9_0);
(__vwsn_bind_handler_9_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FontNameControl*>(nullptr));
(__vwsn_bind_cache_1 = static_cast<::gaclib_controls::FontNameControl*>(nullptr));
(__vwsn_bind_cache_2 = static_cast<::gaclib_controls::FontSizeControl*>(nullptr));
(__vwsn_bind_cache_3 = static_cast<::gaclib_controls::FontSizeControl*>(nullptr));
(__vwsn_bind_cache_4 = static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr));
(__vwsn_bind_cache_5 = static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr));
(__vwsn_bind_cache_6 = static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr));
(__vwsn_bind_cache_7 = static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr));
(__vwsn_bind_cache_8 = static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr));
(__vwsn_bind_cache_9 = static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
(__vwsn_bind_handler_1_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
(__vwsn_bind_handler_2_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
(__vwsn_bind_handler_3_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
(__vwsn_bind_handler_4_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
(__vwsn_bind_handler_5_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
(__vwsn_bind_handler_6_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
(__vwsn_bind_handler_7_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
(__vwsn_bind_handler_8_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
(__vwsn_bind_handler_9_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc43_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc43_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FullFontDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc43_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->FontPreviewGroup();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc43_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc43_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc43_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc43_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc43_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc44_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc44_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FullFontDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc44_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->OK();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc44_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc44_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc44_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc44_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc44_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc45_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc45_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FontNameControl*>(nullptr);
this->__vwsn_bind_cache_1 = static_cast<::gaclib_controls::FontSizeControl*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_handler_1_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc45_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = (::vl::__vwsn::This(__vwsn_bind_cache_0)->GetLegal() && ::vl::__vwsn::This(__vwsn_bind_cache_1)->GetLegal());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc45_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
void __vwsnc45_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_1_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc45_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->nameControl; } catch(...){ return static_cast<::gaclib_controls::FontNameControl*>(nullptr); } }());
(__vwsn_bind_cache_1 = [&](){ try{ return __vwsnthis_0->sizeControl; } catch(...){ return static_cast<::gaclib_controls::FontSizeControl*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LegalChanged, ::vl::Func<void()>(this, &__vwsnc45_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
(__vwsn_bind_handler_1_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_1)->LegalChanged, ::vl::Func<void()>(this, &__vwsnc45_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_1_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc45_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc45_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LegalChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
if (static_cast<bool>(__vwsn_bind_handler_1_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_1)->LegalChanged, __vwsn_bind_handler_1_0);
(__vwsn_bind_handler_1_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FontNameControl*>(nullptr));
(__vwsn_bind_cache_1 = static_cast<::gaclib_controls::FontSizeControl*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
(__vwsn_bind_handler_1_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc46_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc46_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FullFontDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc46_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->Cancel();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc46_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc46_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc46_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc46_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc46_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc47_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc47_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FullFontDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc47_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->FontDialogTitle();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc47_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc47_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc47_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc47_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc47_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc48_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc48_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::FullFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc48_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::gaclib_controls::DialogStrings::Get(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetLocale());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc48_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc48_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return ::vl::presentation::controls::GetApplication(); } catch(...){ return static_cast<::vl::presentation::controls::GuiApplication*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, ::vl::Func<void()>(this, &__vwsnc48_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc48_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc48_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc49_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc49_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::SimpleFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FontNameControl*>(nullptr);
this->__vwsn_bind_cache_1 = static_cast<::gaclib_controls::FontNameControl*>(nullptr);
this->__vwsn_bind_cache_2 = static_cast<::gaclib_controls::FontSizeControl*>(nullptr);
this->__vwsn_bind_cache_3 = static_cast<::gaclib_controls::FontSizeControl*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_handler_1_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_handler_2_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_handler_3_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc49_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = [&](auto defaultFont){ return [&](){ ::vl::presentation::FontProperties __vwsn_temp__; __vwsn_temp__.fontFamily = (::vl::__vwsn::This(::vl::__vwsn::UnboxCollection<::vl::reflection::description::IValueReadonlyList>(::vl::__vwsn::This(__vwsnthis_0->ViewModel.Obj())->GetFontList()).Obj())->Contains(::vl::__vwsn::Box(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetValue())) ? ::vl::__vwsn::This(__vwsn_bind_cache_1)->GetValue() : defaultFont.fontFamily); __vwsn_temp__.size = ((::vl::__vwsn::This(__vwsn_bind_cache_2)->GetValue() > static_cast<::vl::vint>(0)) ? ::vl::__vwsn::This(__vwsn_bind_cache_3)->GetValue() : defaultFont.size); __vwsn_temp__.antialias = true; __vwsn_temp__.verticalAntialias = true; return __vwsn_temp__; }(); }(::vl::__vwsn::This(::vl::__vwsn::This(::vl::presentation::GetCurrentController())->ResourceService())->GetDefaultFont());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc49_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
void __vwsnc49_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_1_0()
{
this->__vwsn_bind_activator_();
}
void __vwsnc49_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_2_0()
{
this->__vwsn_bind_activator_();
}
void __vwsnc49_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_3_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc49_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->nameControl; } catch(...){ return static_cast<::gaclib_controls::FontNameControl*>(nullptr); } }());
(__vwsn_bind_cache_1 = [&](){ try{ return __vwsnthis_0->nameControl; } catch(...){ return static_cast<::gaclib_controls::FontNameControl*>(nullptr); } }());
(__vwsn_bind_cache_2 = [&](){ try{ return __vwsnthis_0->sizeControl; } catch(...){ return static_cast<::gaclib_controls::FontSizeControl*>(nullptr); } }());
(__vwsn_bind_cache_3 = [&](){ try{ return __vwsnthis_0->sizeControl; } catch(...){ return static_cast<::gaclib_controls::FontSizeControl*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->ValueChanged, ::vl::Func<void()>(this, &__vwsnc49_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
(__vwsn_bind_handler_1_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_1)->ValueChanged, ::vl::Func<void()>(this, &__vwsnc49_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_1_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
(__vwsn_bind_handler_2_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_2)->ValueChanged, ::vl::Func<void()>(this, &__vwsnc49_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_2_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
(__vwsn_bind_handler_3_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_3)->ValueChanged, ::vl::Func<void()>(this, &__vwsnc49_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_3_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc49_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc49_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->ValueChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
if (static_cast<bool>(__vwsn_bind_handler_1_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_1)->ValueChanged, __vwsn_bind_handler_1_0);
(__vwsn_bind_handler_1_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
if (static_cast<bool>(__vwsn_bind_handler_2_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_2)->ValueChanged, __vwsn_bind_handler_2_0);
(__vwsn_bind_handler_2_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
if (static_cast<bool>(__vwsn_bind_handler_3_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_3)->ValueChanged, __vwsn_bind_handler_3_0);
(__vwsn_bind_handler_3_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FontNameControl*>(nullptr));
(__vwsn_bind_cache_1 = static_cast<::gaclib_controls::FontNameControl*>(nullptr));
(__vwsn_bind_cache_2 = static_cast<::gaclib_controls::FontSizeControl*>(nullptr));
(__vwsn_bind_cache_3 = static_cast<::gaclib_controls::FontSizeControl*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
(__vwsn_bind_handler_1_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
(__vwsn_bind_handler_2_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
(__vwsn_bind_handler_3_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc4_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc4_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::ColorDialogControl* __vwsnctor___vwsn_this_, ::gaclib_controls::ColorDialogControlConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogControl*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc4_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->Red();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc4_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc4_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::ColorDialogControl*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc4_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc4_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc4_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogControl*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc50_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc50_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::SimpleFontDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::SimpleFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::SimpleFontDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc50_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->FontPreviewGroup();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc50_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc50_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::SimpleFontDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc50_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc50_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc50_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::SimpleFontDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc51_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc51_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::SimpleFontDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::SimpleFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::SimpleFontDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc51_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->OK();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc51_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc51_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::SimpleFontDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc51_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc51_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc51_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::SimpleFontDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc52_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc52_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::SimpleFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FontNameControl*>(nullptr);
this->__vwsn_bind_cache_1 = static_cast<::gaclib_controls::FontSizeControl*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_handler_1_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc52_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = (::vl::__vwsn::This(__vwsn_bind_cache_0)->GetLegal() && ::vl::__vwsn::This(__vwsn_bind_cache_1)->GetLegal());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc52_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
void __vwsnc52_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_1_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc52_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->nameControl; } catch(...){ return static_cast<::gaclib_controls::FontNameControl*>(nullptr); } }());
(__vwsn_bind_cache_1 = [&](){ try{ return __vwsnthis_0->sizeControl; } catch(...){ return static_cast<::gaclib_controls::FontSizeControl*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LegalChanged, ::vl::Func<void()>(this, &__vwsnc52_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
(__vwsn_bind_handler_1_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_1)->LegalChanged, ::vl::Func<void()>(this, &__vwsnc52_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_1_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc52_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc52_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LegalChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
if (static_cast<bool>(__vwsn_bind_handler_1_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_1)->LegalChanged, __vwsn_bind_handler_1_0);
(__vwsn_bind_handler_1_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::FontNameControl*>(nullptr));
(__vwsn_bind_cache_1 = static_cast<::gaclib_controls::FontSizeControl*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
(__vwsn_bind_handler_1_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc53_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc53_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::SimpleFontDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::SimpleFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::SimpleFontDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc53_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->Cancel();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc53_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc53_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::SimpleFontDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc53_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc53_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc53_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::SimpleFontDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc54_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc54_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::SimpleFontDialogWindow* __vwsnctor___vwsn_this_, ::gaclib_controls::SimpleFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::SimpleFontDialogWindow*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc54_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->FontDialogTitle();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc54_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc54_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::SimpleFontDialogWindow*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc54_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc54_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc54_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::SimpleFontDialogWindow*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc55_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsnc55_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::SimpleFontDialogWindowConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc55_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::gaclib_controls::DialogStrings::Get(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetLocale());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc55_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc55_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return ::vl::presentation::controls::GetApplication(); } catch(...){ return static_cast<::vl::presentation::controls::GuiApplication*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, ::vl::Func<void()>(this, &__vwsnc55_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc55_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc55_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc56_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription::__vwsnc56_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::MessageBoxButtonTemplateConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::MessageBoxButtonTemplate*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc56_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(__vwsnthis_0->self)->GetButtonText(::vl::__vwsn::This(__vwsnthis_0->Action.Obj())->GetButton(), ::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc56_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc56_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->self; } catch(...){ return static_cast<::gaclib_controls::MessageBoxButtonTemplate*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc56_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc56_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc56_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::MessageBoxButtonTemplate*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc57_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription::__vwsnc57_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::MessageBoxButtonTemplateConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc57_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::gaclib_controls::DialogStrings::Get(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetLocale());
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc57_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc57_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return ::vl::presentation::controls::GetApplication(); } catch(...){ return static_cast<::vl::presentation::controls::GuiApplication*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, ::vl::Func<void()>(this, &__vwsnc57_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc57_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc57_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->LocaleChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::vl::presentation::controls::GuiApplication*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::__vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings()
{
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::Abort()
{
return ::vl::WString::Unmanaged(L"Abort");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::Blue()
{
return ::vl::WString::Unmanaged(L"Blue:");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::Bold()
{
return ::vl::WString::Unmanaged(L"Bold");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::Cancel()
{
return ::vl::WString::Unmanaged(L"Cancel");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::Color()
{
return ::vl::WString::Unmanaged(L"Color:");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::ColorDialogTitle()
{
return ::vl::WString::Unmanaged(L"Choose Color");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::Continue()
{
return ::vl::WString::Unmanaged(L"Continue");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FileDialogAskCreateFile()
{
return ::vl::WString::Unmanaged(L"Do you want to create the following file(s):");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FileDialogAskOverrideFile()
{
return ::vl::WString::Unmanaged(L"Do you want to override the following file(s):");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FileDialogErrorEmptySelection()
{
return ::vl::WString::Unmanaged(L"At least one file must be selected.");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FileDialogErrorFileExpected()
{
return ::vl::WString::Unmanaged(L"File(s) expected but folder(s) selected:");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FileDialogErrorFileNotExist()
{
return ::vl::WString::Unmanaged(L"File(s) not exist:");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FileDialogErrorFolderNotExist()
{
return ::vl::WString::Unmanaged(L"Folder not exist:");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FileDialogErrorMultipleSelectionNotEnabled()
{
return ::vl::WString::Unmanaged(L"Multiple selection is not enabled in this dialog.");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FileDialogFileName()
{
return ::vl::WString::Unmanaged(L"File Name:");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FileDialogOpen()
{
return ::vl::WString::Unmanaged(L"Open");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FileDialogSave()
{
return ::vl::WString::Unmanaged(L"Save");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FileDialogTextLoadingFiles()
{
return ::vl::WString::Unmanaged(L"(Loading Folders and Files...)");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FileDialogTextLoadingFolders()
{
return ::vl::WString::Unmanaged(L"(Loading...)");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FontColorGroup()
{
return ::vl::WString::Unmanaged(L"Color:");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FontColorGroup2()
{
return ::vl::WString::Unmanaged(L"Pick a Color:");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FontDialogTitle()
{
return ::vl::WString::Unmanaged(L"Choose Font");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FontEffectGroup()
{
return ::vl::WString::Unmanaged(L"Effect:");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FontNameGroup()
{
return ::vl::WString::Unmanaged(L"Font:");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FontPreviewGroup()
{
return ::vl::WString::Unmanaged(L"Preview:");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::FontSizeGroup()
{
return ::vl::WString::Unmanaged(L"Size:");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::Green()
{
return ::vl::WString::Unmanaged(L"Green:");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::HAA()
{
return ::vl::WString::Unmanaged(L"Horizontal Antialias");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::Ignore()
{
return ::vl::WString::Unmanaged(L"Ignore");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::Italic()
{
return ::vl::WString::Unmanaged(L"Italic");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::No()
{
return ::vl::WString::Unmanaged(L"No");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::OK()
{
return ::vl::WString::Unmanaged(L"OK");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::Red()
{
return ::vl::WString::Unmanaged(L"Red:");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::Retry()
{
return ::vl::WString::Unmanaged(L"Retry");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::Strikeline()
{
return ::vl::WString::Unmanaged(L"Strike-through");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::TryAgain()
{
return ::vl::WString::Unmanaged(L"Try Again");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::Underline()
{
return ::vl::WString::Unmanaged(L"Underline");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::VAA()
{
return ::vl::WString::Unmanaged(L"Vertical Antialias");
}
::vl::WString __vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings::Yes()
{
return ::vl::WString::Unmanaged(L"Yes");
}
//-------------------------------------------------------------------
__vwsnc5_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc5_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::ColorDialogControl* __vwsnctor___vwsn_this_, ::gaclib_controls::ColorDialogControlConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogControl*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc5_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->Green();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc5_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc5_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::ColorDialogControl*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc5_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc5_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc5_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogControl*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc6_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc6_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::ColorDialogControl* __vwsnctor___vwsn_this_, ::gaclib_controls::ColorDialogControlConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogControl*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc6_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->Blue();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc6_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc6_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::ColorDialogControl*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc6_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc6_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc6_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogControl*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc7_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc7_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::ColorDialogControl* __vwsnctor___vwsn_this_, ::gaclib_controls::ColorDialogControlConstructor* __vwsnctorthis_0)
:__vwsn_this_(__vwsnctor___vwsn_this_)
, __vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogControl*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc7_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->GetStrings().Obj())->Color();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc7_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc7_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsn_this_; } catch(...){ return static_cast<::gaclib_controls::ColorDialogControl*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, ::vl::Func<void()>(this, &__vwsnc7_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc7_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc7_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->StringsChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogControl*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc8_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc8_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::ColorDialogControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogControl*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc8_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(__vwsn_bind_cache_0)->GetValue();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc8_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc8_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->self; } catch(...){ return static_cast<::gaclib_controls::ColorDialogControl*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_bind_cache_0)->ValueChanged, ::vl::Func<void()>(this, &__vwsnc8_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc8_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc8_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(__vwsn_bind_cache_0)->ValueChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogControl*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
//-------------------------------------------------------------------
__vwsnc9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsnc9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription(::gaclib_controls::ColorDialogControlConstructor* __vwsnctorthis_0)
:__vwsnthis_0(::vl::__vwsn::This(__vwsnctorthis_0))
{
this->__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogControl*>(nullptr);
this->__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_handler_0_1 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_handler_0_2 = ::vl::Ptr<::vl::reflection::description::IEventHandler>();
this->__vwsn_bind_opened_ = false;
this->__vwsn_bind_closed_ = false;
}
void __vwsnc9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_activator_()
{
auto __vwsn_bind_activator_result_ = ::vl::__vwsn::This(__vwsn_bind_cache_0)->ReadColor();
::vl::__vwsn::EventInvoke(this->ValueChanged)(::vl::__vwsn::Box(__vwsn_bind_activator_result_));
}
void __vwsnc9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0()
{
this->__vwsn_bind_activator_();
}
void __vwsnc9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_1()
{
this->__vwsn_bind_activator_();
}
void __vwsnc9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_2()
{
this->__vwsn_bind_activator_();
}
bool __vwsnc9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Open()
{
if ((! __vwsn_bind_opened_))
{
(__vwsn_bind_opened_ = true);
(__vwsn_bind_cache_0 = [&](){ try{ return __vwsnthis_0->self; } catch(...){ return static_cast<::gaclib_controls::ColorDialogControl*>(nullptr); } }());
(__vwsn_bind_handler_0_0 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->colorRed)->ValueChanged, ::vl::Func<void()>(this, &__vwsnc9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_0)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
(__vwsn_bind_handler_0_1 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->colorGreen)->ValueChanged, ::vl::Func<void()>(this, &__vwsnc9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_1)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
(__vwsn_bind_handler_0_2 = [&](){ try{ return ::vl::__vwsn::EventAttach(::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->colorBlue)->ValueChanged, ::vl::Func<void()>(this, &__vwsnc9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::__vwsn_bind_callback_0_2)); } catch(...){ return ::vl::Ptr<::vl::reflection::description::IEventHandler>(); } }());
return true;
}
return false;
}
bool __vwsnc9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Update()
{
if ((__vwsn_bind_opened_ && (! __vwsn_bind_closed_)))
{
this->__vwsn_bind_activator_();
return true;
}
return false;
}
bool __vwsnc9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription::Close()
{
if ((! __vwsn_bind_closed_))
{
(__vwsn_bind_closed_ = true);
if (static_cast<bool>(__vwsn_bind_handler_0_0))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->colorRed)->ValueChanged, __vwsn_bind_handler_0_0);
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
if (static_cast<bool>(__vwsn_bind_handler_0_1))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->colorGreen)->ValueChanged, __vwsn_bind_handler_0_1);
(__vwsn_bind_handler_0_1 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
if (static_cast<bool>(__vwsn_bind_handler_0_2))
{
::vl::__vwsn::EventDetach(::vl::__vwsn::This(::vl::__vwsn::This(__vwsn_bind_cache_0)->colorBlue)->ValueChanged, __vwsn_bind_handler_0_2);
(__vwsn_bind_handler_0_2 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
}
(__vwsn_bind_cache_0 = static_cast<::gaclib_controls::ColorDialogControl*>(nullptr));
(__vwsn_bind_handler_0_0 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
(__vwsn_bind_handler_0_1 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
(__vwsn_bind_handler_0_2 = ::vl::Ptr<::vl::reflection::description::IEventHandler>());
return true;
}
return false;
}
}
/***********************************************************************
Class (::gaclib_controls::ColorComponentControlConstructor)
***********************************************************************/
namespace gaclib_controls
{
void ColorComponentControlConstructor::__vwsn_gaclib_controls_ColorComponentControl_Initialize(::gaclib_controls::ColorComponentControl* __vwsn_this_)
{
(this->self = __vwsn_this_);
(this->__vwsn_precompile_0 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetCellPadding(static_cast<::vl::vint>(5));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowsAndColumns(static_cast<::vl::vint>(1), static_cast<::vl::vint>(2));
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Absolute; __vwsn_temp__.absolute = static_cast<::vl::vint>(48); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_1 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->textBox = new ::vl::presentation::controls::GuiSinglelineTextBox(::vl::presentation::theme::ThemeName::SinglelineTextBox));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"textBox"), ::vl::__vwsn::Box(this->textBox));
}
(this->__vwsn_precompile_2 = ::vl::__vwsn::This(this->textBox)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->textBox)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_1));
}
(this->__vwsn_precompile_3 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->tracker = new ::vl::presentation::controls::GuiScroll(::vl::presentation::theme::ThemeName::HTracker));
::vl::__vwsn::This(this->tracker)->SetPageSize(static_cast<::vl::vint>(0));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"tracker"), ::vl::__vwsn::Box(this->tracker));
}
{
::vl::__vwsn::This(this->tracker)->SetBigMove(static_cast<::vl::vint>(16));
}
{
::vl::__vwsn::This(this->tracker)->SetSmallMove(static_cast<::vl::vint>(1));
}
{
::vl::__vwsn::This(this->tracker)->SetPageSize(static_cast<::vl::vint>(1));
}
{
::vl::__vwsn::This(this->tracker)->SetTotalSize(static_cast<::vl::vint>(256));
}
(this->__vwsn_precompile_4 = ::vl::__vwsn::This(this->tracker)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_4)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->tracker)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_3));
}
{
::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetContainerComposition())->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_0));
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc1_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf1_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc2_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf2_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf3_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->textBox)->TextChanged, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc3_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf4_GuiFakeDialogServiceUI_gaclib_controls_ColorComponentControlConstructor___vwsn_gaclib_controls_ColorComponentControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
}
ColorComponentControlConstructor::ColorComponentControlConstructor()
: self(static_cast<::gaclib_controls::ColorComponentControl*>(nullptr))
, textBox(static_cast<::vl::presentation::controls::GuiSinglelineTextBox*>(nullptr))
, tracker(static_cast<::vl::presentation::controls::GuiScroll*>(nullptr))
, __vwsn_precompile_0(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_1(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_2(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_3(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_4(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
{
}
/***********************************************************************
Class (::gaclib_controls::ColorComponentControl)
***********************************************************************/
::vl::vint ColorComponentControl::GetValue()
{
return this->__vwsn_prop_Value;
}
void ColorComponentControl::SetValue(::vl::vint __vwsn_value_)
{
if ((this->__vwsn_prop_Value != __vwsn_value_))
{
(this->__vwsn_prop_Value = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->ValueChanged)();
}
}
::vl::WString ColorComponentControl::GetTextBoxAlt()
{
return this->__vwsn_prop_TextBoxAlt;
}
void ColorComponentControl::SetTextBoxAlt(const ::vl::WString& __vwsn_value_)
{
if ((this->__vwsn_prop_TextBoxAlt != __vwsn_value_))
{
(this->__vwsn_prop_TextBoxAlt = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->TextBoxAltChanged)();
}
}
ColorComponentControl::ColorComponentControl()
: ::vl::presentation::controls::GuiCustomControl(::vl::presentation::theme::ThemeName::CustomControl)
, __vwsn_prop_Value(static_cast<::vl::vint>(0))
, __vwsn_prop_TextBoxAlt(::vl::WString::Unmanaged(L""))
{
auto __vwsn_resource_ = ::vl::__vwsn::This(::vl::presentation::GetResourceManager())->GetResourceFromClassName(::vl::WString::Unmanaged(L"gaclib_controls::ColorComponentControl"));
auto __vwsn_resolver_ = ::vl::Ptr<::vl::presentation::GuiResourcePathResolver>(new ::vl::presentation::GuiResourcePathResolver(__vwsn_resource_, ::vl::__vwsn::This(__vwsn_resource_.Obj())->GetWorkingDirectory()));
::vl::__vwsn::This(this)->SetResourceResolver(__vwsn_resolver_);
::vl::__vwsn::This(this)->__vwsn_gaclib_controls_ColorComponentControl_Initialize(this);
}
ColorComponentControl::~ColorComponentControl()
{
this->FinalizeInstanceRecursively(static_cast<::vl::presentation::controls::GuiCustomControl*>(this));
}
/***********************************************************************
Class (::gaclib_controls::ColorDialogControlConstructor)
***********************************************************************/
void ColorDialogControlConstructor::__vwsn_gaclib_controls_ColorDialogControl_Initialize(::gaclib_controls::ColorDialogControl* __vwsn_this_)
{
(this->self = __vwsn_this_);
(this->ViewModel = ::vl::__vwsn::This(__vwsn_this_)->GetViewModel());
(this->__vwsn_precompile_0 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetCellPadding(static_cast<::vl::vint>(5));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowsAndColumns(static_cast<::vl::vint>(4), static_cast<::vl::vint>(2));
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(3), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_1 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_2 = new ::vl::presentation::controls::GuiLabel(::vl::presentation::theme::ThemeName::Label));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_2)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_1));
}
(this->__vwsn_precompile_3 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->SetSite(static_cast<::vl::vint>(1), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_4 = new ::vl::presentation::controls::GuiLabel(::vl::presentation::theme::ThemeName::Label));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_4)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_3));
}
(this->__vwsn_precompile_5 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetSite(static_cast<::vl::vint>(2), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_6 = new ::vl::presentation::controls::GuiLabel(::vl::presentation::theme::ThemeName::Label));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_6)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_5));
}
(this->__vwsn_precompile_7 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_7)->SetSite(static_cast<::vl::vint>(3), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_8 = new ::vl::presentation::controls::GuiLabel(::vl::presentation::theme::ThemeName::Label));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_7)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_8)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_7));
}
(this->__vwsn_precompile_9 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
(this->colorRed = new ::gaclib_controls::ColorComponentControl());
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"colorRed"), ::vl::__vwsn::Box(this->colorRed));
{
::vl::__vwsn::This(this->colorRed)->SetTextBoxAlt(::vl::WString::Unmanaged(L"R"));
}
(this->__vwsn_precompile_10 = ::vl::__vwsn::This(this->colorRed)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_10)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->colorRed)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_9));
}
(this->__vwsn_precompile_11 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_11)->SetSite(static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
(this->colorGreen = new ::gaclib_controls::ColorComponentControl());
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"colorGreen"), ::vl::__vwsn::Box(this->colorGreen));
{
::vl::__vwsn::This(this->colorGreen)->SetTextBoxAlt(::vl::WString::Unmanaged(L"G"));
}
(this->__vwsn_precompile_12 = ::vl::__vwsn::This(this->colorGreen)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_12)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_11)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->colorGreen)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_11));
}
(this->__vwsn_precompile_13 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_13)->SetSite(static_cast<::vl::vint>(2), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
(this->colorBlue = new ::gaclib_controls::ColorComponentControl());
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"colorBlue"), ::vl::__vwsn::Box(this->colorBlue));
{
::vl::__vwsn::This(this->colorBlue)->SetTextBoxAlt(::vl::WString::Unmanaged(L"B"));
}
(this->__vwsn_precompile_14 = ::vl::__vwsn::This(this->colorBlue)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_14)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_13)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->colorBlue)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_13));
}
(this->__vwsn_precompile_15 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_15)->SetPreferredMinSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.x = static_cast<::vl::vint>(256); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_15)->SetSite(static_cast<::vl::vint>(3), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
(this->__vwsn_precompile_16 = ::vl::Ptr<::vl::presentation::elements::GuiSolidBackgroundElement>(::vl::reflection::description::Element_Constructor<::vl::presentation::elements::GuiSolidBackgroundElement>()));
{
::vl::__vwsn::This(this->__vwsn_precompile_15)->SetOwnedElement(::vl::Ptr<::vl::presentation::elements::IGuiGraphicsElement>(this->__vwsn_precompile_16));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_15));
}
{
::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetContainerComposition())->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_0));
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc4_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf5_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc5_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf6_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc6_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf7_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc7_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf8_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
::vl::__vwsn::This(this->colorRed)->SetValue(static_cast<::vl::vint>(::vl::__vwsn::This(this->ViewModel.Obj())->GetColor().r));
}
{
::vl::__vwsn::This(this->colorGreen)->SetValue(static_cast<::vl::vint>(::vl::__vwsn::This(this->ViewModel.Obj())->GetColor().g));
}
{
::vl::__vwsn::This(this->colorBlue)->SetValue(static_cast<::vl::vint>(::vl::__vwsn::This(this->ViewModel.Obj())->GetColor().b));
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc8_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc9_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf10_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc10_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf11_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogControlConstructor___vwsn_gaclib_controls_ColorDialogControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
}
ColorDialogControlConstructor::ColorDialogControlConstructor()
: self(static_cast<::gaclib_controls::ColorDialogControl*>(nullptr))
, ViewModel(::vl::Ptr<::vl::presentation::IColorDialogViewModel>())
, colorRed(static_cast<::gaclib_controls::ColorComponentControl*>(nullptr))
, colorGreen(static_cast<::gaclib_controls::ColorComponentControl*>(nullptr))
, colorBlue(static_cast<::gaclib_controls::ColorComponentControl*>(nullptr))
, __vwsn_precompile_0(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_1(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_2(static_cast<::vl::presentation::controls::GuiLabel*>(nullptr))
, __vwsn_precompile_3(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_4(static_cast<::vl::presentation::controls::GuiLabel*>(nullptr))
, __vwsn_precompile_5(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_6(static_cast<::vl::presentation::controls::GuiLabel*>(nullptr))
, __vwsn_precompile_7(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_8(static_cast<::vl::presentation::controls::GuiLabel*>(nullptr))
, __vwsn_precompile_9(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_10(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_11(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_12(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_13(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_14(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_15(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_16(::vl::Ptr<::vl::presentation::elements::GuiSolidBackgroundElement>())
{
}
/***********************************************************************
Class (::gaclib_controls::ColorDialogControl)
***********************************************************************/
::vl::presentation::Color ColorDialogControl::GetValue()
{
return this->__vwsn_prop_Value;
}
void ColorDialogControl::SetValue(::vl::presentation::Color __vwsn_value_)
{
if ((this->__vwsn_prop_Value != __vwsn_value_))
{
(this->__vwsn_prop_Value = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->ValueChanged)();
}
}
::vl::presentation::Color ColorDialogControl::ReadColor()
{
return [&](){ ::vl::presentation::Color __vwsn_temp__; __vwsn_temp__.r = static_cast<::vl::vuint8_t>(::vl::__vwsn::This(this->colorRed)->GetValue()); __vwsn_temp__.g = static_cast<::vl::vuint8_t>(::vl::__vwsn::This(this->colorGreen)->GetValue()); __vwsn_temp__.b = static_cast<::vl::vuint8_t>(::vl::__vwsn::This(this->colorBlue)->GetValue()); return __vwsn_temp__; }();
}
::vl::Ptr<::gaclib_controls::IDialogStringsStrings> ColorDialogControl::GetStrings()
{
return this->__vwsn_prop_Strings;
}
void ColorDialogControl::SetStrings(::vl::Ptr<::gaclib_controls::IDialogStringsStrings> __vwsn_value_)
{
if ((this->__vwsn_prop_Strings.Obj() != __vwsn_value_.Obj()))
{
(this->__vwsn_prop_Strings = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->StringsChanged)();
}
}
::vl::Ptr<::vl::presentation::IColorDialogViewModel> ColorDialogControl::GetViewModel()
{
return this->__vwsn_parameter_ViewModel;
}
ColorDialogControl::ColorDialogControl(::vl::Ptr<::vl::presentation::IColorDialogViewModel> __vwsn_ctor_parameter_ViewModel)
: ::vl::presentation::controls::GuiCustomControl(::vl::presentation::theme::ThemeName::CustomControl)
, __vwsn_prop_Value(::vl::__vwsn::Parse<::vl::presentation::Color>(::vl::WString::Unmanaged(L"#FFFFFF")))
, __vwsn_prop_Strings(::gaclib_controls::DialogStrings::Get(::vl::__vwsn::Parse<::vl::Locale>(::vl::WString::Unmanaged(L"en-US"))))
, __vwsn_parameter_ViewModel(::vl::Ptr<::vl::presentation::IColorDialogViewModel>())
{
(this->__vwsn_parameter_ViewModel = __vwsn_ctor_parameter_ViewModel);
auto __vwsn_resource_ = ::vl::__vwsn::This(::vl::presentation::GetResourceManager())->GetResourceFromClassName(::vl::WString::Unmanaged(L"gaclib_controls::ColorDialogControl"));
auto __vwsn_resolver_ = ::vl::Ptr<::vl::presentation::GuiResourcePathResolver>(new ::vl::presentation::GuiResourcePathResolver(__vwsn_resource_, ::vl::__vwsn::This(__vwsn_resource_.Obj())->GetWorkingDirectory()));
::vl::__vwsn::This(this)->SetResourceResolver(__vwsn_resolver_);
::vl::__vwsn::This(this)->__vwsn_gaclib_controls_ColorDialogControl_Initialize(this);
}
ColorDialogControl::~ColorDialogControl()
{
this->FinalizeInstanceRecursively(static_cast<::vl::presentation::controls::GuiCustomControl*>(this));
}
/***********************************************************************
Class (::gaclib_controls::ColorDialogWindowConstructor)
***********************************************************************/
void ColorDialogWindowConstructor::__vwsn_gaclib_controls_ColorDialogWindow_Initialize(::gaclib_controls::ColorDialogWindow* __vwsn_this_)
{
(this->self = __vwsn_this_);
(this->ViewModel = ::vl::__vwsn::This(__vwsn_this_)->GetViewModel());
{
::vl::__vwsn::This(this->self)->SetIconVisible(false);
}
{
::vl::__vwsn::This(this->self)->SetMinimizedBox(false);
}
{
::vl::__vwsn::This(this->self)->SetMaximizedBox(false);
}
{
::vl::__vwsn::This(this->self)->SetShowInTaskBar(false);
}
{
::vl::__vwsn::This(this->self)->SetClientSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.x = static_cast<::vl::vint>(240); __vwsn_temp__.y = static_cast<::vl::vint>(120); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_0 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetCellPadding(static_cast<::vl::vint>(10));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(10); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowsAndColumns(static_cast<::vl::vint>(2), static_cast<::vl::vint>(3));
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
}
(this->__vwsn_precompile_1 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(3));
}
(this->colorControl = new ::gaclib_controls::ColorDialogControl(this->ViewModel));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"colorControl"), ::vl::__vwsn::Box(this->colorControl));
(this->__vwsn_precompile_2 = ::vl::__vwsn::This(this->colorControl)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->colorControl)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_1));
}
(this->__vwsn_precompile_3 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->SetSite(static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_4 = new ::vl::presentation::controls::GuiButton(::vl::presentation::theme::ThemeName::Button));
}
(this->__vwsn_precompile_5 = ::vl::__vwsn::This(this->__vwsn_precompile_4)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetPreferredMinSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.x = static_cast<::vl::vint>(80); __vwsn_temp__.y = static_cast<::vl::vint>(24); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_4)->SetAlt(::vl::WString::Unmanaged(L"O"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_4)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_3));
}
(this->__vwsn_precompile_6 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_6)->SetSite(static_cast<::vl::vint>(1), static_cast<::vl::vint>(2), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_7 = new ::vl::presentation::controls::GuiButton(::vl::presentation::theme::ThemeName::Button));
}
(this->__vwsn_precompile_8 = ::vl::__vwsn::This(this->__vwsn_precompile_7)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_8)->SetPreferredMinSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.x = static_cast<::vl::vint>(80); __vwsn_temp__.y = static_cast<::vl::vint>(24); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_8)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_7)->SetAlt(::vl::WString::Unmanaged(L"C"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_6)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_7)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_6));
}
{
::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetContainerComposition())->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_0));
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc11_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf12_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf13_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->__vwsn_precompile_4)->Clicked, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc12_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf14_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf15_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->__vwsn_precompile_7)->Clicked, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc13_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf16_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc14_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf17_GuiFakeDialogServiceUI_gaclib_controls_ColorDialogWindowConstructor___vwsn_gaclib_controls_ColorDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
}
ColorDialogWindowConstructor::ColorDialogWindowConstructor()
: self(static_cast<::gaclib_controls::ColorDialogWindow*>(nullptr))
, ViewModel(::vl::Ptr<::vl::presentation::IColorDialogViewModel>())
, colorControl(static_cast<::gaclib_controls::ColorDialogControl*>(nullptr))
, __vwsn_precompile_0(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_1(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_2(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_3(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_4(static_cast<::vl::presentation::controls::GuiButton*>(nullptr))
, __vwsn_precompile_5(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_6(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_7(static_cast<::vl::presentation::controls::GuiButton*>(nullptr))
, __vwsn_precompile_8(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
{
}
/***********************************************************************
Class (::gaclib_controls::ColorDialogWindow)
***********************************************************************/
::vl::Ptr<::gaclib_controls::IDialogStringsStrings> ColorDialogWindow::GetStrings()
{
return this->__vwsn_prop_Strings;
}
void ColorDialogWindow::SetStrings(::vl::Ptr<::gaclib_controls::IDialogStringsStrings> __vwsn_value_)
{
if ((this->__vwsn_prop_Strings.Obj() != __vwsn_value_.Obj()))
{
(this->__vwsn_prop_Strings = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->StringsChanged)();
}
}
::vl::Ptr<::vl::presentation::IColorDialogViewModel> ColorDialogWindow::GetViewModel()
{
return this->__vwsn_parameter_ViewModel;
}
ColorDialogWindow::ColorDialogWindow(::vl::Ptr<::vl::presentation::IColorDialogViewModel> __vwsn_ctor_parameter_ViewModel)
: ::vl::presentation::controls::GuiWindow(::vl::presentation::theme::ThemeName::Window)
, __vwsn_prop_Strings(::gaclib_controls::DialogStrings::Get(::vl::__vwsn::Parse<::vl::Locale>(::vl::WString::Unmanaged(L"en-US"))))
, __vwsn_parameter_ViewModel(::vl::Ptr<::vl::presentation::IColorDialogViewModel>())
{
(this->__vwsn_parameter_ViewModel = __vwsn_ctor_parameter_ViewModel);
auto __vwsn_resource_ = ::vl::__vwsn::This(::vl::presentation::GetResourceManager())->GetResourceFromClassName(::vl::WString::Unmanaged(L"gaclib_controls::ColorDialogWindow"));
auto __vwsn_resolver_ = ::vl::Ptr<::vl::presentation::GuiResourcePathResolver>(new ::vl::presentation::GuiResourcePathResolver(__vwsn_resource_, ::vl::__vwsn::This(__vwsn_resource_.Obj())->GetWorkingDirectory()));
::vl::__vwsn::This(this)->SetResourceResolver(__vwsn_resolver_);
::vl::__vwsn::This(this)->__vwsn_gaclib_controls_ColorDialogWindow_Initialize(this);
}
ColorDialogWindow::~ColorDialogWindow()
{
this->FinalizeInstanceRecursively(static_cast<::vl::presentation::controls::GuiControlHost*>(this));
}
/***********************************************************************
Class (::gaclib_controls::DialogStrings)
***********************************************************************/
::vl::Ptr<::gaclib_controls::IDialogStringsStrings> DialogStrings::__vwsn_ls_en_US_BuildStrings(::vl::Locale __vwsn_ls_locale)
{
return ::vl::Ptr<::gaclib_controls::IDialogStringsStrings>(new ::vl_workflow_global::__vwsnc58_GuiFakeDialogServiceUI_gaclib_controls_DialogStrings___vwsn_ls_en_US_BuildStrings__gaclib_controls_IDialogStringsStrings());
}
void DialogStrings::Install(::vl::Locale __vwsn_ls_locale, ::vl::Ptr<::gaclib_controls::IDialogStringsStrings> __vwsn_ls_impl)
{
if (::vl::__vwsn::This(::vl::__vwsn::This(GLOBAL_NAME __vwsn_ls_DialogStrings.Obj())->GetKeys().Obj())->Contains(::vl::__vwsn::Box(__vwsn_ls_locale)))
{
throw ::vl::Exception(((::vl::WString::Unmanaged(L"Localized strings \"gaclib_controls::DialogStrings\" has already registered for locale \"") + ::vl::__vwsn::ToString(__vwsn_ls_locale)) + ::vl::WString::Unmanaged(L"\".")));
}
::vl::__vwsn::This(GLOBAL_NAME __vwsn_ls_DialogStrings.Obj())->Set(::vl::__vwsn::Box(__vwsn_ls_locale), ::vl::__vwsn::Box(__vwsn_ls_impl));
}
::vl::Ptr<::gaclib_controls::IDialogStringsStrings> DialogStrings::Get(::vl::Locale __vwsn_ls_locale)
{
if (::vl::__vwsn::This(::vl::__vwsn::This(GLOBAL_NAME __vwsn_ls_DialogStrings.Obj())->GetKeys().Obj())->Contains(::vl::__vwsn::Box(__vwsn_ls_locale)))
{
return ::vl::__vwsn::Unbox<::vl::Ptr<::gaclib_controls::IDialogStringsStrings>>(::vl::__vwsn::This(GLOBAL_NAME __vwsn_ls_DialogStrings.Obj())->Get(::vl::__vwsn::Box(__vwsn_ls_locale)));
}
return ::vl::__vwsn::Unbox<::vl::Ptr<::gaclib_controls::IDialogStringsStrings>>(::vl::__vwsn::This(GLOBAL_NAME __vwsn_ls_DialogStrings.Obj())->Get(::vl::__vwsn::Box(::vl::__vwsn::Parse<::vl::Locale>(::vl::WString::Unmanaged(L"en-US")))));
}
DialogStrings::DialogStrings()
{
}
/***********************************************************************
Class (::gaclib_controls::FileDialogWindowConstructor)
***********************************************************************/
void FileDialogWindowConstructor::__vwsn_gaclib_controls_FileDialogWindow_Initialize(::gaclib_controls::FileDialogWindow* __vwsn_this_)
{
(this->self = __vwsn_this_);
(this->ViewModel = ::vl::__vwsn::This(__vwsn_this_)->GetViewModel());
{
::vl::__vwsn::This(this->self)->SetIconVisible(false);
}
{
::vl::__vwsn::This(this->self)->SetMinimizedBox(false);
}
{
::vl::__vwsn::This(this->self)->SetMaximizedBox(false);
}
{
::vl::__vwsn::This(this->self)->SetShowInTaskBar(false);
}
{
::vl::__vwsn::This(this->self)->SetClientSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.x = static_cast<::vl::vint>(480); __vwsn_temp__.y = static_cast<::vl::vint>(360); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_0 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetCellPadding(static_cast<::vl::vint>(5));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(5); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowsAndColumns(static_cast<::vl::vint>(2), static_cast<::vl::vint>(3));
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
}
(this->__vwsn_precompile_1 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(3));
}
(this->filePickerControl = new ::gaclib_controls::FilePickerControl(this->ViewModel));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"filePickerControl"), ::vl::__vwsn::Box(this->filePickerControl));
(this->__vwsn_precompile_2 = ::vl::__vwsn::This(this->filePickerControl)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->filePickerControl)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_1));
}
(this->__vwsn_precompile_3 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->SetSite(static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->buttonOK = new ::vl::presentation::controls::GuiButton(::vl::presentation::theme::ThemeName::Button));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"buttonOK"), ::vl::__vwsn::Box(this->buttonOK));
}
(this->__vwsn_precompile_4 = ::vl::__vwsn::This(this->buttonOK)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_4)->SetPreferredMinSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.x = static_cast<::vl::vint>(80); __vwsn_temp__.y = static_cast<::vl::vint>(24); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_4)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->buttonOK)->SetAlt(::vl::WString::Unmanaged(L"O"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->buttonOK)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_3));
}
(this->__vwsn_precompile_5 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetSite(static_cast<::vl::vint>(1), static_cast<::vl::vint>(2), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_6 = new ::vl::presentation::controls::GuiButton(::vl::presentation::theme::ThemeName::Button));
}
(this->__vwsn_precompile_7 = ::vl::__vwsn::This(this->__vwsn_precompile_6)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_7)->SetPreferredMinSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.x = static_cast<::vl::vint>(80); __vwsn_temp__.y = static_cast<::vl::vint>(24); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_7)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_6)->SetAlt(::vl::WString::Unmanaged(L"C"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_6)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_5));
}
{
::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetContainerComposition())->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_0));
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf18_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->filePickerControl)->RequestClose, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc15_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf20_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf21_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->buttonOK)->Clicked, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc16_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf22_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf23_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->__vwsn_precompile_6)->Clicked, __vwsn_event_handler_);
}
{
::vl::__vwsn::This(this->self)->SetText(::vl::__vwsn::This(this->ViewModel.Obj())->GetTitle());
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc17_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf24_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindowConstructor___vwsn_gaclib_controls_FileDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
}
FileDialogWindowConstructor::FileDialogWindowConstructor()
: self(static_cast<::gaclib_controls::FileDialogWindow*>(nullptr))
, ViewModel(::vl::Ptr<::vl::presentation::IFileDialogViewModel>())
, filePickerControl(static_cast<::gaclib_controls::FilePickerControl*>(nullptr))
, buttonOK(static_cast<::vl::presentation::controls::GuiButton*>(nullptr))
, __vwsn_precompile_0(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_1(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_2(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_3(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_4(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_5(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_6(static_cast<::vl::presentation::controls::GuiButton*>(nullptr))
, __vwsn_precompile_7(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
{
}
/***********************************************************************
Class (::gaclib_controls::FileDialogWindow)
***********************************************************************/
void FileDialogWindow::MakeOpenFileDialog()
{
::vl::__vwsn::This(this->buttonOK)->SetText(::vl::__vwsn::This(this->GetStrings().Obj())->FileDialogOpen());
}
void FileDialogWindow::MakeSaveFileDialog()
{
::vl::__vwsn::This(this->buttonOK)->SetText(::vl::__vwsn::This(this->GetStrings().Obj())->FileDialogSave());
}
::vl::Ptr<::gaclib_controls::IDialogStringsStrings> FileDialogWindow::GetStrings()
{
return this->__vwsn_prop_Strings;
}
void FileDialogWindow::SetStrings(::vl::Ptr<::gaclib_controls::IDialogStringsStrings> __vwsn_value_)
{
if ((this->__vwsn_prop_Strings.Obj() != __vwsn_value_.Obj()))
{
(this->__vwsn_prop_Strings = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->StringsChanged)();
}
}
::vl::Ptr<::vl::presentation::IFileDialogViewModel> FileDialogWindow::GetViewModel()
{
return this->__vwsn_parameter_ViewModel;
}
FileDialogWindow::FileDialogWindow(::vl::Ptr<::vl::presentation::IFileDialogViewModel> __vwsn_ctor_parameter_ViewModel)
: ::vl::presentation::controls::GuiWindow(::vl::presentation::theme::ThemeName::Window)
, __vwsn_prop_Strings(::gaclib_controls::DialogStrings::Get(::vl::__vwsn::Parse<::vl::Locale>(::vl::WString::Unmanaged(L"en-US"))))
, __vwsn_parameter_ViewModel(::vl::Ptr<::vl::presentation::IFileDialogViewModel>())
{
(this->__vwsn_parameter_ViewModel = __vwsn_ctor_parameter_ViewModel);
auto __vwsn_resource_ = ::vl::__vwsn::This(::vl::presentation::GetResourceManager())->GetResourceFromClassName(::vl::WString::Unmanaged(L"gaclib_controls::FileDialogWindow"));
auto __vwsn_resolver_ = ::vl::Ptr<::vl::presentation::GuiResourcePathResolver>(new ::vl::presentation::GuiResourcePathResolver(__vwsn_resource_, ::vl::__vwsn::This(__vwsn_resource_.Obj())->GetWorkingDirectory()));
::vl::__vwsn::This(this)->SetResourceResolver(__vwsn_resolver_);
::vl::__vwsn::This(this)->__vwsn_gaclib_controls_FileDialogWindow_Initialize(this);
this->__vwsn_instance_ctor_();
}
void FileDialogWindow::__vwsn_instance_ctor_()
{
::vl::__vwsn::This(::vl::presentation::controls::GetApplication())->InvokeInMainThread(static_cast<::vl::presentation::controls::GuiControlHost*>(this->self), vl::Func(::vl_workflow_global::__vwsnf25_GuiFakeDialogServiceUI_gaclib_controls_FileDialogWindow___vwsn_instance_ctor__(this)));
}
FileDialogWindow::~FileDialogWindow()
{
this->FinalizeInstanceRecursively(static_cast<::vl::presentation::controls::GuiControlHost*>(this));
}
/***********************************************************************
Class (::gaclib_controls::FilePickerControlConstructor)
***********************************************************************/
void FilePickerControlConstructor::__vwsn_gaclib_controls_FilePickerControl_Initialize(::gaclib_controls::FilePickerControl* __vwsn_this_)
{
(this->self = __vwsn_this_);
(this->ViewModel = ::vl::__vwsn::This(__vwsn_this_)->GetViewModel());
(this->__vwsn_precompile_24 = ::vl::__vwsn::This(this->self)->GetViewModel());
(this->__vwsn_precompile_0 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetCellPadding(static_cast<::vl::vint>(5));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowsAndColumns(static_cast<::vl::vint>(3), static_cast<::vl::vint>(1));
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_1 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_2 = new ::vl::presentation::controls::GuiLabel(::vl::presentation::theme::ThemeName::Label));
}
(this->__vwsn_precompile_3 = ::vl::__vwsn::This(this->__vwsn_precompile_2)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_2)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_1));
}
(this->__vwsn_precompile_4 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_4)->SetSite(static_cast<::vl::vint>(1), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
(this->__vwsn_precompile_5 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetCellPadding(static_cast<::vl::vint>(5));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetRowsAndColumns(static_cast<::vl::vint>(1), static_cast<::vl::vint>(2));
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Absolute; __vwsn_temp__.absolute = static_cast<::vl::vint>(192); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetColumnOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_6 = new ::vl::presentation::compositions::GuiColumnSplitterComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_6)->SetColumnsToTheLeft(static_cast<::vl::vint>(1));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_6));
}
(this->__vwsn_precompile_7 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_7)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->treeView = new ::vl::presentation::controls::GuiBindableTreeView(::vl::presentation::theme::ThemeName::TreeView));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"treeView"), ::vl::__vwsn::Box(this->treeView));
}
{
::vl::__vwsn::This(this->treeView)->SetChildrenProperty(vl::Func(::vl_workflow_global::__vwsnf26_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this)));
}
{
::vl::__vwsn::This(this->treeView)->SetHorizontalAlwaysVisible(false);
}
{
::vl::__vwsn::This(this->treeView)->SetVerticalAlwaysVisible(false);
}
{
::vl::__vwsn::This(this->treeView)->SetTextProperty(vl::Func(::vl_workflow_global::__vwsnf27_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this)));
}
(this->__vwsn_precompile_8 = ::vl::__vwsn::This(this->treeView)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_8)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->treeView)->SetAlt(::vl::WString::Unmanaged(L"D"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_7)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->treeView)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_7));
}
(this->__vwsn_precompile_9 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->dataGrid = new ::vl::presentation::controls::GuiBindableDataGrid(::vl::presentation::theme::ThemeName::ListView));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"dataGrid"), ::vl::__vwsn::Box(this->dataGrid));
}
(this->__vwsn_precompile_12 = ::vl::__vwsn::This(this->dataGrid)->GetFocusableComposition());
{
::vl::__vwsn::This(this->dataGrid)->SetView(::vl::presentation::controls::ListViewView::List);
}
{
::vl::__vwsn::This(this->dataGrid)->SetHorizontalAlwaysVisible(false);
}
{
::vl::__vwsn::This(this->dataGrid)->SetVerticalAlwaysVisible(false);
}
(this->__vwsn_precompile_11 = ::vl::__vwsn::This(this->dataGrid)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_11)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->dataGrid)->SetAlt(::vl::WString::Unmanaged(L"F"));
}
(this->__vwsn_precompile_10 = ::vl::Ptr<::vl::presentation::controls::list::DataColumn>(new ::vl::presentation::controls::list::DataColumn()));
{
::vl::__vwsn::This(this->__vwsn_precompile_10.Obj())->SetTextProperty(vl::Func(::vl_workflow_global::__vwsnf28_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this)));
}
{
auto __vwsn_collection_ = ::vl::__vwsn::UnboxCollection<::vl::reflection::description::IValueList>(::vl::__vwsn::This(this->dataGrid)->GetColumns());
::vl::__vwsn::This(__vwsn_collection_.Obj())->Add(::vl::__vwsn::Box(this->__vwsn_precompile_10));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->dataGrid)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_9));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_4)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_5));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_4));
}
(this->__vwsn_precompile_13 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_13)->SetSite(static_cast<::vl::vint>(2), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
(this->__vwsn_precompile_14 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_14)->SetCellPadding(static_cast<::vl::vint>(5));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_14)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_14)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_14)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_14)->SetRowsAndColumns(static_cast<::vl::vint>(1), static_cast<::vl::vint>(3));
::vl::__vwsn::This(this->__vwsn_precompile_14)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_14)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_14)->SetColumnOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_14)->SetColumnOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Absolute; __vwsn_temp__.absolute = static_cast<::vl::vint>(120); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_15 = new ::vl::presentation::compositions::GuiColumnSplitterComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_15)->SetColumnsToTheLeft(static_cast<::vl::vint>(2));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_14)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_15));
}
(this->__vwsn_precompile_16 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_16)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_17 = new ::vl::presentation::controls::GuiLabel(::vl::presentation::theme::ThemeName::Label));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_16)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_17)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_14)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_16));
}
(this->__vwsn_precompile_18 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_18)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->textBox = new ::vl::presentation::controls::GuiSinglelineTextBox(::vl::presentation::theme::ThemeName::SinglelineTextBox));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"textBox"), ::vl::__vwsn::Box(this->textBox));
}
(this->__vwsn_precompile_20 = ::vl::__vwsn::This(this->textBox)->GetFocusableComposition());
(this->__vwsn_precompile_19 = ::vl::__vwsn::This(this->textBox)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_19)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->textBox)->SetAlt(::vl::WString::Unmanaged(L"S"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_18)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->textBox)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_14)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_18));
}
(this->__vwsn_precompile_21 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_21)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(2), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_22 = new ::vl::presentation::controls::GuiBindableTextList(::vl::presentation::theme::ThemeName::TextList));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_22)->SetHorizontalAlwaysVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_22)->SetVerticalAlwaysVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_22)->SetTextProperty(vl::Func(::vl_workflow_global::__vwsnf29_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this)));
}
{
(this->comboBox = new ::vl::presentation::controls::GuiComboBoxListControl(::vl::presentation::theme::ThemeName::ComboBox, static_cast<::vl::presentation::controls::GuiSelectableListControl*>(this->__vwsn_precompile_22)));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"comboBox"), ::vl::__vwsn::Box(this->comboBox));
}
(this->__vwsn_precompile_23 = ::vl::__vwsn::This(this->comboBox)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_23)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->comboBox)->SetAlt(::vl::WString::Unmanaged(L"E"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_21)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->comboBox)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_14)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_21));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_13)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_14));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_13));
}
{
::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetContainerComposition())->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_0));
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc18_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf30_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
::vl::__vwsn::This(this->treeView)->SetImageProperty(vl::Func(::vl_workflow_global::__vwsno31_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this)));
}
{
::vl::__vwsn::This(this->dataGrid)->SetMultiSelect(::vl::__vwsn::This(this->ViewModel.Obj())->GetEnabledMultipleSelection());
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc19_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf32_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf33_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->__vwsn_precompile_12)->GetEventReceiver()->keyUp, __vwsn_event_handler_);
}
{
::vl::__vwsn::This(this->dataGrid)->SetSmallImageProperty(vl::Func(::vl_workflow_global::__vwsno34_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this)));
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf35_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->dataGrid)->SelectionChanged, __vwsn_event_handler_);
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf36_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->dataGrid)->ItemLeftButtonDoubleClick, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc20_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf38_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf39_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->__vwsn_precompile_20)->GetEventReceiver()->keyUp, __vwsn_event_handler_);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_22)->SetItemSource(::vl::Ptr<::vl::reflection::description::IValueEnumerable>(::vl::__vwsn::UnboxCollection<::vl::reflection::description::IValueReadonlyList>(::vl::__vwsn::This(this->ViewModel.Obj())->GetFilters())));
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc21_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf40_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc22_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf41_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf42_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->__vwsn_precompile_24.Obj())->SelectedFolderChanged, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc23_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf43_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControlConstructor___vwsn_gaclib_controls_FilePickerControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
}
FilePickerControlConstructor::FilePickerControlConstructor()
: self(static_cast<::gaclib_controls::FilePickerControl*>(nullptr))
, ViewModel(::vl::Ptr<::vl::presentation::IFileDialogViewModel>())
, textBox(static_cast<::vl::presentation::controls::GuiSinglelineTextBox*>(nullptr))
, treeView(static_cast<::vl::presentation::controls::GuiBindableTreeView*>(nullptr))
, dataGrid(static_cast<::vl::presentation::controls::GuiBindableDataGrid*>(nullptr))
, comboBox(static_cast<::vl::presentation::controls::GuiComboBoxListControl*>(nullptr))
, __vwsn_precompile_0(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_1(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_2(static_cast<::vl::presentation::controls::GuiLabel*>(nullptr))
, __vwsn_precompile_3(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_4(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_5(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_6(static_cast<::vl::presentation::compositions::GuiColumnSplitterComposition*>(nullptr))
, __vwsn_precompile_7(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_8(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_9(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_10(::vl::Ptr<::vl::presentation::controls::list::DataColumn>())
, __vwsn_precompile_11(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_12(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(nullptr))
, __vwsn_precompile_13(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_14(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_15(static_cast<::vl::presentation::compositions::GuiColumnSplitterComposition*>(nullptr))
, __vwsn_precompile_16(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_17(static_cast<::vl::presentation::controls::GuiLabel*>(nullptr))
, __vwsn_precompile_18(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_19(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_20(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(nullptr))
, __vwsn_precompile_21(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_22(static_cast<::vl::presentation::controls::GuiBindableTextList*>(nullptr))
, __vwsn_precompile_23(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_24(::vl::Ptr<::vl::presentation::IFileDialogViewModel>())
{
}
/***********************************************************************
Class (::gaclib_controls::FilePickerControl)
***********************************************************************/
::vl::collections::LazyList<::vl::Ptr<::vl::presentation::IFileDialogFile>> FilePickerControl::GetSelectedFiles()
{
return ::vl::reflection::description::GetLazyList<::vl::Ptr<::vl::presentation::IFileDialogFile>>(::vl::reflection::description::EnumerableCoroutine::Create(vl::Func(::vl_workflow_global::__vwsnf44_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_GetSelectedFiles_(this))));
}
::vl::collections::LazyList<::vl::WString> FilePickerControl::GetSelection()
{
return ::vl::__vwsn::This(this->GetViewModel().Obj())->ParseDisplayString(::vl::__vwsn::This(this->textBox)->GetText());
}
void FilePickerControl::LocateSelectedFolderInTreeView()
{
auto fragments = ::vl::reflection::description::IValueList::Create();
auto currentFolder = ::vl::__vwsn::This(this->GetViewModel().Obj())->GetSelectedFolder();
if ((! static_cast<bool>(currentFolder)))
{
return;
}
while ((static_cast<bool>(currentFolder) && (::vl::__vwsn::This(currentFolder.Obj())->GetType() == ::vl::presentation::FileDialogFolderType::Folder)))
{
::vl::__vwsn::This(fragments.Obj())->Add(::vl::__vwsn::Box(currentFolder));
(currentFolder = ::vl::__vwsn::This(currentFolder.Obj())->GetParent());
}
auto currentNode = ::vl::__vwsn::This(::vl::__vwsn::This(this->treeView)->GetNodeRootProvider())->GetRootNode();
{
auto __vwsn_for_enumerable_fragment = ::vl::reflection::description::Sys::ReverseEnumerable(::vl::Ptr<::vl::reflection::description::IValueEnumerable>(fragments));
auto __vwsn_for_enumerator_fragment = ::vl::__vwsn::This(__vwsn_for_enumerable_fragment.Obj())->CreateEnumerator();
while (::vl::__vwsn::This(__vwsn_for_enumerator_fragment.Obj())->Next())
{
auto fragment = ::vl::__vwsn::Unbox<::vl::Ptr<::vl::presentation::IFileDialogFolder>>(::vl::__vwsn::This(__vwsn_for_enumerator_fragment.Obj())->GetCurrent());
{
::vl::__vwsn::This(currentNode.Obj())->SetExpanding(true);
(currentNode = ::vl::__vwsn::This(currentNode.Obj())->GetChild(::vl::__vwsn::This(fragment.Obj())->GetIndex()));
if ((! static_cast<bool>(currentNode)))
{
return;
}
}
}
}
auto index = ::vl::__vwsn::This(::vl::__vwsn::This(this->treeView)->GetNodeItemView())->CalculateNodeVisibilityIndex(::vl::__vwsn::Ensure(static_cast<::vl::presentation::controls::tree::INodeProvider*>(currentNode.Obj())));
::vl::__vwsn::This(this->treeView)->EnsureItemVisible(index);
::vl::__vwsn::This(this->treeView)->SelectItemsByClick(index, false, false, true);
}
::vl::Ptr<::vl::presentation::controls::list::IDataFilter> FilePickerControl::CreateFileFilter(::vl::Ptr<::vl::presentation::IFileDialogFilter> filter)
{
if ((! static_cast<bool>(filter)))
{
return ::vl::Ptr<::vl::presentation::controls::list::IDataFilter>();
}
else
{
return ::vl::Ptr<::vl::presentation::controls::list::IDataFilter>(new ::vl_workflow_global::__vwsnc25_GuiFakeDialogServiceUI_gaclib_controls_FilePickerControl_CreateFileFilter__vl_presentation_controls_list_IDataFilter(filter, this));
}
}
::vl::Ptr<::gaclib_controls::IDialogStringsStrings> FilePickerControl::GetStrings()
{
return this->__vwsn_prop_Strings;
}
void FilePickerControl::SetStrings(::vl::Ptr<::gaclib_controls::IDialogStringsStrings> __vwsn_value_)
{
if ((this->__vwsn_prop_Strings.Obj() != __vwsn_value_.Obj()))
{
(this->__vwsn_prop_Strings = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->StringsChanged)();
}
}
::vl::Ptr<::vl::presentation::IFileDialogViewModel> FilePickerControl::GetViewModel()
{
return this->__vwsn_parameter_ViewModel;
}
FilePickerControl::FilePickerControl(::vl::Ptr<::vl::presentation::IFileDialogViewModel> __vwsn_ctor_parameter_ViewModel)
: ::vl::presentation::controls::GuiCustomControl(::vl::presentation::theme::ThemeName::CustomControl)
, imageFolder(::vl::Ptr<::vl::presentation::GuiImageData>())
, imageFile(::vl::Ptr<::vl::presentation::GuiImageData>())
, __vwsn_prop_Strings(::gaclib_controls::DialogStrings::Get(::vl::__vwsn::Parse<::vl::Locale>(::vl::WString::Unmanaged(L"en-US"))))
, __vwsn_parameter_ViewModel(::vl::Ptr<::vl::presentation::IFileDialogViewModel>())
{
(this->__vwsn_parameter_ViewModel = __vwsn_ctor_parameter_ViewModel);
auto __vwsn_resource_ = ::vl::__vwsn::This(::vl::presentation::GetResourceManager())->GetResourceFromClassName(::vl::WString::Unmanaged(L"gaclib_controls::FilePickerControl"));
auto __vwsn_resolver_ = ::vl::Ptr<::vl::presentation::GuiResourcePathResolver>(new ::vl::presentation::GuiResourcePathResolver(__vwsn_resource_, ::vl::__vwsn::This(__vwsn_resource_.Obj())->GetWorkingDirectory()));
::vl::__vwsn::This(this)->SetResourceResolver(__vwsn_resolver_);
::vl::__vwsn::This(this)->__vwsn_gaclib_controls_FilePickerControl_Initialize(this);
this->__vwsn_instance_ctor_();
}
void FilePickerControl::__vwsn_instance_ctor_()
{
(this->imageFolder = ::vl::__vwsn::Ensure(::vl::__vwsn::SharedPtrCast<::vl::presentation::GuiImageData>(::vl::__vwsn::This(this->self)->ResolveResource(::vl::WString::Unmanaged(L"res"), ::vl::WString::Unmanaged(L"Images/Folder"), true).Obj())));
(this->imageFile = ::vl::__vwsn::Ensure(::vl::__vwsn::SharedPtrCast<::vl::presentation::GuiImageData>(::vl::__vwsn::This(this->self)->ResolveResource(::vl::WString::Unmanaged(L"res"), ::vl::WString::Unmanaged(L"Images/File"), true).Obj())));
::vl::__vwsn::This(this->GetViewModel().Obj())->InitLocalizedText(::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetStrings().Obj())->FileDialogTextLoadingFolders(), ::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetStrings().Obj())->FileDialogTextLoadingFiles(), ::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetStrings().Obj())->FileDialogErrorEmptySelection(), ::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetStrings().Obj())->FileDialogErrorFileNotExist(), ::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetStrings().Obj())->FileDialogErrorFileExpected(), ::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetStrings().Obj())->FileDialogErrorFolderNotExist(), ::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetStrings().Obj())->FileDialogErrorMultipleSelectionNotEnabled(), ::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetStrings().Obj())->FileDialogAskCreateFile(), ::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetStrings().Obj())->FileDialogAskOverrideFile());
::vl::__vwsn::This(this->treeView)->SetItemSource(::vl::__vwsn::Box(::vl::__vwsn::This(this->GetViewModel().Obj())->GetRootFolder()));
::vl::__vwsn::This(this->dataGrid)->SetItemSource(::vl::Ptr<::vl::reflection::description::IValueEnumerable>(::vl::__vwsn::UnboxCollection<::vl::reflection::description::IValueObservableList>(::vl::__vwsn::This(this->GetViewModel().Obj())->GetFiles())));
::vl::__vwsn::This(this->comboBox)->SetSelectedIndex(::vl::__vwsn::This(::vl::__vwsn::UnboxCollection<::vl::reflection::description::IValueReadonlyList>(::vl::__vwsn::This(this->GetViewModel().Obj())->GetFilters()).Obj())->IndexOf(::vl::__vwsn::Box(::vl::__vwsn::This(this->GetViewModel().Obj())->GetSelectedFilter())));
::vl::__vwsn::This(this->GetViewModel().Obj())->RefreshFiles();
}
FilePickerControl::~FilePickerControl()
{
this->FinalizeInstanceRecursively(static_cast<::vl::presentation::controls::GuiCustomControl*>(this));
}
/***********************************************************************
Class (::gaclib_controls::FontNameControlConstructor)
***********************************************************************/
void FontNameControlConstructor::__vwsn_gaclib_controls_FontNameControl_Initialize(::gaclib_controls::FontNameControl* __vwsn_this_)
{
(this->self = __vwsn_this_);
(this->ViewModel = ::vl::__vwsn::This(__vwsn_this_)->GetViewModel());
{
(this->__vwsn_precompile_0 = new ::vl::presentation::controls::GuiControl(::vl::presentation::theme::ThemeName::GroupBox));
}
(this->__vwsn_precompile_6 = ::vl::__vwsn::This(this->__vwsn_precompile_0)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_6)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_1 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetCellPadding(static_cast<::vl::vint>(5));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(5); __vwsn_temp__.top = static_cast<::vl::vint>(5); __vwsn_temp__.right = static_cast<::vl::vint>(5); __vwsn_temp__.bottom = static_cast<::vl::vint>(5); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetRowsAndColumns(static_cast<::vl::vint>(2), static_cast<::vl::vint>(1));
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetRowOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_2 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->textBox = new ::vl::presentation::controls::GuiSinglelineTextBox(::vl::presentation::theme::ThemeName::SinglelineTextBox));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"textBox"), ::vl::__vwsn::Box(this->textBox));
}
(this->__vwsn_precompile_3 = ::vl::__vwsn::This(this->textBox)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->textBox)->SetAlt(::vl::WString::Unmanaged(L"F"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->textBox)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_2));
}
(this->__vwsn_precompile_4 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_4)->SetSite(static_cast<::vl::vint>(1), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->textList = new ::vl::presentation::controls::GuiBindableTextList(::vl::presentation::theme::ThemeName::TextList));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"textList"), ::vl::__vwsn::Box(this->textList));
}
{
::vl::__vwsn::This(this->textList)->SetHorizontalAlwaysVisible(false);
}
{
::vl::__vwsn::This(this->textList)->SetVerticalAlwaysVisible(false);
}
(this->__vwsn_precompile_5 = ::vl::__vwsn::This(this->textList)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->textList)->SetAlt(::vl::WString::Unmanaged(L"N"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_4)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->textList)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_4));
}
{
::vl::__vwsn::This(::vl::__vwsn::This(this->__vwsn_precompile_0)->GetContainerComposition())->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_1));
}
{
::vl::__vwsn::This(this->self)->AddChild(this->__vwsn_precompile_0);
}
{
::vl::__vwsn::This(this->textBox)->SetReadonly(::vl::__vwsn::This(this->ViewModel.Obj())->GetFontMustExist());
}
{
::vl::__vwsn::This(this->textList)->SetItemSource(::vl::Ptr<::vl::reflection::description::IValueEnumerable>(::vl::__vwsn::UnboxCollection<::vl::reflection::description::IValueReadonlyList>(::vl::__vwsn::This(this->ViewModel.Obj())->GetFontList())));
}
{
::vl::__vwsn::This(this->textList)->SetTextProperty(vl::Func(::vl_workflow_global::__vwsno45_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_(this)));
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf46_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->textList)->SelectionChanged, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc26_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf47_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc27_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf48_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc28_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf49_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf50_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->self)->ValueChanged, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc29_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf51_GuiFakeDialogServiceUI_gaclib_controls_FontNameControlConstructor___vwsn_gaclib_controls_FontNameControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
}
FontNameControlConstructor::FontNameControlConstructor()
: self(static_cast<::gaclib_controls::FontNameControl*>(nullptr))
, ViewModel(::vl::Ptr<::vl::presentation::ICommonFontDialogViewModel>())
, textBox(static_cast<::vl::presentation::controls::GuiSinglelineTextBox*>(nullptr))
, textList(static_cast<::vl::presentation::controls::GuiBindableTextList*>(nullptr))
, __vwsn_precompile_0(static_cast<::vl::presentation::controls::GuiControl*>(nullptr))
, __vwsn_precompile_1(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_2(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_3(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_4(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_5(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_6(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
{
}
/***********************************************************************
Class (::gaclib_controls::FontNameControl)
***********************************************************************/
::vl::WString FontNameControl::GetValue()
{
return this->__vwsn_prop_Value;
}
void FontNameControl::SetValue(const ::vl::WString& __vwsn_value_)
{
if ((this->__vwsn_prop_Value != __vwsn_value_))
{
(this->__vwsn_prop_Value = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->ValueChanged)();
}
}
bool FontNameControl::GetLegal()
{
return this->__vwsn_prop_Legal;
}
void FontNameControl::SetLegal(bool __vwsn_value_)
{
if ((this->__vwsn_prop_Legal != __vwsn_value_))
{
(this->__vwsn_prop_Legal = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->LegalChanged)();
}
}
void FontNameControl::UpdateSelectedIndex()
{
auto index = ::vl::__vwsn::This(::vl::__vwsn::UnboxCollection<::vl::reflection::description::IValueReadonlyList>(::vl::__vwsn::This(this->GetViewModel().Obj())->GetFontList()).Obj())->IndexOf(::vl::__vwsn::Box(this->GetValue()));
if ((index > (- static_cast<::vl::vint>(1))))
{
::vl::__vwsn::This(this->textList)->SelectItemsByClick(index, false, false, true);
::vl::__vwsn::This(this->textList)->EnsureItemVisible(index);
}
}
void FontNameControl::InitValue(const ::vl::WString& value)
{
::vl::__vwsn::This(this->textBox)->SetText(value);
::vl::__vwsn::This(this->textBox)->Select([&](){ ::vl::presentation::TextPos __vwsn_temp__; __vwsn_temp__.row = static_cast<::vl::vint>(0); __vwsn_temp__.column = static_cast<::vl::vint>(0); return __vwsn_temp__; }(), [&](){ ::vl::presentation::TextPos __vwsn_temp__; __vwsn_temp__.row = static_cast<::vl::vint>(0); __vwsn_temp__.column = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
this->UpdateSelectedIndex();
}
::vl::Ptr<::gaclib_controls::IDialogStringsStrings> FontNameControl::GetStrings()
{
return this->__vwsn_prop_Strings;
}
void FontNameControl::SetStrings(::vl::Ptr<::gaclib_controls::IDialogStringsStrings> __vwsn_value_)
{
if ((this->__vwsn_prop_Strings.Obj() != __vwsn_value_.Obj()))
{
(this->__vwsn_prop_Strings = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->StringsChanged)();
}
}
::vl::Ptr<::vl::presentation::ICommonFontDialogViewModel> FontNameControl::GetViewModel()
{
return this->__vwsn_parameter_ViewModel;
}
FontNameControl::FontNameControl(::vl::Ptr<::vl::presentation::ICommonFontDialogViewModel> __vwsn_ctor_parameter_ViewModel)
: ::vl::presentation::controls::GuiCustomControl(::vl::presentation::theme::ThemeName::CustomControl)
, __vwsn_prop_Value(::vl::WString::Unmanaged(L""))
, __vwsn_prop_Legal(false)
, __vwsn_prop_Strings(::gaclib_controls::DialogStrings::Get(::vl::__vwsn::Parse<::vl::Locale>(::vl::WString::Unmanaged(L"en-US"))))
, __vwsn_parameter_ViewModel(::vl::Ptr<::vl::presentation::ICommonFontDialogViewModel>())
{
(this->__vwsn_parameter_ViewModel = __vwsn_ctor_parameter_ViewModel);
auto __vwsn_resource_ = ::vl::__vwsn::This(::vl::presentation::GetResourceManager())->GetResourceFromClassName(::vl::WString::Unmanaged(L"gaclib_controls::FontNameControl"));
auto __vwsn_resolver_ = ::vl::Ptr<::vl::presentation::GuiResourcePathResolver>(new ::vl::presentation::GuiResourcePathResolver(__vwsn_resource_, ::vl::__vwsn::This(__vwsn_resource_.Obj())->GetWorkingDirectory()));
::vl::__vwsn::This(this)->SetResourceResolver(__vwsn_resolver_);
::vl::__vwsn::This(this)->__vwsn_gaclib_controls_FontNameControl_Initialize(this);
}
FontNameControl::~FontNameControl()
{
this->FinalizeInstanceRecursively(static_cast<::vl::presentation::controls::GuiCustomControl*>(this));
}
/***********************************************************************
Class (::gaclib_controls::FontSizeControlConstructor)
***********************************************************************/
void FontSizeControlConstructor::__vwsn_gaclib_controls_FontSizeControl_Initialize(::gaclib_controls::FontSizeControl* __vwsn_this_)
{
(this->self = __vwsn_this_);
{
(this->__vwsn_precompile_0 = new ::vl::presentation::controls::GuiControl(::vl::presentation::theme::ThemeName::GroupBox));
}
(this->__vwsn_precompile_6 = ::vl::__vwsn::This(this->__vwsn_precompile_0)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_6)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_1 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetCellPadding(static_cast<::vl::vint>(5));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(5); __vwsn_temp__.top = static_cast<::vl::vint>(5); __vwsn_temp__.right = static_cast<::vl::vint>(5); __vwsn_temp__.bottom = static_cast<::vl::vint>(5); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetRowsAndColumns(static_cast<::vl::vint>(2), static_cast<::vl::vint>(1));
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetRowOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_2 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->textBox = new ::vl::presentation::controls::GuiSinglelineTextBox(::vl::presentation::theme::ThemeName::SinglelineTextBox));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"textBox"), ::vl::__vwsn::Box(this->textBox));
}
(this->__vwsn_precompile_3 = ::vl::__vwsn::This(this->textBox)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->textBox)->SetAlt(::vl::WString::Unmanaged(L"S"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->textBox)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_2));
}
(this->__vwsn_precompile_4 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_4)->SetSite(static_cast<::vl::vint>(1), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->textList = new ::vl::presentation::controls::GuiBindableTextList(::vl::presentation::theme::ThemeName::TextList));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"textList"), ::vl::__vwsn::Box(this->textList));
}
{
::vl::__vwsn::This(this->textList)->SetHorizontalAlwaysVisible(false);
}
{
::vl::__vwsn::This(this->textList)->SetVerticalAlwaysVisible(false);
}
(this->__vwsn_precompile_5 = ::vl::__vwsn::This(this->textList)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->textList)->SetAlt(::vl::WString::Unmanaged(L"L"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_4)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->textList)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_4));
}
{
::vl::__vwsn::This(::vl::__vwsn::This(this->__vwsn_precompile_0)->GetContainerComposition())->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_1));
}
{
::vl::__vwsn::This(this->self)->AddChild(this->__vwsn_precompile_0);
}
{
::vl::__vwsn::This(this->textList)->SetItemSource(::vl::Ptr<::vl::reflection::description::IValueEnumerable>(::vl::__vwsn::This(this->self)->GetSizeList()));
}
{
::vl::__vwsn::This(this->textList)->SetTextProperty(vl::Func(::vl_workflow_global::__vwsno52_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_(this)));
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf53_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->textList)->SelectionChanged, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc30_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf54_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc31_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf55_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc32_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf56_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf57_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->self)->ValueChanged, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc33_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf58_GuiFakeDialogServiceUI_gaclib_controls_FontSizeControlConstructor___vwsn_gaclib_controls_FontSizeControl_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
}
FontSizeControlConstructor::FontSizeControlConstructor()
: self(static_cast<::gaclib_controls::FontSizeControl*>(nullptr))
, textBox(static_cast<::vl::presentation::controls::GuiSinglelineTextBox*>(nullptr))
, textList(static_cast<::vl::presentation::controls::GuiBindableTextList*>(nullptr))
, __vwsn_precompile_0(static_cast<::vl::presentation::controls::GuiControl*>(nullptr))
, __vwsn_precompile_1(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_2(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_3(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_4(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_5(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_6(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
{
}
/***********************************************************************
Class (::gaclib_controls::FontSizeControl)
***********************************************************************/
::vl::Ptr<::vl::reflection::description::IValueList> FontSizeControl::GetSizeList()
{
return this->__vwsn_prop_SizeList;
}
void FontSizeControl::SetSizeList(::vl::Ptr<::vl::reflection::description::IValueList> __vwsn_value_)
{
(this->__vwsn_prop_SizeList = __vwsn_value_);
}
::vl::vint FontSizeControl::GetValue()
{
return this->__vwsn_prop_Value;
}
void FontSizeControl::SetValue(::vl::vint __vwsn_value_)
{
if ((this->__vwsn_prop_Value != __vwsn_value_))
{
(this->__vwsn_prop_Value = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->ValueChanged)();
}
}
bool FontSizeControl::GetLegal()
{
return this->__vwsn_prop_Legal;
}
void FontSizeControl::SetLegal(bool __vwsn_value_)
{
if ((this->__vwsn_prop_Legal != __vwsn_value_))
{
(this->__vwsn_prop_Legal = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->LegalChanged)();
}
}
void FontSizeControl::UpdateSelectedIndex()
{
auto index = ::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetSizeList().Obj())->IndexOf(::vl::__vwsn::Box(this->GetValue()));
if ((index > (- static_cast<::vl::vint>(1))))
{
::vl::__vwsn::This(this->textList)->SelectItemsByClick(index, false, false, true);
::vl::__vwsn::This(this->textList)->EnsureItemVisible(index);
}
}
void FontSizeControl::InitValue(::vl::vint value)
{
::vl::__vwsn::This(this->textBox)->SetText(::vl::__vwsn::ToString(value));
::vl::__vwsn::This(this->textBox)->Select([&](){ ::vl::presentation::TextPos __vwsn_temp__; __vwsn_temp__.row = static_cast<::vl::vint>(0); __vwsn_temp__.column = static_cast<::vl::vint>(0); return __vwsn_temp__; }(), [&](){ ::vl::presentation::TextPos __vwsn_temp__; __vwsn_temp__.row = static_cast<::vl::vint>(0); __vwsn_temp__.column = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
this->UpdateSelectedIndex();
}
::vl::Ptr<::gaclib_controls::IDialogStringsStrings> FontSizeControl::GetStrings()
{
return this->__vwsn_prop_Strings;
}
void FontSizeControl::SetStrings(::vl::Ptr<::gaclib_controls::IDialogStringsStrings> __vwsn_value_)
{
if ((this->__vwsn_prop_Strings.Obj() != __vwsn_value_.Obj()))
{
(this->__vwsn_prop_Strings = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->StringsChanged)();
}
}
FontSizeControl::FontSizeControl()
: ::vl::presentation::controls::GuiCustomControl(::vl::presentation::theme::ThemeName::CustomControl)
, __vwsn_prop_SizeList((::vl::__vwsn::CreateList().Add(static_cast<::vl::vint>(8)).Add(static_cast<::vl::vint>(9)).Add(static_cast<::vl::vint>(10)).Add(static_cast<::vl::vint>(11)).Add(static_cast<::vl::vint>(12)).Add(static_cast<::vl::vint>(14)).Add(static_cast<::vl::vint>(16)).Add(static_cast<::vl::vint>(18)).Add(static_cast<::vl::vint>(20)).Add(static_cast<::vl::vint>(22)).Add(static_cast<::vl::vint>(24)).Add(static_cast<::vl::vint>(26)).Add(static_cast<::vl::vint>(28)).Add(static_cast<::vl::vint>(36)).Add(static_cast<::vl::vint>(48)).Add(static_cast<::vl::vint>(72))).list)
, __vwsn_prop_Value(static_cast<::vl::vint>(0))
, __vwsn_prop_Legal(false)
, __vwsn_prop_Strings(::gaclib_controls::DialogStrings::Get(::vl::__vwsn::Parse<::vl::Locale>(::vl::WString::Unmanaged(L"en-US"))))
{
auto __vwsn_resource_ = ::vl::__vwsn::This(::vl::presentation::GetResourceManager())->GetResourceFromClassName(::vl::WString::Unmanaged(L"gaclib_controls::FontSizeControl"));
auto __vwsn_resolver_ = ::vl::Ptr<::vl::presentation::GuiResourcePathResolver>(new ::vl::presentation::GuiResourcePathResolver(__vwsn_resource_, ::vl::__vwsn::This(__vwsn_resource_.Obj())->GetWorkingDirectory()));
::vl::__vwsn::This(this)->SetResourceResolver(__vwsn_resolver_);
::vl::__vwsn::This(this)->__vwsn_gaclib_controls_FontSizeControl_Initialize(this);
}
FontSizeControl::~FontSizeControl()
{
this->FinalizeInstanceRecursively(static_cast<::vl::presentation::controls::GuiCustomControl*>(this));
}
/***********************************************************************
Class (::gaclib_controls::FullFontDialogWindowConstructor)
***********************************************************************/
void FullFontDialogWindowConstructor::__vwsn_gaclib_controls_FullFontDialogWindow_Initialize(::gaclib_controls::FullFontDialogWindow* __vwsn_this_)
{
(this->self = __vwsn_this_);
(this->ViewModel = ::vl::__vwsn::This(__vwsn_this_)->GetViewModel());
{
::vl::__vwsn::This(this->self)->SetIconVisible(false);
}
{
::vl::__vwsn::This(this->self)->SetMinimizedBox(false);
}
{
::vl::__vwsn::This(this->self)->SetMaximizedBox(false);
}
{
::vl::__vwsn::This(this->self)->SetShowInTaskBar(false);
}
{
::vl::__vwsn::This(this->self)->SetClientSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.x = static_cast<::vl::vint>(360); __vwsn_temp__.y = static_cast<::vl::vint>(480); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_0 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetCellPadding(static_cast<::vl::vint>(10));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowsAndColumns(static_cast<::vl::vint>(3), static_cast<::vl::vint>(3));
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
}
(this->__vwsn_precompile_1 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(3));
}
(this->__vwsn_precompile_2 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetCellPadding(static_cast<::vl::vint>(10));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(10); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetRowsAndColumns(static_cast<::vl::vint>(3), static_cast<::vl::vint>(2));
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetRowOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetRowOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(0.5); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetColumnOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(0.5); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_3 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(0), static_cast<::vl::vint>(3), static_cast<::vl::vint>(1));
}
(this->nameControl = new ::gaclib_controls::FontNameControl(::vl::Ptr<::vl::presentation::ICommonFontDialogViewModel>(this->ViewModel)));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"nameControl"), ::vl::__vwsn::Box(this->nameControl));
(this->__vwsn_precompile_4 = ::vl::__vwsn::This(this->nameControl)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_4)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->nameControl)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_3));
}
(this->__vwsn_precompile_5 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
(this->sizeControl = new ::gaclib_controls::FontSizeControl());
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"sizeControl"), ::vl::__vwsn::Box(this->sizeControl));
(this->__vwsn_precompile_6 = ::vl::__vwsn::This(this->sizeControl)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_6)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->sizeControl)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_5));
}
(this->__vwsn_precompile_7 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_7)->SetSite(static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_8 = new ::vl::presentation::controls::GuiControl(::vl::presentation::theme::ThemeName::GroupBox));
}
(this->__vwsn_precompile_16 = ::vl::__vwsn::This(this->__vwsn_precompile_8)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_16)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_9 = new ::vl::presentation::compositions::GuiStackComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->SetDirection(::vl::presentation::compositions::GuiStackComposition::Direction::Vertical);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
(this->__vwsn_precompile_10 = new ::vl::presentation::compositions::GuiStackItemComposition());
{
(this->checkBold = new ::vl::presentation::controls::GuiSelectableButton(::vl::presentation::theme::ThemeName::CheckBox));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"checkBold"), ::vl::__vwsn::Box(this->checkBold));
}
{
::vl::__vwsn::This(this->checkBold)->SetAlt(::vl::WString::Unmanaged(L"B"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_10)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->checkBold)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_10));
}
(this->__vwsn_precompile_11 = new ::vl::presentation::compositions::GuiStackItemComposition());
{
(this->checkItalic = new ::vl::presentation::controls::GuiSelectableButton(::vl::presentation::theme::ThemeName::CheckBox));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"checkItalic"), ::vl::__vwsn::Box(this->checkItalic));
}
{
::vl::__vwsn::This(this->checkItalic)->SetAlt(::vl::WString::Unmanaged(L"I"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_11)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->checkItalic)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_11));
}
(this->__vwsn_precompile_12 = new ::vl::presentation::compositions::GuiStackItemComposition());
{
(this->checkUnderline = new ::vl::presentation::controls::GuiSelectableButton(::vl::presentation::theme::ThemeName::CheckBox));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"checkUnderline"), ::vl::__vwsn::Box(this->checkUnderline));
}
{
::vl::__vwsn::This(this->checkUnderline)->SetAlt(::vl::WString::Unmanaged(L"U"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_12)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->checkUnderline)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_12));
}
(this->__vwsn_precompile_13 = new ::vl::presentation::compositions::GuiStackItemComposition());
{
(this->checkStrikeline = new ::vl::presentation::controls::GuiSelectableButton(::vl::presentation::theme::ThemeName::CheckBox));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"checkStrikeline"), ::vl::__vwsn::Box(this->checkStrikeline));
}
{
::vl::__vwsn::This(this->checkStrikeline)->SetAlt(::vl::WString::Unmanaged(L"U"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_13)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->checkStrikeline)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_13));
}
(this->__vwsn_precompile_14 = new ::vl::presentation::compositions::GuiStackItemComposition());
{
(this->checkHAA = new ::vl::presentation::controls::GuiSelectableButton(::vl::presentation::theme::ThemeName::CheckBox));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"checkHAA"), ::vl::__vwsn::Box(this->checkHAA));
}
{
::vl::__vwsn::This(this->checkHAA)->SetAlt(::vl::WString::Unmanaged(L"H"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_14)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->checkHAA)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_14));
}
(this->__vwsn_precompile_15 = new ::vl::presentation::compositions::GuiStackItemComposition());
{
(this->checkVAA = new ::vl::presentation::controls::GuiSelectableButton(::vl::presentation::theme::ThemeName::CheckBox));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"checkVAA"), ::vl::__vwsn::Box(this->checkVAA));
}
{
::vl::__vwsn::This(this->checkVAA)->SetAlt(::vl::WString::Unmanaged(L"V"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_15)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->checkVAA)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_15));
}
{
::vl::__vwsn::This(::vl::__vwsn::This(this->__vwsn_precompile_8)->GetContainerComposition())->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_9));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_7)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_8)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_7));
}
(this->__vwsn_precompile_17 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_17)->SetSite(static_cast<::vl::vint>(2), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_18 = new ::vl::presentation::controls::GuiControl(::vl::presentation::theme::ThemeName::GroupBox));
}
(this->__vwsn_precompile_21 = ::vl::__vwsn::This(this->__vwsn_precompile_18)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_21)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
(this->colorBounds = new ::vl::presentation::compositions::GuiBoundsComposition());
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"colorBounds"), ::vl::__vwsn::Box(this->colorBounds));
{
::vl::__vwsn::This(this->colorBounds)->SetPreferredMinSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.y = static_cast<::vl::vint>(20); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->colorBounds)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(1); __vwsn_temp__.top = static_cast<::vl::vint>(1); __vwsn_temp__.right = static_cast<::vl::vint>(1); __vwsn_temp__.bottom = static_cast<::vl::vint>(1); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_19 = ::vl::Ptr<::vl::presentation::elements::Gui3DBorderElement>(::vl::reflection::description::Element_Constructor<::vl::presentation::elements::Gui3DBorderElement>()));
{
::vl::__vwsn::This(this->__vwsn_precompile_19.Obj())->SetColor2(::vl::__vwsn::Parse<::vl::presentation::Color>(::vl::WString::Unmanaged(L"#AAAAAA")));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_19.Obj())->SetColor1(::vl::__vwsn::Parse<::vl::presentation::Color>(::vl::WString::Unmanaged(L"#444444")));
}
{
::vl::__vwsn::This(this->colorBounds)->SetOwnedElement(::vl::Ptr<::vl::presentation::elements::IGuiGraphicsElement>(this->__vwsn_precompile_19));
}
(this->__vwsn_precompile_20 = new ::vl::presentation::compositions::GuiBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_20)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(1); __vwsn_temp__.top = static_cast<::vl::vint>(1); __vwsn_temp__.right = static_cast<::vl::vint>(1); __vwsn_temp__.bottom = static_cast<::vl::vint>(1); return __vwsn_temp__; }());
}
(this->colorBackground = ::vl::Ptr<::vl::presentation::elements::GuiSolidBackgroundElement>(::vl::reflection::description::Element_Constructor<::vl::presentation::elements::GuiSolidBackgroundElement>()));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"colorBackground"), ::vl::__vwsn::Box(this->colorBackground));
{
::vl::__vwsn::This(this->__vwsn_precompile_20)->SetOwnedElement(::vl::Ptr<::vl::presentation::elements::IGuiGraphicsElement>(this->colorBackground));
}
{
::vl::__vwsn::This(this->colorBounds)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_20));
}
{
::vl::__vwsn::This(::vl::__vwsn::This(this->__vwsn_precompile_18)->GetContainerComposition())->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->colorBounds));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_17)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_18)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_17));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_2));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_1));
}
(this->__vwsn_precompile_22 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_22)->SetPreferredMinSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.y = static_cast<::vl::vint>(48); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_22)->SetSite(static_cast<::vl::vint>(1), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(3));
}
{
(this->__vwsn_precompile_23 = new ::vl::presentation::controls::GuiControl(::vl::presentation::theme::ThemeName::GroupBox));
}
(this->__vwsn_precompile_28 = ::vl::__vwsn::This(this->__vwsn_precompile_23)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_28)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_24 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_24)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_24)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_24)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_24)->SetRowsAndColumns(static_cast<::vl::vint>(3), static_cast<::vl::vint>(3));
::vl::__vwsn::This(this->__vwsn_precompile_24)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_24)->SetRowOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_24)->SetRowOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_24)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_24)->SetColumnOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_24)->SetColumnOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_25 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_25)->SetSite(static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_26 = new ::vl::presentation::controls::GuiLabel(::vl::presentation::theme::ThemeName::Label));
}
(this->__vwsn_precompile_27 = ::vl::__vwsn::This(this->__vwsn_precompile_26)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_27)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_26)->SetText(::vl::WString::Unmanaged(L"ABCxyz"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_25)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_26)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_24)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_25));
}
{
::vl::__vwsn::This(::vl::__vwsn::This(this->__vwsn_precompile_23)->GetContainerComposition())->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_24));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_22)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_23)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_22));
}
(this->__vwsn_precompile_29 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_29)->SetSite(static_cast<::vl::vint>(2), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_30 = new ::vl::presentation::controls::GuiButton(::vl::presentation::theme::ThemeName::Button));
}
(this->__vwsn_precompile_31 = ::vl::__vwsn::This(this->__vwsn_precompile_30)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_31)->SetPreferredMinSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.x = static_cast<::vl::vint>(80); __vwsn_temp__.y = static_cast<::vl::vint>(24); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_31)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_30)->SetAlt(::vl::WString::Unmanaged(L"O"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_29)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_30)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_29));
}
(this->__vwsn_precompile_32 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_32)->SetSite(static_cast<::vl::vint>(2), static_cast<::vl::vint>(2), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_33 = new ::vl::presentation::controls::GuiButton(::vl::presentation::theme::ThemeName::Button));
}
(this->__vwsn_precompile_34 = ::vl::__vwsn::This(this->__vwsn_precompile_33)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_34)->SetPreferredMinSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.x = static_cast<::vl::vint>(80); __vwsn_temp__.y = static_cast<::vl::vint>(24); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_34)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_33)->SetAlt(::vl::WString::Unmanaged(L"C"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_32)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_33)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_32));
}
{
::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetContainerComposition())->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_0));
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc34_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf59_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc35_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf60_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc36_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf61_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc37_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf62_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc38_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf63_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc39_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf64_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc40_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf65_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
::vl::__vwsn::This(this->colorBackground.Obj())->SetColor(::vl::__vwsn::This(this->ViewModel.Obj())->GetColor());
}
{
::vl::__vwsn::This(this->colorBounds)->SetAssociatedCursor(::vl::__vwsn::This(::vl::__vwsn::This(::vl::presentation::GetCurrentController())->ResourceService())->GetSystemCursor(::vl::presentation::INativeCursor::SystemCursorType::Hand));
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf66_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->colorBounds)->GetEventReceiver()->leftButtonUp, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc41_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf67_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc42_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf68_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc43_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf69_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc44_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf70_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc45_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf71_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf72_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->__vwsn_precompile_30)->Clicked, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc46_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf73_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf74_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->__vwsn_precompile_33)->Clicked, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc47_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf75_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc48_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf76_GuiFakeDialogServiceUI_gaclib_controls_FullFontDialogWindowConstructor___vwsn_gaclib_controls_FullFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
}
FullFontDialogWindowConstructor::FullFontDialogWindowConstructor()
: self(static_cast<::gaclib_controls::FullFontDialogWindow*>(nullptr))
, ViewModel(::vl::Ptr<::vl::presentation::IFullFontDialogViewModel>())
, nameControl(static_cast<::gaclib_controls::FontNameControl*>(nullptr))
, sizeControl(static_cast<::gaclib_controls::FontSizeControl*>(nullptr))
, checkBold(static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr))
, checkItalic(static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr))
, checkUnderline(static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr))
, checkStrikeline(static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr))
, checkHAA(static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr))
, checkVAA(static_cast<::vl::presentation::controls::GuiSelectableButton*>(nullptr))
, colorBounds(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, colorBackground(::vl::Ptr<::vl::presentation::elements::GuiSolidBackgroundElement>())
, __vwsn_precompile_0(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_1(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_2(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_3(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_4(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_5(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_6(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_7(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_8(static_cast<::vl::presentation::controls::GuiControl*>(nullptr))
, __vwsn_precompile_9(static_cast<::vl::presentation::compositions::GuiStackComposition*>(nullptr))
, __vwsn_precompile_10(static_cast<::vl::presentation::compositions::GuiStackItemComposition*>(nullptr))
, __vwsn_precompile_11(static_cast<::vl::presentation::compositions::GuiStackItemComposition*>(nullptr))
, __vwsn_precompile_12(static_cast<::vl::presentation::compositions::GuiStackItemComposition*>(nullptr))
, __vwsn_precompile_13(static_cast<::vl::presentation::compositions::GuiStackItemComposition*>(nullptr))
, __vwsn_precompile_14(static_cast<::vl::presentation::compositions::GuiStackItemComposition*>(nullptr))
, __vwsn_precompile_15(static_cast<::vl::presentation::compositions::GuiStackItemComposition*>(nullptr))
, __vwsn_precompile_16(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_17(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_18(static_cast<::vl::presentation::controls::GuiControl*>(nullptr))
, __vwsn_precompile_19(::vl::Ptr<::vl::presentation::elements::Gui3DBorderElement>())
, __vwsn_precompile_20(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_21(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_22(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_23(static_cast<::vl::presentation::controls::GuiControl*>(nullptr))
, __vwsn_precompile_24(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_25(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_26(static_cast<::vl::presentation::controls::GuiLabel*>(nullptr))
, __vwsn_precompile_27(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_28(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_29(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_30(static_cast<::vl::presentation::controls::GuiButton*>(nullptr))
, __vwsn_precompile_31(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_32(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_33(static_cast<::vl::presentation::controls::GuiButton*>(nullptr))
, __vwsn_precompile_34(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
{
}
/***********************************************************************
Class (::gaclib_controls::FullFontDialogWindow)
***********************************************************************/
::vl::Ptr<::gaclib_controls::IDialogStringsStrings> FullFontDialogWindow::GetStrings()
{
return this->__vwsn_prop_Strings;
}
void FullFontDialogWindow::SetStrings(::vl::Ptr<::gaclib_controls::IDialogStringsStrings> __vwsn_value_)
{
if ((this->__vwsn_prop_Strings.Obj() != __vwsn_value_.Obj()))
{
(this->__vwsn_prop_Strings = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->StringsChanged)();
}
}
::vl::Ptr<::vl::presentation::IFullFontDialogViewModel> FullFontDialogWindow::GetViewModel()
{
return this->__vwsn_parameter_ViewModel;
}
FullFontDialogWindow::FullFontDialogWindow(::vl::Ptr<::vl::presentation::IFullFontDialogViewModel> __vwsn_ctor_parameter_ViewModel)
: ::vl::presentation::controls::GuiWindow(::vl::presentation::theme::ThemeName::Window)
, __vwsn_prop_Strings(::gaclib_controls::DialogStrings::Get(::vl::__vwsn::Parse<::vl::Locale>(::vl::WString::Unmanaged(L"en-US"))))
, __vwsn_parameter_ViewModel(::vl::Ptr<::vl::presentation::IFullFontDialogViewModel>())
{
(this->__vwsn_parameter_ViewModel = __vwsn_ctor_parameter_ViewModel);
auto __vwsn_resource_ = ::vl::__vwsn::This(::vl::presentation::GetResourceManager())->GetResourceFromClassName(::vl::WString::Unmanaged(L"gaclib_controls::FullFontDialogWindow"));
auto __vwsn_resolver_ = ::vl::Ptr<::vl::presentation::GuiResourcePathResolver>(new ::vl::presentation::GuiResourcePathResolver(__vwsn_resource_, ::vl::__vwsn::This(__vwsn_resource_.Obj())->GetWorkingDirectory()));
::vl::__vwsn::This(this)->SetResourceResolver(__vwsn_resolver_);
::vl::__vwsn::This(this)->__vwsn_gaclib_controls_FullFontDialogWindow_Initialize(this);
this->__vwsn_instance_ctor_();
}
void FullFontDialogWindow::__vwsn_instance_ctor_()
{
::vl::__vwsn::This(this->nameControl)->InitValue(::vl::__vwsn::This(this->GetViewModel().Obj())->GetFont().fontFamily);
::vl::__vwsn::This(this->sizeControl)->InitValue(::vl::__vwsn::This(this->GetViewModel().Obj())->GetFont().size);
::vl::__vwsn::This(this->checkBold)->SetSelected(::vl::__vwsn::This(this->GetViewModel().Obj())->GetFont().bold);
::vl::__vwsn::This(this->checkItalic)->SetSelected(::vl::__vwsn::This(this->GetViewModel().Obj())->GetFont().italic);
::vl::__vwsn::This(this->checkUnderline)->SetSelected(::vl::__vwsn::This(this->GetViewModel().Obj())->GetFont().underline);
::vl::__vwsn::This(this->checkStrikeline)->SetSelected(::vl::__vwsn::This(this->GetViewModel().Obj())->GetFont().strikeline);
::vl::__vwsn::This(this->checkHAA)->SetSelected(::vl::__vwsn::This(this->GetViewModel().Obj())->GetFont().antialias);
::vl::__vwsn::This(this->checkVAA)->SetSelected(::vl::__vwsn::This(this->GetViewModel().Obj())->GetFont().verticalAntialias);
}
FullFontDialogWindow::~FullFontDialogWindow()
{
this->FinalizeInstanceRecursively(static_cast<::vl::presentation::controls::GuiControlHost*>(this));
}
/***********************************************************************
Class (::gaclib_controls::IDialogStringsStrings)
***********************************************************************/
/***********************************************************************
Class (::gaclib_controls::MessageBoxButtonTemplateConstructor)
***********************************************************************/
void MessageBoxButtonTemplateConstructor::__vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize(::gaclib_controls::MessageBoxButtonTemplate* __vwsn_this_)
{
(this->self = __vwsn_this_);
(this->Action = ::vl::__vwsn::This(__vwsn_this_)->GetAction());
{
::vl::__vwsn::This(this->self)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
(this->buttonControl = new ::vl::presentation::controls::GuiButton(::vl::presentation::theme::ThemeName::Button));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"buttonControl"), ::vl::__vwsn::Box(this->buttonControl));
}
(this->__vwsn_precompile_0 = ::vl::__vwsn::This(this->buttonControl)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetPreferredMinSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.x = static_cast<::vl::vint>(80); __vwsn_temp__.y = static_cast<::vl::vint>(24); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->self)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->buttonControl)->GetBoundsComposition()));
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc56_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf86_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
::vl::__vwsn::This(this->buttonControl)->SetAlt(::vl::__vwsn::This(this->self)->GetButtonAlt(::vl::__vwsn::This(this->Action.Obj())->GetButton()));
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf87_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->buttonControl)->Clicked, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc57_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf88_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxButtonTemplateConstructor___vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
}
MessageBoxButtonTemplateConstructor::MessageBoxButtonTemplateConstructor()
: Action(::vl::Ptr<::vl::presentation::IMessageBoxDialogAction>())
, self(static_cast<::gaclib_controls::MessageBoxButtonTemplate*>(nullptr))
, buttonControl(static_cast<::vl::presentation::controls::GuiButton*>(nullptr))
, __vwsn_precompile_0(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
{
}
/***********************************************************************
Class (::gaclib_controls::MessageBoxButtonTemplate)
***********************************************************************/
::vl::presentation::controls::GuiButton* MessageBoxButtonTemplate::GetButtonControl()
{
return this->__vwsn_prop_ButtonControl;
}
void MessageBoxButtonTemplate::SetButtonControl(::vl::presentation::controls::GuiButton* __vwsn_value_)
{
if ((this->__vwsn_prop_ButtonControl != __vwsn_value_))
{
(this->__vwsn_prop_ButtonControl = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->ButtonControlChanged)();
}
}
::vl::WString MessageBoxButtonTemplate::GetButtonText(::vl::presentation::INativeDialogService::MessageBoxButtonsOutput button, ::vl::Ptr<::gaclib_controls::IDialogStringsStrings> strings)
{
{
auto __vwsn_switch_0 = button;
if ((__vwsn_switch_0 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectOK))
{
return ::vl::__vwsn::This(strings.Obj())->OK();
}
else if ((__vwsn_switch_0 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectCancel))
{
return ::vl::__vwsn::This(strings.Obj())->Cancel();
}
else if ((__vwsn_switch_0 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectYes))
{
return ::vl::__vwsn::This(strings.Obj())->Yes();
}
else if ((__vwsn_switch_0 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectNo))
{
return ::vl::__vwsn::This(strings.Obj())->No();
}
else if ((__vwsn_switch_0 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectRetry))
{
return ::vl::__vwsn::This(strings.Obj())->Retry();
}
else if ((__vwsn_switch_0 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectAbort))
{
return ::vl::__vwsn::This(strings.Obj())->Abort();
}
else if ((__vwsn_switch_0 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectIgnore))
{
return ::vl::__vwsn::This(strings.Obj())->Ignore();
}
else if ((__vwsn_switch_0 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectTryAgain))
{
return ::vl::__vwsn::This(strings.Obj())->TryAgain();
}
else if ((__vwsn_switch_0 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectContinue))
{
return ::vl::__vwsn::This(strings.Obj())->Continue();
}
else
{
return ::vl::WString::Unmanaged(L"");
}
}
}
::vl::WString MessageBoxButtonTemplate::GetButtonAlt(::vl::presentation::INativeDialogService::MessageBoxButtonsOutput button)
{
{
auto __vwsn_switch_1 = button;
if ((__vwsn_switch_1 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectOK))
{
return ::vl::WString::Unmanaged(L"O");
}
else if ((__vwsn_switch_1 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectCancel))
{
return ::vl::WString::Unmanaged(L"C");
}
else if ((__vwsn_switch_1 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectYes))
{
return ::vl::WString::Unmanaged(L"Y");
}
else if ((__vwsn_switch_1 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectNo))
{
return ::vl::WString::Unmanaged(L"N");
}
else if ((__vwsn_switch_1 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectRetry))
{
return ::vl::WString::Unmanaged(L"R");
}
else if ((__vwsn_switch_1 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectAbort))
{
return ::vl::WString::Unmanaged(L"A");
}
else if ((__vwsn_switch_1 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectIgnore))
{
return ::vl::WString::Unmanaged(L"I");
}
else if ((__vwsn_switch_1 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectTryAgain))
{
return ::vl::WString::Unmanaged(L"T");
}
else if ((__vwsn_switch_1 == ::vl::presentation::INativeDialogService::MessageBoxButtonsOutput::SelectContinue))
{
return ::vl::WString::Unmanaged(L"K");
}
else
{
return ::vl::WString::Unmanaged(L"");
}
}
}
::vl::Ptr<::gaclib_controls::IDialogStringsStrings> MessageBoxButtonTemplate::GetStrings()
{
return this->__vwsn_prop_Strings;
}
void MessageBoxButtonTemplate::SetStrings(::vl::Ptr<::gaclib_controls::IDialogStringsStrings> __vwsn_value_)
{
if ((this->__vwsn_prop_Strings.Obj() != __vwsn_value_.Obj()))
{
(this->__vwsn_prop_Strings = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->StringsChanged)();
}
}
::vl::Ptr<::vl::presentation::IMessageBoxDialogAction> MessageBoxButtonTemplate::GetAction()
{
return this->__vwsn_parameter_Action;
}
MessageBoxButtonTemplate::MessageBoxButtonTemplate(::vl::Ptr<::vl::presentation::IMessageBoxDialogAction> __vwsn_ctor_parameter_Action)
: __vwsn_prop_ButtonControl(static_cast<::vl::presentation::controls::GuiButton*>(nullptr))
, __vwsn_prop_Strings(::gaclib_controls::DialogStrings::Get(::vl::__vwsn::Parse<::vl::Locale>(::vl::WString::Unmanaged(L"en-US"))))
, __vwsn_parameter_Action(::vl::Ptr<::vl::presentation::IMessageBoxDialogAction>())
{
(this->__vwsn_parameter_Action = __vwsn_ctor_parameter_Action);
auto __vwsn_resource_ = ::vl::__vwsn::This(::vl::presentation::GetResourceManager())->GetResourceFromClassName(::vl::WString::Unmanaged(L"gaclib_controls::MessageBoxButtonTemplate"));
auto __vwsn_resolver_ = ::vl::Ptr<::vl::presentation::GuiResourcePathResolver>(new ::vl::presentation::GuiResourcePathResolver(__vwsn_resource_, ::vl::__vwsn::This(__vwsn_resource_.Obj())->GetWorkingDirectory()));
::vl::__vwsn::This(this)->SetResourceResolver(__vwsn_resolver_);
::vl::__vwsn::This(this)->__vwsn_gaclib_controls_MessageBoxButtonTemplate_Initialize(this);
this->__vwsn_instance_ctor_();
}
void MessageBoxButtonTemplate::__vwsn_instance_ctor_()
{
::vl::__vwsn::This(this->self)->SetButtonControl(::vl::__vwsn::This(this->self)->buttonControl);
}
MessageBoxButtonTemplate::~MessageBoxButtonTemplate()
{
this->FinalizeInstanceRecursively(static_cast<::vl::presentation::templates::GuiTemplate*>(this));
}
/***********************************************************************
Class (::gaclib_controls::MessageBoxWindowConstructor)
***********************************************************************/
void MessageBoxWindowConstructor::__vwsn_gaclib_controls_MessageBoxWindow_Initialize(::gaclib_controls::MessageBoxWindow* __vwsn_this_)
{
(this->self = __vwsn_this_);
(this->ViewModel = ::vl::__vwsn::This(__vwsn_this_)->GetViewModel());
{
::vl::__vwsn::This(this->self)->SetIconVisible(false);
}
{
::vl::__vwsn::This(this->self)->SetSizeBox(false);
}
{
::vl::__vwsn::This(this->self)->SetMinimizedBox(false);
}
{
::vl::__vwsn::This(this->self)->SetMaximizedBox(false);
}
{
::vl::__vwsn::This(this->self)->SetShowInTaskBar(false);
}
{
::vl::__vwsn::This(this->self)->SetClientSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.x = static_cast<::vl::vint>(240); __vwsn_temp__.y = static_cast<::vl::vint>(120); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_0 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetCellPadding(static_cast<::vl::vint>(10));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(10); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowsAndColumns(static_cast<::vl::vint>(3), static_cast<::vl::vint>(2));
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_1 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
(this->__vwsn_precompile_2 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetRowsAndColumns(static_cast<::vl::vint>(3), static_cast<::vl::vint>(1));
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetRowOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetRowOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
}
(this->__vwsn_precompile_3 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->SetSite(static_cast<::vl::vint>(1), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
(this->__vwsn_precompile_4 = ::vl::Ptr<::vl::presentation::elements::GuiSolidBackgroundElement>(::vl::reflection::description::Element_Constructor<::vl::presentation::elements::GuiSolidBackgroundElement>()));
{
::vl::__vwsn::This(this->__vwsn_precompile_4.Obj())->SetColor(::vl::__vwsn::Parse<::vl::presentation::Color>(::vl::WString::Unmanaged(L"#FFFFFF")));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->SetOwnedElement(::vl::Ptr<::vl::presentation::elements::IGuiGraphicsElement>(this->__vwsn_precompile_4));
}
(this->__vwsn_precompile_5 = new ::vl::presentation::compositions::GuiBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetPreferredMinSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.x = static_cast<::vl::vint>(48); __vwsn_temp__.y = static_cast<::vl::vint>(48); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
(this->__vwsn_precompile_6 = ::vl::Ptr<::vl::presentation::elements::GuiImageFrameElement>(::vl::reflection::description::Element_Constructor<::vl::presentation::elements::GuiImageFrameElement>()));
{
::vl::__vwsn::This(this->__vwsn_precompile_6.Obj())->SetStretch(true);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetOwnedElement(::vl::Ptr<::vl::presentation::elements::IGuiGraphicsElement>(this->__vwsn_precompile_6));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_5));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_3));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_2));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_1));
}
(this->__vwsn_precompile_7 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_7)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
(this->__vwsn_precompile_8 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_8)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_8)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_8)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_8)->SetRowsAndColumns(static_cast<::vl::vint>(3), static_cast<::vl::vint>(1));
::vl::__vwsn::This(this->__vwsn_precompile_8)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_8)->SetRowOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_8)->SetRowOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_8)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
}
(this->__vwsn_precompile_9 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->SetSite(static_cast<::vl::vint>(1), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_10 = new ::vl::presentation::controls::GuiLabel(::vl::presentation::theme::ThemeName::Label));
}
(this->__vwsn_precompile_11 = ::vl::__vwsn::This(this->__vwsn_precompile_10)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_11)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_10)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_8)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_9));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_7)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_8));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_7));
}
(this->__vwsn_precompile_12 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_12)->SetSite(static_cast<::vl::vint>(2), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(2));
}
(this->__vwsn_precompile_13 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_13)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_13)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_13)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_13)->SetRowsAndColumns(static_cast<::vl::vint>(1), static_cast<::vl::vint>(3));
::vl::__vwsn::This(this->__vwsn_precompile_13)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_13)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_13)->SetColumnOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_13)->SetColumnOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_14 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_14)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
(this->buttonStack = new ::vl::presentation::compositions::GuiRepeatStackComposition());
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"buttonStack"), ::vl::__vwsn::Box(this->buttonStack));
{
::vl::__vwsn::This(this->buttonStack)->SetItemTemplate(vl::Func(::vl_workflow_global::__vwsnf89_GuiFakeDialogServiceUI_gaclib_controls_MessageBoxWindowConstructor___vwsn_gaclib_controls_MessageBoxWindow_Initialize_(this)));
}
{
::vl::__vwsn::This(this->buttonStack)->SetPadding(static_cast<::vl::vint>(5));
}
{
::vl::__vwsn::This(this->buttonStack)->SetDirection(::vl::presentation::compositions::GuiStackComposition::Direction::Horizontal);
}
{
::vl::__vwsn::This(this->buttonStack)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->buttonStack)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_14)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->buttonStack));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_13)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_14));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_12)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_13));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_12));
}
{
::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetContainerComposition())->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_0));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_6.Obj())->SetImage(::vl::__vwsn::This(this->self)->GetIcon(::vl::__vwsn::This(this->ViewModel.Obj())->GetIcon()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_10)->SetText(::vl::__vwsn::This(this->ViewModel.Obj())->GetText());
}
{
::vl::__vwsn::This(this->buttonStack)->SetItemSource(::vl::Ptr<::vl::reflection::description::IValueEnumerable>(::vl::__vwsn::UnboxCollection<::vl::reflection::description::IValueReadonlyList>(::vl::__vwsn::This(this->ViewModel.Obj())->GetButtons())));
}
{
::vl::__vwsn::This(this->self)->SetText(::vl::__vwsn::This(this->ViewModel.Obj())->GetTitle());
}
}
MessageBoxWindowConstructor::MessageBoxWindowConstructor()
: self(static_cast<::gaclib_controls::MessageBoxWindow*>(nullptr))
, ViewModel(::vl::Ptr<::vl::presentation::IMessageBoxDialogViewModel>())
, buttonStack(static_cast<::vl::presentation::compositions::GuiRepeatStackComposition*>(nullptr))
, __vwsn_precompile_0(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_1(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_2(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_3(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_4(::vl::Ptr<::vl::presentation::elements::GuiSolidBackgroundElement>())
, __vwsn_precompile_5(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_6(::vl::Ptr<::vl::presentation::elements::GuiImageFrameElement>())
, __vwsn_precompile_7(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_8(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_9(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_10(static_cast<::vl::presentation::controls::GuiLabel*>(nullptr))
, __vwsn_precompile_11(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_12(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_13(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_14(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
{
}
/***********************************************************************
Class (::gaclib_controls::MessageBoxWindow)
***********************************************************************/
::vl::Ptr<::vl::presentation::INativeImage> MessageBoxWindow::GetIcon(::vl::presentation::INativeDialogService::MessageBoxIcons icon)
{
auto iconUri = ::vl::WString::Unmanaged(L"Images/None");
{
auto __vwsn_switch_2 = ::vl::__vwsn::This(this->GetViewModel().Obj())->GetIcon();
if ((__vwsn_switch_2 == ::vl::presentation::INativeDialogService::MessageBoxIcons::IconError))
{
(iconUri = ::vl::WString::Unmanaged(L"Images/Error"));
}
else if ((__vwsn_switch_2 == ::vl::presentation::INativeDialogService::MessageBoxIcons::IconQuestion))
{
(iconUri = ::vl::WString::Unmanaged(L"Images/Question"));
}
else if ((__vwsn_switch_2 == ::vl::presentation::INativeDialogService::MessageBoxIcons::IconWarning))
{
(iconUri = ::vl::WString::Unmanaged(L"Images/Warning"));
}
else if ((__vwsn_switch_2 == ::vl::presentation::INativeDialogService::MessageBoxIcons::IconInformation))
{
(iconUri = ::vl::WString::Unmanaged(L"Images/Information"));
}
}
return ::vl::__vwsn::This(::vl::__vwsn::Ensure(::vl::__vwsn::SharedPtrCast<::vl::presentation::GuiImageData>(::vl::__vwsn::This(this->self)->ResolveResource(::vl::WString::Unmanaged(L"res"), iconUri, true).Obj())).Obj())->GetImage();
}
::vl::Ptr<::vl::presentation::IMessageBoxDialogViewModel> MessageBoxWindow::GetViewModel()
{
return this->__vwsn_parameter_ViewModel;
}
MessageBoxWindow::MessageBoxWindow(::vl::Ptr<::vl::presentation::IMessageBoxDialogViewModel> __vwsn_ctor_parameter_ViewModel)
: ::vl::presentation::controls::GuiWindow(::vl::presentation::theme::ThemeName::Window)
, __vwsn_parameter_ViewModel(::vl::Ptr<::vl::presentation::IMessageBoxDialogViewModel>())
{
(this->__vwsn_parameter_ViewModel = __vwsn_ctor_parameter_ViewModel);
auto __vwsn_resource_ = ::vl::__vwsn::This(::vl::presentation::GetResourceManager())->GetResourceFromClassName(::vl::WString::Unmanaged(L"gaclib_controls::MessageBoxWindow"));
auto __vwsn_resolver_ = ::vl::Ptr<::vl::presentation::GuiResourcePathResolver>(new ::vl::presentation::GuiResourcePathResolver(__vwsn_resource_, ::vl::__vwsn::This(__vwsn_resource_.Obj())->GetWorkingDirectory()));
::vl::__vwsn::This(this)->SetResourceResolver(__vwsn_resolver_);
::vl::__vwsn::This(this)->__vwsn_gaclib_controls_MessageBoxWindow_Initialize(this);
this->__vwsn_instance_ctor_();
}
void MessageBoxWindow::__vwsn_instance_ctor_()
{
auto defaultButton = ::vl::__vwsn::This(::vl::__vwsn::UnboxCollection<::vl::reflection::description::IValueReadonlyList>(::vl::__vwsn::This(this->GetViewModel().Obj())->GetButtons()).Obj())->IndexOf(::vl::__vwsn::Box(::vl::__vwsn::This(this->GetViewModel().Obj())->GetDefaultButton()));
auto buttonControl = ::vl::__vwsn::This(::vl::__vwsn::Ensure(::vl::__vwsn::RawPtrCast<::gaclib_controls::MessageBoxButtonTemplate>(::vl::__vwsn::This(::vl::__vwsn::This(this->buttonStack)->GetStackItems()[defaultButton])->Children()[static_cast<::vl::vint>(0)])))->GetButtonControl();
::vl::__vwsn::This(buttonControl)->SetFocused();
}
MessageBoxWindow::~MessageBoxWindow()
{
this->FinalizeInstanceRecursively(static_cast<::vl::presentation::controls::GuiControlHost*>(this));
}
/***********************************************************************
Class (::gaclib_controls::SimpleFontDialogWindowConstructor)
***********************************************************************/
void SimpleFontDialogWindowConstructor::__vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize(::gaclib_controls::SimpleFontDialogWindow* __vwsn_this_)
{
(this->self = __vwsn_this_);
(this->ViewModel = ::vl::__vwsn::This(__vwsn_this_)->GetViewModel());
{
::vl::__vwsn::This(this->self)->SetIconVisible(false);
}
{
::vl::__vwsn::This(this->self)->SetMinimizedBox(false);
}
{
::vl::__vwsn::This(this->self)->SetMaximizedBox(false);
}
{
::vl::__vwsn::This(this->self)->SetShowInTaskBar(false);
}
{
::vl::__vwsn::This(this->self)->SetClientSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.x = static_cast<::vl::vint>(360); __vwsn_temp__.y = static_cast<::vl::vint>(360); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_0 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetCellPadding(static_cast<::vl::vint>(10));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowsAndColumns(static_cast<::vl::vint>(3), static_cast<::vl::vint>(3));
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetRowOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_0)->SetColumnOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
}
(this->__vwsn_precompile_1 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(3));
}
(this->__vwsn_precompile_2 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetCellPadding(static_cast<::vl::vint>(10));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(10); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetRowsAndColumns(static_cast<::vl::vint>(1), static_cast<::vl::vint>(2));
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(0.5); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_2)->SetColumnOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(0.5); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_3 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
(this->nameControl = new ::gaclib_controls::FontNameControl(::vl::Ptr<::vl::presentation::ICommonFontDialogViewModel>(this->ViewModel)));
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"nameControl"), ::vl::__vwsn::Box(this->nameControl));
(this->__vwsn_precompile_4 = ::vl::__vwsn::This(this->nameControl)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_4)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_3)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->nameControl)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_3));
}
(this->__vwsn_precompile_5 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->SetSite(static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
(this->sizeControl = new ::gaclib_controls::FontSizeControl());
::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"sizeControl"), ::vl::__vwsn::Box(this->sizeControl));
(this->__vwsn_precompile_6 = ::vl::__vwsn::This(this->sizeControl)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_6)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_5)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->sizeControl)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_2)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_5));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_1)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_2));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_1));
}
(this->__vwsn_precompile_7 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_7)->SetPreferredMinSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.y = static_cast<::vl::vint>(48); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_7)->SetSite(static_cast<::vl::vint>(1), static_cast<::vl::vint>(0), static_cast<::vl::vint>(1), static_cast<::vl::vint>(3));
}
{
(this->__vwsn_precompile_8 = new ::vl::presentation::controls::GuiControl(::vl::presentation::theme::ThemeName::GroupBox));
}
(this->__vwsn_precompile_13 = ::vl::__vwsn::This(this->__vwsn_precompile_8)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_13)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_9 = new ::vl::presentation::compositions::GuiTableComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->SetBorderVisible(false);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->SetMinSizeLimitation(::vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation::LimitToElementAndChildren);
}
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->SetRowsAndColumns(static_cast<::vl::vint>(3), static_cast<::vl::vint>(3));
::vl::__vwsn::This(this->__vwsn_precompile_9)->SetRowOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_9)->SetRowOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_9)->SetRowOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_9)->SetColumnOption(static_cast<::vl::vint>(0), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_9)->SetColumnOption(static_cast<::vl::vint>(1), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::MinSize; return __vwsn_temp__; }());
::vl::__vwsn::This(this->__vwsn_precompile_9)->SetColumnOption(static_cast<::vl::vint>(2), [&](){ ::vl::presentation::compositions::GuiCellOption __vwsn_temp__; __vwsn_temp__.composeType = ::vl::presentation::compositions::GuiCellOption::ComposeType::Percentage; __vwsn_temp__.percentage = static_cast<double>(1.0); return __vwsn_temp__; }());
}
(this->__vwsn_precompile_10 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_10)->SetSite(static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_11 = new ::vl::presentation::controls::GuiLabel(::vl::presentation::theme::ThemeName::Label));
}
(this->__vwsn_precompile_12 = ::vl::__vwsn::This(this->__vwsn_precompile_11)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_12)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_11)->SetText(::vl::WString::Unmanaged(L"ABCxyz"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_10)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_11)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_9)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_10));
}
{
::vl::__vwsn::This(::vl::__vwsn::This(this->__vwsn_precompile_8)->GetContainerComposition())->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_9));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_7)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_8)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_7));
}
(this->__vwsn_precompile_14 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_14)->SetSite(static_cast<::vl::vint>(2), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_15 = new ::vl::presentation::controls::GuiButton(::vl::presentation::theme::ThemeName::Button));
}
(this->__vwsn_precompile_16 = ::vl::__vwsn::This(this->__vwsn_precompile_15)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_16)->SetPreferredMinSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.x = static_cast<::vl::vint>(80); __vwsn_temp__.y = static_cast<::vl::vint>(24); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_16)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_15)->SetAlt(::vl::WString::Unmanaged(L"O"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_14)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_15)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_14));
}
(this->__vwsn_precompile_17 = new ::vl::presentation::compositions::GuiCellComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_17)->SetSite(static_cast<::vl::vint>(2), static_cast<::vl::vint>(2), static_cast<::vl::vint>(1), static_cast<::vl::vint>(1));
}
{
(this->__vwsn_precompile_18 = new ::vl::presentation::controls::GuiButton(::vl::presentation::theme::ThemeName::Button));
}
(this->__vwsn_precompile_19 = ::vl::__vwsn::This(this->__vwsn_precompile_18)->GetBoundsComposition());
{
::vl::__vwsn::This(this->__vwsn_precompile_19)->SetPreferredMinSize([&](){ ::vl::presentation::Size __vwsn_temp__; __vwsn_temp__.x = static_cast<::vl::vint>(80); __vwsn_temp__.y = static_cast<::vl::vint>(24); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_19)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(0); __vwsn_temp__.top = static_cast<::vl::vint>(0); __vwsn_temp__.right = static_cast<::vl::vint>(0); __vwsn_temp__.bottom = static_cast<::vl::vint>(0); return __vwsn_temp__; }());
}
{
::vl::__vwsn::This(this->__vwsn_precompile_18)->SetAlt(::vl::WString::Unmanaged(L"C"));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_17)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(::vl::__vwsn::This(this->__vwsn_precompile_18)->GetBoundsComposition()));
}
{
::vl::__vwsn::This(this->__vwsn_precompile_0)->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_17));
}
{
::vl::__vwsn::This(::vl::__vwsn::This(this->self)->GetContainerComposition())->AddChild(static_cast<::vl::presentation::compositions::GuiGraphicsComposition*>(this->__vwsn_precompile_0));
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc49_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf77_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc50_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf78_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc51_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf79_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc52_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf80_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf81_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->__vwsn_precompile_15)->Clicked, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc53_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf82_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_event_handler_ = vl::Func(::vl_workflow_global::__vwsnf83_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(this->__vwsn_precompile_18)->Clicked, __vwsn_event_handler_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc54_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(__vwsn_this_, this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf84_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
{
auto __vwsn_created_subscription_ = ::vl::Ptr<::vl::reflection::description::IValueSubscription>(new ::vl_workflow_global::__vwsnc55_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize__vl_reflection_description_IValueSubscription(this));
::vl::__vwsn::EventAttach(::vl::__vwsn::This(__vwsn_created_subscription_.Obj())->ValueChanged, vl::Func(::vl_workflow_global::__vwsnf85_GuiFakeDialogServiceUI_gaclib_controls_SimpleFontDialogWindowConstructor___vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize_(this)));
::vl::__vwsn::This(__vwsn_this_)->AddSubscription(__vwsn_created_subscription_);
}
}
SimpleFontDialogWindowConstructor::SimpleFontDialogWindowConstructor()
: self(static_cast<::gaclib_controls::SimpleFontDialogWindow*>(nullptr))
, ViewModel(::vl::Ptr<::vl::presentation::ISimpleFontDialogViewModel>())
, nameControl(static_cast<::gaclib_controls::FontNameControl*>(nullptr))
, sizeControl(static_cast<::gaclib_controls::FontSizeControl*>(nullptr))
, __vwsn_precompile_0(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_1(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_2(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_3(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_4(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_5(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_6(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_7(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_8(static_cast<::vl::presentation::controls::GuiControl*>(nullptr))
, __vwsn_precompile_9(static_cast<::vl::presentation::compositions::GuiTableComposition*>(nullptr))
, __vwsn_precompile_10(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_11(static_cast<::vl::presentation::controls::GuiLabel*>(nullptr))
, __vwsn_precompile_12(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_13(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_14(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_15(static_cast<::vl::presentation::controls::GuiButton*>(nullptr))
, __vwsn_precompile_16(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
, __vwsn_precompile_17(static_cast<::vl::presentation::compositions::GuiCellComposition*>(nullptr))
, __vwsn_precompile_18(static_cast<::vl::presentation::controls::GuiButton*>(nullptr))
, __vwsn_precompile_19(static_cast<::vl::presentation::compositions::GuiBoundsComposition*>(nullptr))
{
}
/***********************************************************************
Class (::gaclib_controls::SimpleFontDialogWindow)
***********************************************************************/
::vl::Ptr<::gaclib_controls::IDialogStringsStrings> SimpleFontDialogWindow::GetStrings()
{
return this->__vwsn_prop_Strings;
}
void SimpleFontDialogWindow::SetStrings(::vl::Ptr<::gaclib_controls::IDialogStringsStrings> __vwsn_value_)
{
if ((this->__vwsn_prop_Strings.Obj() != __vwsn_value_.Obj()))
{
(this->__vwsn_prop_Strings = __vwsn_value_);
::vl::__vwsn::EventInvoke(this->StringsChanged)();
}
}
::vl::Ptr<::vl::presentation::ISimpleFontDialogViewModel> SimpleFontDialogWindow::GetViewModel()
{
return this->__vwsn_parameter_ViewModel;
}
SimpleFontDialogWindow::SimpleFontDialogWindow(::vl::Ptr<::vl::presentation::ISimpleFontDialogViewModel> __vwsn_ctor_parameter_ViewModel)
: ::vl::presentation::controls::GuiWindow(::vl::presentation::theme::ThemeName::Window)
, __vwsn_prop_Strings(::gaclib_controls::DialogStrings::Get(::vl::__vwsn::Parse<::vl::Locale>(::vl::WString::Unmanaged(L"en-US"))))
, __vwsn_parameter_ViewModel(::vl::Ptr<::vl::presentation::ISimpleFontDialogViewModel>())
{
(this->__vwsn_parameter_ViewModel = __vwsn_ctor_parameter_ViewModel);
auto __vwsn_resource_ = ::vl::__vwsn::This(::vl::presentation::GetResourceManager())->GetResourceFromClassName(::vl::WString::Unmanaged(L"gaclib_controls::SimpleFontDialogWindow"));
auto __vwsn_resolver_ = ::vl::Ptr<::vl::presentation::GuiResourcePathResolver>(new ::vl::presentation::GuiResourcePathResolver(__vwsn_resource_, ::vl::__vwsn::This(__vwsn_resource_.Obj())->GetWorkingDirectory()));
::vl::__vwsn::This(this)->SetResourceResolver(__vwsn_resolver_);
::vl::__vwsn::This(this)->__vwsn_gaclib_controls_SimpleFontDialogWindow_Initialize(this);
this->__vwsn_instance_ctor_();
}
void SimpleFontDialogWindow::__vwsn_instance_ctor_()
{
::vl::__vwsn::This(this->nameControl)->InitValue(::vl::__vwsn::This(this->GetViewModel().Obj())->GetFontFamily());
::vl::__vwsn::This(this->sizeControl)->InitValue(::vl::__vwsn::This(this->GetViewModel().Obj())->GetFontSize());
}
SimpleFontDialogWindow::~SimpleFontDialogWindow()
{
this->FinalizeInstanceRecursively(static_cast<::vl::presentation::controls::GuiControlHost*>(this));
}
}
#undef GLOBAL_SYMBOL
#undef GLOBAL_NAME
#undef GLOBAL_OBJ
#if defined( _MSC_VER)
#pragma warning(pop)
#elif defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
/***********************************************************************
.\UTILITIES\FAKESERVICES\DIALOGS\SOURCE\GUIFAKEDIALOGSERVICEUIRESOURCE.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
namespace user_resource
{
using namespace collections;
using namespace stream;
using namespace controls;
class GuiFakeDialogServiceUIResourceReader
{
public:
static const vint parserBufferLength = 31816; // 31816 bytes before compressing
static const vint parserBufferBlock = 1024;
static const vint parserBufferRemain = 72;
static const vint parserBufferRows = 32;
static const char* parserBuffer[32];
static void ReadToStream(vl::stream::MemoryStream& stream)
{
DecompressStream(parserBuffer, false, parserBufferRows, parserBufferBlock, parserBufferRemain, stream);
}
};
const char* GuiFakeDialogServiceUIResourceReader::parserBuffer[] = {
"\x60\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x3C\x52\x65\x73\x6F\x75\x72\x63\x65\x4D\x65\x74\x61\x64\x61\x74\x61\x20\x4E\x61\x6D\x65\x3D\x22\x47\x75\x69\x46\x61\x6B\x65\x44\x69\x61\x6C\x6F\x67\x53\x65\x72\x76\x69\x63\x65\x55\x49\x22\x20\x56\x65\x72\x73\x69\x6F\x6E\x3D\x22\x31\x2E\x30\x22\x3E\x3C\x44\x65\x70\x65\x6E\x64\x65\x6E\x63\x69\x65\x73\x2F\x3E\x3C\x2F\x52\x65\x73\x6F\x75\x72\x63\x65\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x05\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x4C\x6F\x63\x61\x6C\x69\x7A\x65\x64\x53\x74\x72\x69\x6E\x67\x73\x08\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x49\x6E\x73\x74\x61\x6E\x63\x65\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x54\x65\x78\x74\x05\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x49\x6D\x61\x67\x65\x0F\x00\x00\x00\x00\x00\x00\x00\x0F\x00\x00\x00\x43\x6C\x61\x73\x73\x4E\x61\x6D\x65\x52\x65\x63\x6F\x72\x64\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x43\x6F\x6C\x6F\x72\x44\x69\x61\x6C\x6F\x67\x43\x6F\x6D\x70\x6F\x6E\x65\x6E\x74\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x46\x69\x6C\x65\x44\x69\x61\x6C\x6F\x67\x43\x6F\x6D\x70\x6F\x6E\x65\x6E\x74\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x46\x6F\x6E\x74\x44\x69\x61\x6C\x6F\x67\x43\x6F\x6D\x70\x6F\x6E\x65\x6E\x74\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0C\x00\x00\x00\x00\x00\x00\x00\x0C\x00\x00\x00\x47\x61\x63\x47\x65\x6E\x43\x6F\x6E\x66\x69\x67\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x43\x70\x70\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x0D\x00\x00\x00\x00\x00\x00\x00\x0D\x00\x00\x00\x43\x70\x70\x43\x6F\x6D\x70\x72\x65\x73\x73\x65\x64\x1A\x00\x00\x00\x00\x00\x00\x00\x1A\x00\x00\x00\x47\x75\x69\x46\x61\x6B\x65\x44\x69\x61\x6C\x6F\x67\x53\x65\x72\x76\x69\x63\x65\x55\x49\x2E\x63\x70\x70\x02\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x4E\x61\x6D\x65\x16\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x47\x75\x69\x46\x61\x6B\x65\x44\x69\x61\x6C\x6F\x67\x53\x65\x72\x76\x69\x63\x65\x55\x49\x02\x00\x00\x00\x00\x00\x00\x00\x0D\x00\x00\x00\x00\x00\x00\x00\x0D\x00\x00\x00\x4E\x6F\x72\x6D\x61\x6C\x49\x6E\x63\x6C\x75\x64\x65\x13\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x2E\x2E\x2F\x2E\x2E\x2F\x2E\x2E\x2F\x2E\x2E\x2F\x47\x61\x63\x55\x49\x2E\x68\x02\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x52\x65\x66\x6C\x65\x63\x74\x69\x6F\x6E\x49\x6E\x63\x6C\x75\x64\x65\x3C\x00\x00\x00\x00\x00\x00\x00\x3C\x00\x00\x00\x2E\x2E\x2F\x2E\x2E\x2F\x2E\x2E\x2F\x2E\x2E\x2F\x52\x65\x66\x6C\x65\x63\x74\x69\x6F\x6E\x2F\x54\x79\x70\x65\x44\x65\x73\x63\x72\x69\x70\x74\x6F\x72\x73\x2F\x47\x75\x69\x52\x65\x66\x6C\x65\x63\x74\x69\x6F\x6E\x50\x6C\x75\x67\x69\x6E\x2E\x68\x02\x00\x00\x00\x00\x00\x00\x00\x0C\x00\x00\x00\x00\x00\x00\x00\x0C\x00\x00\x00\x53\x6F\x75\x72\x63\x65\x46\x6F\x6C\x64\x65\x72\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x53\x6F\x75\x72\x63\x65\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x49\x6D\x61\x67\x65\x73\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x45\x72\x72\x6F\x72\xDA\x14\x00\x00\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\xF0\x00\x00\x00\xF0\x08\x06\x00\x00\x00\x3E\x55\xE9\x92\x00\x00\x00\x06\x62\x4B\x47\x44\x00\xFF\x00\xFF\x00\xFF\xA0\xBD\xA7\x93\x00\x00\x14\x8F\x49\x44\x41\x54\x78\x9C\xED\x9D\x79\xB0\x9F\x55\x79\xC7\x3F\xF7\xE6\x26\x21\x85\x34\x81\x84\x80\x20\x92\xB0\x59\x51\xF6\xAD\x42\x14\xA4\x99\x5A\xA6\x82\x6C\x42\x6A\x2D\xAB\x20\x8B\x0B\xE0\x42\xC7\x5A\x44\x16\xC5\xA5\x15\x6C\x1D\xA1",
"\xAD\x54\x10\x24\x41\xDB\x8E\x55\x2C\x65\x06\x87\x2A\xA0\x6C\xB2\x86\x2D\x21\x09\x81\x11\x59\xB2\x10\x48\x02\xDC\x24\xB7\x7F\x9C\xDF\x6F\x72\x8D\x97\xBB\xFD\x9E\xE7\x39\xEF\x79\xDF\xEF\x67\xE6\x99\x7B\xE7\xE6\xE6\xDC\xF3\x3C\xE7\x79\xDE\xDF\x79\xCF\x79\xCE\x73\x40\x08\x21\x84\x10\x42\x08\x21\x84\x10\x42\x08\x21\x84\x10\x42\x08\x21\x84\x10\x42\x08\x21\x84\x10\x42\x08\x21\x84\x10\x42\x08\x21\x84\x10\x42\x08\x21\x84\x10\x42\x08\x21\x84\x10\x42\x88\xBC\x74\xE5\xEE\x80\x18\x36\x53\x80\xE9\x2D\xD9\x1E\x78\x4B\xEB\x67\x53\x80\xA9\xAD\xAF\xE3\x81\x49\xAD\xDF\x1F\x07\x6C\xDA\xFA\x7E\x15\xF0\x46\xEB\xFB\x15\xC0\xEB\xC0\xD2\x8D\xE4\x39\x60\x71\x3F\x59\xE6\xA5\x88\xB0\x43\x01\x5C\x3D\xA6\x01\xBB\xB7\x64\xB7\xD6\xD7\x9D\x81\x89\xC1\xFD\x58\x09\xCC\x07\x1E\x6E\xC9\x43\x2D\x79\x21\xB8\x1F\x62\x10\x14\xC0\x79\x19\x03\xFC\x09\x70\x10\x30\xB3\x25\x33\xB2\xF6\x68\x68\x9E\x03\xEE\x03\x6E\x07\xEE\x00\xEE\x66\xC3\xA7\xBB\x08\x46\x01\x1C\xCF\x2E\xC0\x61\xC0\x5F\x00\xEF\x61\xC3\x34\xB7\x54\x5E\x05\x7E\x01\xFC\x0F\x70\x33\xB0\x20\x6F\x77\x84\xB0\x65\x0C\xF0\x3E\xE0\x9F\x49\xCE\xDD\x57\x73\x99\x0F\x7C\x0B\x38\x18\xE8\x36\xB0\x9F\x10\xE1\x74\x93\xA6\xC3\x57\x00\xBF\x25\x7F\x50\xE5\x92\x17\x81\x6B\x81\x59\x28\x98\x45\x01\xBC\x0D\xB8\x10\x58\x42\xFE\xE0\xA9\x9A\x3C\x0D\x7C\x11\x78\xEB\x68\x8D\x2B\x84\x07\x3D\xC0\x51\xC0\x4D\xC0\x3A\xF2\x07\x4A\xD5\x65\x2D\xF0\x53\xE0\x48\xD2\xEB\x85\x10\x59\xD8\x0C\x38\x1D\x78\x82\xFC\x41\x51\xAA\x2C\x02\xCE\x07\x26\x8F\xD0\xF6\x42\x8C\x9A\x6D\x81\xAF\x02\xCB\xC9\x1F\x00\x75\x91\xE5\xC0\x65\xA4\xE4\x14\x21\x5C\xD8\x92\xE4\x64\xAB\xC9\xEF\xF0\x75\x95\xD7\x81\xAB\x50\x20\x0B\x43\xA6\x90\x16\xA6\x56\x92\xDF\xC1\x9B\x22\xAB\x48\x2B\xF8\x5B\x0D\x3D\x3C\x42\x0C\xCC\x78\xE0\x73\xC0\xCB\xE4\x77\xE8\xA6\xCA\x0A\xE0\x33\xA4\xBC\x6E\x21\x86\xCD\xE1\x34\x23\xE9\xA2\x14\x99\x0F\x7C\x68\xD0\x11\x13\x02\x78\x3B\x70\x2B\xF9\x1D\x56\x32\xB0\xFC\x2F\xE9\x60\x87\x10\xBF\x47\x0F\x69\x3B\x63\x0D\xF9\x9D\x54\x32\xB8\xAC\x21\xAD\x49\x68\x5A\x2D\x00\xD8\x13\xB8\x97\xFC\x8E\x29\x19\x99\x3C\x08\xEC\x3F\xC0\x78\x8A\x86\x30\x16\xB8\x84\x94\x19\x94\xDB\x19\x25\xA3\x93\x5E\xE0\x4B\xA4\x19\x94\x68\x10\x33\x48\xE7\x59\x73\x3B\xA0\xC4\x46\xEE\x42\xEF\xC6\x8D\xE1\x54\xE0\x15\xF2\x3B\x9D\xC4\x56\x56\x02\x27\xD1\x30\x9A\x74\xA0\x7F\x02\xF0\x1D\xE0\xC4\xDC\x1D\xE9\x80\x35\xC0\x53\xA4\x9A\x55\x8B\x5A\x5F\x9F\x67\x43\x5D\xAB\x97\x48\x7B\xA7\x90\xAA\x64\xAC\x6A\x7D\xBF\x29\x1B\x16\x7D\x26\xB3\xA1\x86\xD6\x14\x52\xB2\xC4\x0C\x52\xAD\xAD\x19\xC0\x0E\x24\x5B\x95\xCA\xD5\xC0\xD9\xC0\x6B\xB9\x3B\x12\x41\x53\x02\x78\x06\xF0\x1F\xC0\x5E\xB9\x3B\x32\x02\x96\x01\x77\x02\xBF\x21\xD5\xA4\x7A\x90\x14\xBC\xEB\x9D\xFF\xEE\x18\x60\x47\x60\x0F\x52\x4D\xAE\xBD\x81\x03\x81\xCD\x9D\xFF\xAE\x25\xF7\x01\xC7\x90\x8E\x30\x8A\xC2\x79\x3F\xE9\x93\x29\xF7\x14\x6F\x28\x79\x11\xF8\x01\xF0\x51\x60\x57\xAA\xF5\x70\xED\x22\xF5\xE9\x34\xE0\x06\xCA\xB1\xE7\x2C\x0F\x63\x88\x38\xCE\xA4\xDA\xAB\xCC\x0F\x91\x56\x51\x0F\xA0\xAC\xB3\xB1\x63\x80\x3F\x05\x2E\x22\xCD\x0E\x72\xDB\xF1\xCD\xA4\x97\x74\xE4\x53\x14\x46\x37\xF0\x75\xF2\x3B\xD0\x40\xF2\x28\x70\x01\xA9\x1A\x65\x5D\xD8\x95\x94\x5C\xF1\x18\xF9\xED\x3B\x90\x5C\x46\xB5\x66\x34\x62\x10\x26\x00\x3F\x22\xBF\xD3\xF4\x97\x55\xC0\xF7\x48\xEF\x92\x75\x67\x26\x70\x0D\xD5\x3B\x76\x39\x17\xD8\xC4\x51\x6F\x61\xC0\x44\xE0\xFF\xC8\xEF\x2C\x6D\x59\x04\x9C\xC3\x86\xDB\x12\x9A\xC4\x64\xE0\x3C\xD2\x4A\x79\xEE\x71\x68\xCB\xCF\x49\x95\x54\x44\x05\xD9\x1C\xF8\x35\xF9\x9D\xA4\x8F\x54\xEC\xFC\x38\xCA\x7A\xAF\xF5\xA2\x07\x98\x4D\x75\xD2\x55\xEF\x44\x25\x7C\x2A\xC7\x34\xE0\x7E\xF2\x3B\xC7\x43\xA4\x63\x6F\x7A\xDF\x1A\x98\x59\xC0\x3D\xE4\x1F\xA7\xDF\x90\x2A\xAC\x88\x0A\xB0\x25\x30\x8F\xBC\x0E\x31\x8F\x54\x65\x51\x81\x3B\x34\x5D\xC0\xD1\xE4\x5F\xF0\x7A\x98\x94\xD0\x22\x32\x32\x89\xBC\x53\xB3\x65\xA4\x63\x88\x3A\xDA\x36\x72\x7A\x48\x5B\x3C\x2F\x92\x6F\xFC\x1E\x00\xB6\xF0\x56\x54\x0C\xCC\x44\xF2\xBD\xF3\xAE\x23\x5D\x95\xA2\xC1\xEF\x9C\xA9\xC0\x95\xA4\x0C\xB3\x1C\x63\x79\x27\x5A\xD8\x0A\x67\x02\x70\x1B\x79\x06\x7C\x1E\xCD\xD8\x0E\x8A\x66\x26\xF9\xA6\xD5\xB7\xA2\x2D\xA6\x30\xBA\xC9\xB3\xCF\xDB\x3E\x7B\x3A\xDE\x5F\xC5\xC6\x32\x9E\x74\x46\xBB\x97\xF8\xF1\x9D\x83\xD6\x30\x42",
"\xF8\x06\xF1\x83\xBB\x88\x74\x87\xAF\x88\x61\x7F\x52\x21\xBB\xE8\x71\xFE\x72\x84\x72\x4D\xE6\x4C\xE2\x07\xF5\xDF\xD0\x3B\x52\x0E\x26\x92\xB2\xD7\xA2\xC7\xFB\xB4\x00\xDD\x1A\xC9\xFB\x89\x3D\x98\xB0\x1A\x38\x21\x44\x33\x31\x18\xA7\x10\x5B\x6C\xB0\x17\xF8\xB3\x10\xCD\x1A\xC4\xF6\xC4\x6E\x37\x2C\x01\xF6\x0B\xD1\x4C\x0C\x87\xBD\x80\x85\xC4\x8D\xFF\x52\xD2\x19\x72\x61\xC0\x04\x52\xE6\x4C\xD4\xE0\xDD\x86\xB6\x87\xAA\xC8\x54\xE0\x97\xC4\xF9\xC1\xDD\x68\x65\xDA\x84\xAB\x89\x1B\x34\x9D\x58\xA9\x36\xE3\x81\xEB\x88\xF3\x87\x6B\x63\xD4\xAA\x2F\xA7\x12\x37\x58\x17\xA1\x6D\x84\x12\xE8\x22\xAD\x16\x47\xF9\x85\xD6\x41\x46\xC9\x8E\xC4\xDC\x08\xB8\x9E\x74\xEC\x4D\x94\xC5\xD9\xC4\x64\x6F\xBD\x82\x4A\xD6\x8E\x98\x1E\xE0\x57\xC4\x04\xEF\x27\x82\x74\x12\xF6\x9C\x4E\x4A\x6B\xF5\xF6\x93\xBB\x49\x17\x01\x88\x61\x72\x31\xFE\x83\xB2\x8E\xB2\x4B\xCC\x8A\xC4\x49\xC4\x04\xF1\x85\x31\xEA\x94\xCF\x7E\xF8\xEF\xF7\xAE\x07\x3E\x16\xA5\x90\x70\xE7\x4C\xFC\xA7\xD3\xBD\xC0\x3E\x51\x0A\x95\x4A\x0F\x31\x5B\x46\x9F\x8D\x52\x48\x84\x71\x0E\xFE\x7E\xF3\x20\x9A\x4A\x0F\xCA\xDF\xE1\x3F\x08\x17\x85\x69\x23\xA2\xB9\x0C\x7F\xFF\x39\x3F\x4C\x9B\xC2\xD8\x05\xFF\x94\xB9\x1B\xD0\x56\x51\x9D\xE9\x02\xBE\x8F\xAF\x0F\xAD\x06\x76\x8A\x52\xA8\x24\x6E\xC5\xD7\xF0\xB7\xA1\xCA\x19\x4D\x60\x13\xFC\x33\xB6\x6E\x0E\xD3\xA6\x10\x8E\xC2\xD7\xE0\x0B\x51\x7A\x64\x93\x98\x4A\xBA\x17\xC9\xD3\xA7\x3E\x10\xA6\x4D\xC5\x19\x07\x3C\x89\x9F\xA1\xD7\xA0\xD5\xC3\x26\xB2\x27\xBE\xC5\xE5\x17\xA0\xE2\x0E\x00\xFC\x2D\xBE\x4F\xCA\x93\xE3\x54\x11\x15\xE3\x6F\xF0\xF5\xAD\xC6\x67\xF0\x4D\x05\x5E\xC6\xCF\xC0\xDF\x8D\x53\x45\x54\x94\x6B\xF0\xF3\xAF\xE5\x34\xFC\xD5\xCC\xF3\x02\xB2\x05\xA4\xAA\x0E\xA2\xD9\x6C\x86\xEF\x2B\xDA\xA5\x71\xAA\x54\x8B\xAD\x49\x97\x7E\x79\x18\xB5\x97\x74\xFD\xA5\x10\x90\xB2\xFB\xDE\xC0\xC7\xD7\x5E\x25\xDD\x0C\xD2\x38\x2E\xC7\xEF\xA9\x78\x61\x9C\x1A\xA2\x10\x2E\xC1\xCF\xDF\xBE\x11\xA8\x47\x25\xD8\x16\xBF\xA4\x8D\x79\x68\xBF\x57\xFC\x21\x9B\xE0\x57\x77\x7A\x35\x69\x46\xD9\x18\xBE\x86\x8F\x21\xD7\xA1\xF2\xAF\xE2\xCD\x79\x37\x7E\x27\x97\x1A\xF3\x2E\x3C\x91\xB4\x7A\xE7\x61\xC4\x6F\x07\xEA\x21\xCA\xE4\x2A\x7C\x7C\x6F\x29\x0D\x29\x3F\x7C\x2E\x3E\x06\x5C\x06\x4C\x09\xD4\x43\x94\xC9\x16\xA4\x60\xF3\xF0\xC1\x4F\x06\xEA\x91\x85\x31\xC0\x53\xF8\x18\xEF\xEC\x40\x3D\x44\xD9\x78\x7D\x88\x2C\x22\x1D\x89\xAD\x2D\x5E\x39\xCF\xF3\xA8\xB9\xE1\x84\x29\x63\xF1\x5B\xD0\xFA\x60\xA0\x1E\xE1\xFC\x0C\x1F\xA3\x1D\x19\xA9\x84\xA8\x05\xC7\xE2\xE3\x8B\x3F\x89\x54\x22\x92\xED\xF0\x29\x95\x73\x2F\x3A\xE3\x2B\x46\x4E\x17\x70\x3F\xF6\xFE\xB8\x96\xE4\xEB\xB5\xE3\x4B\xF8\x3C\xF1\x0E\x8B\x54\x42\xD4\x8A\x23\xF0\xF1\xC9\x2F\x44\x2A\x11\x41\x37\xE9\xBE\x21\x6B\x43\xDD\x1D\xA9\x84\xA8\x1D\x5D\xC0\x7D\xD8\xFB\xE5\x22\x6A\x36\x2B\x3C\x18\x9F\x27\xDD\x71\x91\x4A\x88\x5A\xF2\x61\x7C\x7C\xF3\xC0\x48\x25\xBC\xF9\x36\x3E\x4F\x39\xAD\x3C\x8B\x4E\xE9\x01\x16\x63\xEF\x9F\x97\x07\xEA\xE0\xCA\x18\xE0\x39\xEC\x0D\x74\x4E\xA4\x12\xA2\xD6\x9C\x87\xBD\x7F\x3E\x4B\x7A\x75\x2C\x9E\x43\xB1\x37\xCE\x6A\x60\xF3\x48\x25\x44\xAD\x99\x8C\xCF\xD1\xD6\xF7\x7A\x77\x3C\xE2\x09\x71\x94\x43\x9B\x73\x49\xF9\xD4\xA5\x33\x0E\x98\x0D\xCC\x21\x15\x20\xE8\x6D\xC9\x82\xD6\xCF\x66\x93\xF7\x64\x55\xD5\xFB\x67\xC5\x0A\xE0\x3F\x1D\xDA\x3D\xDA\xA1\xCD\x70\x16\x60\xFF\x64\xAB\xC3\x02\xC1\x31\x0C\x6F\x65\x7E\x49\xEB\x77\xD5\x3F\x5F\x0E\xC6\xDE\x4F\x9F\x08\xD5\xC0\x81\x5D\xB0\x37\xCA\xA3\xA1\x1A\xD8\xD3\x0D\x5C\xC1\xC8\xF5\xBE\x82\x98\x19\x53\xD5\xFB\xE7\x45\x17\x30\x1F\x7B\x7F\xDD\x31\x52\x09\x6B\x3E\x85\xBD\x41\x2E\x08\xD5\xC0\x9E\xD1\x04\x47\x5B\xAE\xC1\x37\x48\xBA\xE9\xAC\x08\xDC\x15\x8E\x7D\x8B\xC0\xE3\x56\xCC\xB3\x42\x35\x30\xE6\x66\xEC\x0D\xF2\x8E\x50\x0D\x6C\x39\x86\xCE\xF5\xF7\x0A\xE2\x4E\x83\xB7\x2D\x25\x4F\xA7\xDF\x85\xBD\xBF\x16\x9B\x1B\x3D\x16\xFB\x95\xBD\x07\x43\x35\xB0\x65\x1C\xE9\x86\x08\x0B\x3B\xDC\x80\xED\x1E\x78\x37\xF0\x3D\xA3\xBE\x2D\xA6\xEC\x82\xE7\xF3\xB0\xF5\xD9\x57\x28\x34\x5F\x61\x5F\xEC\x9F\x66\x17\x46\x2A\x60\xCC\x6C\x6C\x6D\x61\x15\xC4\x96\xC1\xDB\x96\xE3\x0D\xFA\x95\x0B\x8F\x69\xF4\x5E\xA1\x1A\x18\xE1\x71\x5F\xEB\x01\xA1\x1A\xD8\x32\x17\x7B\x7B\x74\x3A\x9D\xB6\x9A\x36\x6F\x2C\x73\x3B\xE8\x53\x6E\x0E\xC2\xDE\x1E\x1F\x0F\xD5\xC0\x88\x1B\xB1",
"\x35\xC2\x8B\xA4\xAC\xAE\x52\xB1\x9A\x3E\x5B\x05\xB1\x57\xF0\xF6\xB5\x74\x2D\x95\x31\xD8\x97\xDC\xB9\x21\x54\x03\x23\x9E\xC5\xD6\x08\xD7\xC7\x76\xDF\x1C\xCF\xBB\x8F\x47\x3A\x9D\xF6\x98\x36\xF7\x97\x35\x23\xE8\x4B\x15\xB1\x9E\x2D\x2D\x89\xED\x7E\xE7\x6C\x8D\xBD\x53\x9C\x1A\xAA\x81\x3D\x9E\x37\xE5\x8D\x24\x88\xBD\x83\xB7\x8F\xB4\x78\x59\x32\x67\x60\x6F\x93\x2D\x43\x35\xE8\x90\x3F\xC7\xDE\x00\x25\x6F\x1F\x81\xDF\x14\xBA\xBF\x0C\x35\x9D\xF6\x9C\x36\xF7\x97\x92\xA7\xD0\x00\xBB\x61\x6F\x93\x43\x3D\x3A\xEA\x95\x14\xB0\x9B\x71\x7B\xCB\x29\x3F\x2D\xED\x9E\x80\xBF\x71\x02\xF0\xEF\x0C\x3C\xAE\xDD\xAD\x7F\x3B\x21\xA0\x1F\x11\xBA\x7A\xF2\x08\xA9\x4C\xB1\x25\xD6\x31\x01\x94\x13\xC0\x77\x02\xEB\x8D\xDB\x8C\xE6\xBF\x82\xFE\xCE\x09\xA4\xF5\x82\xFE\xD3\xE9\x6E\xE0\x6A\x62\x82\x17\x7C\x0E\x06\x44\xD2\x07\xDC\x65\xDC\xA6\x4B\x00\x7B\x61\x5D\xA6\xE4\x4B\xB1\xDD\x77\xC1\x32\x91\x63\x38\xD2\x7E\x27\x8E\x78\xE7\xED\x2F\x8B\x29\x3B\x91\xA3\x8D\xF5\x7E\xB0\xF5\x03\xC1\x95\x95\xD8\x2A\x5F\x72\x7A\x5E\x7F\x2C\x52\x29\x47\x22\xD7\x10\xF3\xCE\x5B\xC7\xB1\x3A\x1E\x5B\xBB\x58\x4F\xC9\xDD\x98\x82\xBD\x53\xEC\x1C\xAA\x81\x2F\x9D\x1C\x66\xA8\xBA\x94\x7E\x98\xA1\x3F\xEF\xC0\xDE\x3E\x93\x43\x35\x18\x25\xFB\x60\xAB\xF4\x2A\xCA\x4E\xE0\xD8\x98\xA8\x95\xE0\x68\xF1\x3E\x29\x15\x4D\x0F\xF6\x7B\xF7\x7B\x5A\x77\xD2\xC3\xE0\x33\x8C\xDB\x5B\x48\xBA\x12\xB2\x2E\xAC\x07\x4E\x26\x39\x7C\x5D\x98\x03\x9C\x42\xF9\x0B\x8D\xFD\x59\x0B\x3C\x6D\xDC\xE6\x74\xE3\xF6\x5C\x02\x78\x7B\xE3\xF6\x16\x1B\xB7\x57\x05\xD6\x93\x1C\xBE\x0E\x41\x3C\x07\xF8\x08\xF5\x7A\xC8\xB6\xB1\xDE\xCF\xB6\xFE\x70\x73\x09\xE0\xAD\x8C\xDB\x5B\x64\xDC\x5E\x55\xA8\x43\x10\xD7\x39\x78\xC1\xFE\xC3\x63\x6B\xE3\xF6\x5C\x02\x78\xAA\x71\x7B\x8B\x8D\xDB\xAB\x12\x25\x07\x71\xDD\x83\x17\xEC\x3F\x3C\xCC\xEF\xAF\xF6\x08\x60\xEB\x4E\x3E\x6F\xDC\x5E\xD5\x28\x31\x88\x9B\x10\xBC\x00\xBF\x33\x6E\xAF\x91\x01\xBC\xD4\xB8\xBD\x2A\x52\x52\x10\x37\x25\x78\xC1\xDE\xF7\xAC\x67\xA7\x2E\x3C\x8E\xED\xD2\xFB\xBE\xB1\xDD\xCF\x4A\x74\xD6\xD4\x48\xE5\x06\xEA\xB5\xA5\x37\x14\x07\x60\x6B\xBF\x22\x2A\xAA\x3E\x83\xAD\xD2\xE6\x2B\x77\x15\xA7\xAA\x41\xDC\xB4\xE0\x85\x54\x12\xD6\xD2\x86\xD6\xDB\x52\x2E\xBC\x80\xAD\xD2\x45\x9D\xA3\x34\xA2\x6A\x41\xDC\xC4\xE0\x05\xFB\x73\xED\xD6\xEF\xD4\x2E\x2C\xC7\x56\xE9\x22\xD2\xCF\x1C\xA8\x4A\x10\x37\x35\x78\x21\xDD\xBF\x65\x69\xCB\x22\xAE\x03\xB2\xAE\x3C\x31\x21\xB6\xFB\x95\x22\x77\x10\x37\x39\x78\x01\xFE\x08\x5B\x7B\x16\x51\xA9\x64\x2D\xB6\x4A\x37\xD9\x81\x20\x5F\xEE\x74\xDD\x72\x9B\x47\xC3\x18\x6C\x6D\xBA\xD6\xBA\x83\x4D\x1F\xA0\x52\xE8\xCB\xF0\x37\xC7\x21\xFF\x68\x24\x9A\x42\xDB\x51\x85\x29\x74\x91\xB7\x0A\x18\xD1\xC8\x29\xB4\x16\xB1\x6C\xC8\x1D\xBC\x0A\xE2\x86\x2E\x62\x69\x1B\xA9\x73\xAA\x12\xBC\x4D\x0F\xE2\x46\x6E\x23\x29\x91\xA3\x33\xAA\x16\xBC\x4D\x0E\xE2\xCA\x27\x72\x78\x2C\x52\x58\xCF\xF3\x8B\xC8\x1F\x35\xA2\x5D\x3D\xF2\xC4\xDC\x1D\x19\x80\xD9\xC0\xF7\x69\x56\x10\x5B\xFB\x9E\xF9\x3B\xB0\x47\x00\xBF\x64\xDC\x9E\xF9\x09\x8E\x8A\x52\xE5\xE0\x6D\xD3\xB4\x20\xB6\xF6\x3D\xEB\xD8\x70\x09\x60\xEB\x13\x1C\x4D\x08\xE0\x12\x82\xB7\x4D\x93\x82\xB8\xF2\x27\xEB\x4A\x08\x60\xF3\x2A\x06\x15\xA3\xA4\xE0\x6D\xD3\x94\x20\xB6\xF6\xBD\x22\x02\xD8\x7A\x9A\x30\xDD\xB8\xBD\x2A\x51\x62\xF0\xB6\x69\x42\x10\x5B\x2F\xA0\x16\x31\x85\xB6\xAE\xA0\x31\xDD\xB8\xBD\xAA\x50\x72\xF0\xB6\xA9\x7B\x10\x4F\x37\x6E\xCF\x7C\x1B\xC9\x23\x80\x17\x1B\xB7\x37\xDD\xB8\xBD\x2A\x50\x87\xE0\x6D\x53\xE7\x20\xDE\xC1\xB8\xBD\x45\xC6\xED\xB9\xB0\x37\xB6\x7B\x67\xAB\xA9\xD7\x81\x06\x15\x76\x2F\x83\x1E\xE0\x35\x6C\x6D\xB4\x47\xA8\x06\xA3\x64\x0B\xEC\x9D\xE3\xED\xA1\x1A\xF8\xA2\xAB\x55\xCA\xE0\x9D\xD8\xDB\x67\x52\xA8\x06\x1D\xB0\x02\x5B\xC5\x8F\x8D\xED\xBE\x1B\xBA\xDC\xAC\x1C\x66\x63\x6B\x97\xA2\x8A\x33\xDE\x8B\xAD\xF2\x17\xC5\x76\xDF\x85\x1C\xD7\x8B\x8E\x41\xD7\x8B\x8E\x96\x4B\xB0\xB5\x8B\xCB\xF5\xA2\x5E\xEF\x2C\x0F\x1B\xB7\xB7\xB7\x71\x7B\x39\x38\x9A\xB8\xBC\xEE\xFE\xA5\x5F\xA3\x4B\xD6\x6E\x0F\x1C\x19\xF4\xB7\x3C\xB1\xF6\xB9\x87\x8C\xDB\x73\xE5\x5C\x6C\x9F\x5E\xCB\x28\x7F\x81\x64\x2E\x31\x9F\x80\x6F\xB6\x98\x14\xB9\x78\x36\xB7\x03\x3B\x55\x81\x6E\xEC\x5F\x03\x3F\x11\xAA\x41\x87\xCC\xC2\xDE\x29\x76\x0D\xD5\xC0\x9E\x88\xE9\xF3\x50\x2B\xC1\x51\x41\x6C\x7D",
"\x29\x58\x34\xBB\x63\x6F\x93\x43\x22\x15\xE8\x94\x2D\xB1\x37\xC0\x69\xA1\x1A\xD8\x63\x7D\xD7\xEC\xC6\x32\xDC\x02\x74\x11\xEF\xC4\x6B\x46\x66\x9A\xCA\x71\x16\xF6\x36\x29\xEE\x54\x9D\xF5\xB9\xE0\x1B\x62\xBB\x6F\x8E\x75\xA9\xA1\xD1\x04\x6F\x1B\xEF\x20\x2E\xA2\x74\xCC\x20\xFC\x10\x5B\x7B\x2C\x0E\xED\xBD\x11\x73\xB0\x35\xC2\x52\xCA\x4E\xE8\xF0\x9A\x42\x8F\x36\x81\xC2\x73\x3A\x5D\xF2\x14\xBA\x07\xFB\xB2\x50\xD7\x7B\x75\xD6\x73\x61\xE8\x4E\xE3\xF6\xB6\x00\xF6\x33\x6E\x33\x92\x7B\x1C\xDA\xBC\x16\x38\x99\xB4\xD2\x3C\x52\xD6\xB7\xFE\xEF\xB5\xA6\x3D\x4A\x78\xE8\x1A\xC5\xBB\xB1\xAF\xC3\x76\x87\x71\x7B\x21\xEC\x83\xFD\x93\xBD\xE4\xFD\x60\xEB\xC4\x00\xAB\xA2\xEB\x1E\xD3\xE9\xE3\x0D\xFA\x95\x8B\x4B\xB1\xF7\xDB\x3D\x43\x35\x30\xA2\x07\x78\x05\x5B\x43\x58\xEF\x2F\x47\x62\x99\xC8\x61\x7D\x63\x82\x65\x10\x2F\xA6\xEC\x44\x8E\x47\xB1\xF5\xD9\x97\x29\xF8\xD5\xEF\x67\xD8\x3F\xCD\x4A\xDE\x4E\xB2\x48\xA5\xF4\x3A\x34\x60\xF5\x4E\x5C\x72\x2A\xE5\x1E\xD8\xFB\xEB\x8F\x43\x35\x30\xE6\x93\xD8\x1B\xE4\xC2\x48\x05\x1C\xE8\xE4\x30\x83\xF7\x89\x9F\x4E\x83\xB8\xF4\xC3\x0C\x1E\xD3\xE7\x33\x43\x35\x30\x66\x67\xEC\x0D\xF2\x58\xA8\x06\xF6\x74\x33\xBA\x20\xBE\x82\x98\x6C\xB4\xAA\xF7\xCF\x8B\x2E\x60\x01\xF6\xFE\x5A\x7C\x59\xE4\xF9\xD8\x1B\xE5\xA0\x50\x0D\x7C\x38\x06\x58\xC2\xD0\xBA\x2E\x21\xCF\xB4\xB4\xEA\xFD\xB3\xE6\x7D\xE8\xC3\x66\x40\xBE\x85\xBD\x61\xA2\x12\xF3\xBD\x19\x47\x5A\x9D\x9E\x43\x7A\xFA\xF7\xB6\x64\x41\xEB\x67\xB3\x5B\xBF\x93\x8B\xAA\xF7\xCF\x92\xEB\xB0\xF7\xD3\x6F\x86\x6A\xE0\xC4\xC1\xD8\x1B\x66\x35\xE9\xDE\x1A\x21\x2C\x98\x8C\x4F\xA6\x5C\x1D\x66\x8A\x74\x03\xBF\xC5\xDE\x38\xE7\x46\x2A\x21\x6A\xCD\xA7\xB1\xF7\xCF\x67\x28\x7B\x4D\xE0\xF7\xF0\x98\x46\x3F\x03\x8C\x8D\x54\x42\xD4\x92\xB1\xA4\x3B\x8B\xAC\xFD\xF3\x1F\x22\x95\xF0\x66\x26\xF6\x06\xEA\x23\xBD\x83\x09\xD1\x09\x1F\xC1\xC7\x37\xF7\x8F\x54\xC2\x9B\x6E\x7C\x9E\x72\x25\xE7\xDC\x8A\xFC\x74\x01\xF7\x63\xEF\x97\x4F\xB5\xDA\xAE\x15\x5F\xC4\xE7\x49\xF7\x97\x91\x4A\x88\x5A\x71\x24\x3E\x3E\xF9\xF9\x48\x25\xA2\x78\x2B\xB0\x16\x7B\x63\xDD\x47\x0D\x9F\x76\xC2\x9D\x2E\xE0\x01\xEC\xFD\xB1\x17\xD8\x26\x50\x8F\x50\x6E\xC2\xE7\x89\x77\x74\xA4\x12\xA2\x16\x1C\x8F\x8F\x2F\x16\x9D\xFB\x3C\x14\x1F\xC4\xC7\x68\x8F\xA1\x15\x69\x31\x7C\xC6\x01\x4F\xE2\xE3\x8B\x87\x07\xEA\x11\xCE\x18\x7C\xF2\x4D\xFB\x80\x4F\x05\xEA\x21\xCA\xE6\xB3\xF8\xF8\xE0\x42\x0A\x3E\x3A\x38\x5C\x3C\x4E\x28\xF5\x91\x4A\xCF\x16\x57\x38\x4C\x84\x33\x0D\xFB\x92\xB1\x6D\x39\x3B\x50\x8F\x6C\x6C\x46\x0A\x36\x0F\x03\x5E\x19\xA8\x87\x28\x93\xEF\xE2\xE3\x7B\x2F\x01\x9B\x06\xEA\x91\x95\xAF\xE0\x63\xC4\x75\xA4\xA4\x11\x21\x06\xE2\x60\x52\x2D\x30\x0F\xDF\x2B\xB9\xDC\xD3\x88\xD9\x06\xBF\x3A\xC9\x8F\x51\x76\x49\x17\xE1\xC3\x04\xFC\x16\xAE\x56\x01\x5B\xC5\xA9\x52\x0D\xFE\x11\x1F\x63\xF6\x01\x17\x07\xEA\x21\xCA\xC0\x6B\xD6\xD7\x07\x7C\x2D\x50\x8F\xCA\xB0\x25\xF6\x45\xEF\xDA\xD2\x4B\x2A\x0F\x2A\x04\xA4\x63\x7D\x1E\x49\x44\x7D\x24\x1F\x9E\x16\xA7\x4A\xB5\xF8\x2A\x7E\x4F\xC5\xA7\x80\x3F\x8E\x53\x45\x54\x94\x49\xC0\x22\xFC\xFC\xEC\x92\x38\x55\xAA\xC7\x14\xFC\x96\xF4\xFB\x48\xA5\x52\x45\xB3\xB9\x1E\x3F\xFF\x5A\x8E\x0A\x4B\xF0\x19\xFC\x0C\xDC\x07\x9C\x1A\xA7\x8A\xA8\x18\x67\xE0\xEB\x5B\x4A\x1E\x22\xA5\xB5\x3D\x81\x9F\x91\xD7\x50\xF6\x95\x2C\x62\x74\x1C\x00\xBC\x86\x9F\x5F\x29\x7D\xB7\x1F\x47\xE0\xFB\xA4\x5C\x8C\xB2\xB4\x9A\xC4\x34\xEC\x6F\xC7\xDC\x58\x0E\x0B\xD3\xA6\x10\x6E\xC1\xD7\xE0\xBF\x40\xFB\xC3\x4D\x60\x02\xE9\x62\x3D\x4F\x5F\xFA\x69\x98\x36\x05\xB1\x33\xBE\x77\xE8\xF6\x01\x73\xD1\xD9\xE1\x3A\xD3\x85\xEF\xA2\x55\x1F\x29\x69\x63\xC7\x28\x85\x4A\xE3\x7C\x7C\x8D\xDF\x47\xBA\x3E\x43\xD4\x93\xAF\xE3\xEF\x3F\x9F\x0E\xD3\xA6\x40\x7A\x48\x15\x36\xBC\x07\xE1\x73\x51\x0A\x89\x30\xCE\xC5\xDF\x6F\x1E\x40\x0B\x57\x43\xB2\x0F\x29\x93\xCA\x73\x20\xD6\x93\xB6\x18\x44\x3D\xF8\x38\xFE\xC1\xDB\x0B\xEC\x15\xA5\x50\xE9\x5C\x88\xFF\x80\xAC\x03\x4E\x8A\x51\x47\x38\x72\x2A\x7E\x27\x8C\xFA\xCB\x05\x51\x0A\xD5\x81\x1E\xFC\x57\x12\xDB\x9F\xC4\xDA\x8C\x2F\x97\x33\x48\x0F\x62\x6F\x3F\xB9\x9D\x06\x54\xDA\xB0\x66\x07\xD2\xED\xE6\xDE\x83\xD3\x07\xFC\x7D\x90\x4E\xC2\x8E\x88\x05\xCF\x3E\x52\xAA\xEF\xF4\x18\x95\xEA\xC7\x89\xC4\x0C\x52\x1F\xE9\xB8\x99\xB6\x98\xAA\x4F\x37\x31\xAB\xCD\x6D\xF9\x70\x8C",
"\x5A\xF5\xE5\x5F\x89\x1B\xAC\x1F\x91\x12\x01\x44\x35\x19\x0F\xFC\x80\x38\x7F\xF8\x4E\x8C\x5A\xF5\x66\x13\xD2\x15\x2A\x51\x83\xF6\x4B\x94\x76\x59\x45\xA6\x11\xB3\x2E\xD2\x96\x5F\xA3\xCC\x3D\x33\xB6\x03\x5E\x20\x6E\xF0\x9E\x21\x25\xC3\x8B\x6A\xB0\x0F\xBE\x67\x7A\x37\x96\xE7\x49\x37\x89\x08\x43\x66\xE1\xBF\x3F\xDC\x5F\xD6\xA0\xA3\x88\x55\xE0\x63\xF8\x9E\x2A\xDA\x58\xDE\x00\x0E\x89\x50\xAC\x89\x9C\x4E\xDC\x40\xB6\xE5\x1A\x54\xD9\x23\x07\x93\xF0\xCF\x6B\x1E\x48\x4E\x89\x50\xAE\xC9\x5C\x46\xFC\xA0\x2E\x46\xE5\x6A\x23\x39\x00\xBF\x1B\x3C\x06\x93\x46\x95\x86\xCD\x45\x17\x30\x87\xF8\xC1\xED\x25\x55\xBB\xD4\xC2\x86\x1F\x9B\x00\x5F\xC6\xAF\x00\xDD\x60\x72\x1D\xDA\x46\x0C\x63\x13\xE0\xE7\xC4\x0F\x72\x1F\xA9\x12\xC3\x7B\xFC\x55\x6C\x1C\x87\xE0\x5B\x99\x65\x30\xB9\x05\x3D\x98\xC3\xD9\x8C\xD8\x6D\x85\xFE\xB2\x1E\xF8\x17\x52\x69\x5C\xD1\x19\xD3\x48\xD7\x9D\x44\xE4\x33\x0F\x24\xB7\xD3\xA0\x2B\x51\xAA\xC6\x24\x62\xF7\x88\x37\x96\xE5\xA4\x94\x3E\x3D\xBD\x47\xCE\x58\x52\x1E\xBA\x67\x55\xD2\xA1\xE4\x01\x54\x55\x32\x3B\x53\x81\x87\xC9\xE7\x04\x7D\xC0\xE3\xC0\x87\xD0\x3B\xD4\x70\xE8\x06\x8E\xC3\xEF\x9A\x93\xE1\xCA\xC3\x28\x61\xA7\x32\x6C\x0E\xDC\x45\x5E\x87\x68\x3B\x85\x02\xF9\xCD\x99\x45\x4C\xC1\x86\xA1\xE4\x3E\x14\xBC\x95\x63\x32\x70\x07\xF9\x9D\xA3\xED\x20\x7F\x45\x3A\x16\xD9\x74\xC6\x02\x7F\x0D\xDC\x4F\xFE\x71\xE9\x23\xA5\xCA\x4E\x72\xD5\x58\x8C\x9A\xCD\x80\x5B\xC9\xEF\x24\x6D\x79\x1A\x38\x8F\x66\xBE\x67\x6D\x4E\x2A\xDA\xBF\x84\xFC\xE3\xD0\x96\x5B\xD0\x82\x55\xE5\x19\x4F\xDA\xD3\xCB\xED\x2C\xFD\xE5\x35\xE0\x46\xD2\x14\xB2\xEE\xD3\xEB\x7D\x80\xAB\x48\xD5\x1B\x73\xDB\xBD\xBF\xDC\x48\xDA\x7E\x14\x05\xD0\x85\xEF\x75\x92\x9D\xC8\x93\xA4\x84\x90\x77\xB9\x69\x1F\xCF\xEE\xA4\x4B\xBE\x72\x64\x4F\x0D\x47\x2E\xA6\xFE\x0F\xCE\x5A\x72\x1A\xB1\x07\x20\x46\x2A\xF3\x48\x8E\x7F\x10\x65\x95\x6C\xE9\x21\xA5\x96\x5E\x4A\x4A\x6C\xC9\x6D\xC7\x37\x93\x37\x80\x93\x9D\x6C\x20\x82\x38\x94\xD8\xA3\x88\xA3\x95\x65\xA4\xC2\xF3\x67\x90\x3E\x9D\xBB\x3D\x8C\x31\x4A\xBA\x81\xDD\x80\x33\x81\x1F\x92\xF6\xBF\x73\xDB\x6B\x28\x79\x9E\x06\x9C\x2A\x6A\xCA\xB4\xE2\x6D\xA4\x6A\x1B\x25\x5D\x72\xB6\x82\x94\x69\x76\x3F\xF0\x10\x69\x8B\x6A\x3E\x29\x4F\xD8\x93\x1E\x60\x17\x52\xC0\xEE\x4E\x2A\xA5\x7A\x20\x65\xAD\xDC\xDE\x05\x1C\x0B\x3C\x9B\xBB\x23\xDE\x34\x25\x80\x21\x2D\x60\xFC\x13\xF0\xD1\xDC\x1D\xE9\x80\xD7\x81\x85\xA4\xD3\x51\x8B\x5A\xF2\x3C\xB0\xB4\x9F\xBC\x4C\x0A\xF2\xB5\xA4\xDB\xE3\x01\x26\x92\x02\xB3\x87\x14\x88\x53\xFA\xC9\x56\xC0\x8C\x8D\xA4\xE4\xCC\xB2\x2B\x81\x73\x48\xB6\x12\x35\xE4\x04\xE2\xAA\x5D\x4A\xE2\x64\x05\x2A\x40\xD7\x18\xB6\x27\xDD\x56\x98\xDB\xE9\x24\x36\xF2\x2B\x74\xE1\x58\xE3\xE8\x21\xDD\x00\x51\xE5\x55\x6A\xC9\xE0\xD2\x4B\xAA\xE9\x5D\xD2\x0A\xBE\x30\x66\x0F\xE0\x6E\xF2\x3B\xA3\x64\x64\xF2\x00\xB0\xEF\x00\xE3\x29\x1A\x48\x0F\xE9\x68\xDB\xAB\xE4\x77\x4C\xC9\xE0\xB2\x9A\x74\x84\x53\x9F\xBA\xE2\x0F\xD8\x09\xB8\x99\xFC\x4E\x2A\x19\x58\x6E\x22\x5D\xB9\x23\xC4\xA0\xCC\x02\x1E\x21\xBF\xC3\x4A\x92\x3C\x01\x7C\x60\xD0\x11\x13\x62\x23\xC6\x91\x6E\x63\xCF\x59\x31\xA2\xE9\xB2\x8C\xB4\xA7\xAB\x4B\xB5\xC5\xA8\xD9\x82\xB4\x5A\xAD\xBD\xE3\x38\x79\x95\x54\x3E\xB8\x89\xC7\x30\x85\x13\x53\x49\x4E\x55\xB5\x63\x72\x75\x92\x55\xC0\x15\xC0\xD6\xC3\x1C\x13\x21\x46\xCC\xD6\xA4\x53\x38\x4B\xC9\xEF\xF0\x75\x91\x97\x48\xA7\xB2\xB6\x1A\xC1\x38\x08\xD1\x11\x9B\x92\xAE\x7A\x79\x9C\xFC\x01\x50\xAA\x2C\x24\x6D\xDF\xA9\x4A\x86\xC8\xC6\x18\xE0\x08\xE0\x27\xE4\xB9\x51\xA0\x34\xE9\x05\x7E\x0C\x1C\x8E\xF6\x72\x45\xC5\xD8\x16\xF8\x02\xE9\x93\x25\x77\xA0\x54\x4D\x16\x00\x9F\x07\xB6\x19\xB5\x75\x85\x08\xE4\x9D\xA4\xD5\xEB\x26\x07\xF3\xB3\xA4\x45\xA9\x99\x34\xEB\xE8\xAA\xA8\x11\xDD\xC0\x7B\x81\xCB\xC9\x77\xF7\x4F\xA4\x3C\x0E\x7C\x93\x14\xB4\x55\xAA\x2A\x22\x84\x09\x3B\x00\x67\x91\xDE\x99\x57\x92\x3F\xE0\x3A\x95\x97\x81\xFF\x26\x95\xDB\x99\x61\x68\x27\x31\x0C\x34\xAD\xC9\xCB\x18\x52\xE9\x9A\x99\xA4\xB2\x35\x33\x81\xED\xB2\xF6\x68\x68\x9E\x21\x15\x47\xBF\x93\x74\x31\xD8\x23\xC0\xBA\xAC\x3D\x6A\x30\x0A\xE0\xEA\x31\x95\x54\x8B\x6A\x37\x36\xD4\xA5\xDA\x89\xF8\xAC\xA4\x65\xA4\x85\xA7\x76\x3D\xAE\x47\x80\x07\x49\xFB\xDF\xA2\x22\x28\x80\xCB\x61\x12\x69\x8A\x3A\xBD\x25\x6F\x21\x05\x7B\xFF\xFA\x56\xE3\x5B\xBF\xD7",
"\x4D\xCA\x1F\xDE\xAC\xF5\x7F\x5F\x25\x6D\xDF\xAC\x27\x4D\x79\x5F\x27\x05\xE2\x4B\xAD\xAF\x2F\x02\xBF\x23\xDD\x24\xB1\xA8\x25\x2B\xDD\x35\x12\x42\x08\x21\x84\x10\x42\x08\x21\x84\x10\x42\x08\x21\x84\x10\x42\x08\x21\x84\x10\x42\x08\x21\x84\x10\x42\x08\x21\x84\x10\x42\x08\x21\x84\x10\x42\x08\x21\x84\x10\x42\x08\x21\x84\x10\x42\x14\xCF\xFF\x03\xB1\x8E\xCD\xDE\x86\xA6\xFE\xA6\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x46\x69\x6C\x65\x83\x0A\x00\x00\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\xF0\x00\x00\x00\xF0\x08\x06\x00\x00\x00\x3E\x55\xE9\x92\x00\x00\x00\x06\x62\x4B\x47\x44\x00\xFF\x00\xFF\x00\xFF\xA0\xBD\xA7\x93\x00\x00\x0A\x38\x49\x44\x41\x54\x78\x9C\xED\xDD\x4B\xAC\x5D\x55\x1D\xC7\xF1\x6F\xB1\x5C\x0A\xAD\x60\x62\xD2\x52\x1E\x36\xEA\xA0\x32\xD1\x28\x30\x30\x10\x30\xC1\x47\x9C\xF5\x01\xA6\x13\x67\x0C\x14\x22\xC1\x10\x26\x24\xA2\x71\x0A\x9A\xA0\x4E\x1C\x69\x2B\xC2\x45\x12\x0A\x92\x18\x1F\x09\xB4\x3C\xA2\x09\x15\x13\x62\x10\xB5\x26\x4A\x54\xA8\x46\x45\x21\x69\x69\xAF\xAD\x83\x7D\x6E\x72\xC1\xAB\x9C\x7B\xF7\xDA\xEB\xBF\xFE\x7B\x7F\x3F\xC9\x7F\xBA\xEF\x7F\xAF\xB5\x7E\x77\x9F\xB3\xCF\x7E\x80\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x14\x6B\x43\x74\x03\x81\x36\x03\x57\x03\x97\x03\x3B\x67\xB5\x0D\xB8\x00\xD8\x02\x9C\x1D\xD7\x5A\xF3\x4E\x01\x2F\x01\x8F\x00\x77\x00\xAF\xC5\xB6\xA3\xA9\xD8\x06\xDC\x0A\x3C\x01\xBC\x0E\x9C\xB1\x7A\xD7\x12\x70\xD7\x5A\x26\x41\x5A\xAB\x8F\x00\x8F\xD2\x1D\x39\xA2\x17\xFC\x58\xEB\xE7\xC0\xC6\x39\xE7\x43\x9A\xCB\x75\xC0\xD3\xC4\x2F\xEE\xA9\xD4\xF3\xC0\x59\x73\xCD\x8C\xF4\x7F\x6C\x07\x0E\x10\xBF\xA0\xA7\x58\x4F\xE1\x91\x58\x3D\xEC\x03\x5E\x21\x7E\x21\x4F\xB9\xEE\xC5\x23\xB1\xD6\x68\x13\xF0\x4D\xE2\x17\xAF\xD5\xD5\x7E\x0C\xB1\xE6\xB4\x05\xF8\x31\xF1\x8B\xD6\x7A\x63\xDD\x8F\x1F\xA7\xF5\x16\xB6\x01\xCF\x12\xBF\x58\xAD\xD5\xCB\x23\xB1\xFE\xA7\xF3\x31\xBC\x19\xCA\x23\xB1\xFE\xCB\x26\xE0\x30\xF1\x8B\xD3\x9A\xAF\x3C\x12\xEB\x0D\x3C\x61\x95\xAF\x3C\x12\x0B\x80\x1B\x88\x5F\x8C\x96\x21\xD6\x3A\x5C\x84\xBF\xF3\x66\x2F\x3F\x4E\x4F\xD8\x22\xF1\x0B\xD0\xEA\x5F\x1E\x89\x27\xE8\x3A\xE2\x17\x9E\x55\xAE\x3C\x12\x4F\xCC\x93\xC4\x2F\x3A\xAB\x6C\x79\x24\x9E\x88\x6B\x89\x5F\x6C\xD6\x30\xE5\x91\x78\x02\x1E\x25\x7E\xA1\x59\x86\xB8\x29\x59\x1E\xA9\xB3\x15\xF8\x13\x7E\xD4\x1A\xBB\x45\xE0\xD3\x74\x4F\xF9\xD0\x88\x7C\x9E\x61\xFF\xFB\x9F\xA0\xBB\x7F\x78\x37\xB0\x83\x69\x3E\x0F\x2B\xFA\x08\xEC\x91\x78\xC4\x9E\x60\xB8\x05\x73\x1F\xDD\x6F\xCB\x53\x17\x1D\x5C\x43\x3C\x52\x9B\x19\xE6\x01\x74\x4B\xC0\x67\x2A\xEE\x47\xEB\xA2\x43\x6B\x88\x47\xEA\x13\x0C\xB3\x40\x3E\x5B\x73\x27\x12\x88\x0E\xAC\x21\x1E\xA9\x3B\x28\xBF\x30\xEE\xAB\xBA\x07\x39\x44\x87\xD5\x10\x8F\xD4\x7E\xCA\x2E\x88\xE3\xF8\x9D\x77\x35\xD1\x41\x35\xC4\x23\xF5\x33\xCA\x2E\x86\x03\x75\xDB\x4F\x23\x3A\xA4\x86\x78\xA4\x7E\x4F\xD9\x85\xB0\xBB\x6A\xF7\x79\x44\x07\xD4\x10\x8F\xD4\xDF\x28\xBB\x08\xDE\x55\xB7\xFD\x34\xA2\xC3\x39\x6F\x79\xED\x74\x32\xA5\x7F\x42\x9A\xE2\x45\x1A\xF3\x88\x0E\xA6\x21\x1E\xA9\xD2\x93\xAF\xD5\x45\x87\xD2\x10\x8F\x94\x01\xAE\x23\x3A\x90\x86\x78\xA4\x0C\x70\x1D\xD1\x61\x34\xC4\x23\x65\x80\xEB\x88\x0E\xA2\x21\x1E\x29\x03\x5C\x47\xE9\x71\xFE\xF6\x00\xDB\x34\xC4\x09\x19\xE0\x3A\x4A\x8F\xF3\x59\x18\x62\x61\x80\x6B\x19\x62\x9C\x0D\xB1\x0C\x70\x25\x43\x8D\xB3\x21\x9E\x38\x03\x5C\xC7\x90\xE3\x6C\x88\x27\xCC\x00\xD7\x31\xF4\x38\x1B\xE2\x89\x32\xC0\x75\xD4\x18\x67\x43\x3C\x41\x06\xB8\x8E\x5A\xE3\x6C\x88\x27\xC6\x00\xD7\x51\x73\x9C\x0D\xF1\x84\x18\xE0\x3A\x6A\x8F\xB3\x21\x9E\x08\x03\x5C\x47\xC4\x38\x1B\xE2\x09\x30\xC0\x75\x44\x8D\xB3\x21\x1E\x39\x03\x5C\x47\xE4\x38\x1B\xE2\x11\x33\xC0\x75\x44\x8F\xB3\x21\x1E\xA9\xE8\x85\x35\x15\x2D\x8C\xB3\x21\x1E\xA1\x16\x16\xD6\x14\xB4\x32\xCE\x86\x78\x64\x5A\x59\x58\x63\xF7\x2F\xEA\x86\xA6\xB5\x7A\x80\x84\x21\xF6\x19\xBB\x5A\xF6\x52\x74\x03\xC1\x3E\x05\x1C\x22\x59\x88\x0D\xB0\x96\x4D\x3D\xC0\x00\x57\x01\xCF\x91\x28\xC4\x06\x58\xCB\xFE\x1C\xDD\x40\x23\x2E\x03\x8E\x44\x37\x31\x2F\x03\xAC\x65\x69\x16\x6D\x05\x1F\x00\xEE\x8A\x6E\x62\x1E\x1B\xA2\x1B\x98\x43\xE9",
"\x13\x4F\x19\xF6\x39\xC2\x7B\x81\xA3\xD1\x4D\x34\x64\x09\x78\x27\xDD\xC9\xBD\x66\x79\x04\xD6\xB2\xDF\x01\xBF\x8C\x6E\xA2\x21\x1B\x81\x2F\x47\x37\xF1\x56\x0C\xB0\x56\x3A\x18\xDD\x40\x63\xF6\x44\x37\xF0\x56\x32\x7C\x9C\xF4\x23\x74\x3D\xDB\xE8\x3E\x46\x6F\x89\x6E\xA4\x11\x4B\x34\xFE\x32\x3C\x8F\xC0\x5A\xE9\x18\x70\x77\x74\x13\x0D\x69\xFE\xE7\xA4\x0C\x47\x23\x8F\xC0\x75\x6D\x01\x7E\x0B\x5C\x18\xDD\x48\x23\x9A\x5E\x2F\x1E\x81\xF5\x66\xAF\x01\x37\xE1\x65\xA7\x29\x18\x60\xAD\xE6\x20\xF0\xA5\xE8\x26\x34\x0E\xDE\xCC\x10\x63\x03\xDD\x5D\x3A\xD1\x37\x19\x44\x97\x7A\x72\x42\xE2\x9C\x0B\x3C\x48\x7C\x88\x0C\x70\x62\x4E\x48\xAC\x0D\xC0\x9D\xC0\x69\xE2\xC3\x64\x80\x13\x72\x42\xDA\xB0\x9B\xEE\x86\x87\xE8\x40\x19\xE0\x64\x9C\x90\x76\x6C\x06\xBE\xC0\xB4\x6E\xFE\x6F\x5A\xD3\xBF\x71\xCD\x94\x1E\xC4\x0C\xFB\xDC\xBA\xAD\xC0\xCD\xC0\x2E\xE0\xFD\xC1\xBD\x0C\xAD\xE9\xF5\xD2\x74\x73\x33\x06\xB8\x6D\xEF\xA1\x0B\xF2\x07\x81\x8B\x81\xED\xC0\x25\x8C\xE7\x72\xCC\xA6\xD7\x4B\xD3\xCD\xCD\x18\x60\xAD\xC5\xA4\xD6\x8B\x17\x72\x48\x89\x19\x60\x29\x31\x03\x2C\x25\x66\x80\xA5\xC4\x0C\xB0\x94\x98\x01\x96\x12\x33\xC0\x52\x62\x06\x58\x4A\xCC\x00\x4B\x89\x19\x60\x29\x31\x03\x2C\x25\x66\x80\xA5\xC4\x0C\xB0\x94\x98\x01\x96\x12\x33\xC0\x52\x62\x06\x58\x4A\xCC\x00\x4B\x89\x19\x60\x29\x31\x03\x2C\x25\x66\x80\xA5\xC4\x0C\xB0\x94\x98\x01\x96\x12\x33\xC0\x52\x62\x06\x58\x4A\xCC\x00\x4B\x89\x19\x60\x29\x31\x03\x2C\x25\x66\x80\xA5\xC4\x0C\xB0\x94\x98\x01\x1E\xC6\x02\xB0\x0F\x58\x04\x8E\x02\xA7\x88\x7F\x51\x75\xED\x3A\x35\xDB\xF7\xC5\xD9\x58\x2C\xF4\x1A\x51\xA5\x95\xED\x8D\xEB\x7B\x81\x17\x07\xE8\x3B\x7B\xBD\x38\x1B\x9B\xA1\x65\x5B\x2F\xA3\x97\x65\x42\xCE\x02\xEE\x19\xA0\xDF\xB1\xD5\x3D\x0C\xFB\xC9\x2F\xCB\x7A\x99\x8C\x2C\x13\x62\x78\xD7\x16\xE2\xA1\x64\x59\x2F\x93\x91\x61\x42\xF6\x0E\xD0\xE7\xD8\x6B\xA8\x8F\xD3\x19\xD6\x4B\x31\x1B\xA2\x1B\x98\x43\xE9\x41\x2C\xBD\xCF\x0B\xC0\x0B\xC0\xBB\x0B\x6F\x77\xEC\xFE\x00\xEC\x04\x5E\x2F\xBC\xDD\xD6\xD7\x4B\x51\x9E\x85\xEE\x6F\x0F\x86\x77\x3D\x76\x00\xBB\xA2\x9B\xC8\xCE\x00\xF7\xB7\x3B\xBA\x81\xC4\xF6\x44\x37\x90\x9D\x01\xEE\xEF\xCA\xE8\x06\x12\x73\xEC\x7A\x6A\xFA\xF3\xFD\x4C\xEB\xDF\x69\x8E\x03\x9B\x0A\x6F\x73\x2A\x4E\x00\xE7\x16\xDE\x66\xEB\xEB\xA5\x28\x8F\xC0\xFD\x35\x7F\xA6\xB2\x61\xA7\xA3\x1B\xC8\xCE\x00\xF7\xF7\x72\x74\x03\x89\x1D\x8B\x6E\x20\x3B\x03\xDC\xDF\x33\xD1\x0D\x24\xE6\xD8\xF5\x64\x80\xFB\x3B\x18\xDD\x40\x62\x0F\x45\x37\x90\x5D\xD3\x5F\xD0\x67\x5A\x3F\x29\xE1\x85\x1C\xEB\xE3\x85\x1C\x05\x78\x04\xEE\xEF\x24\x70\x7B\x74\x13\x09\xDD\x46\xF9\xF0\xAA\x41\x59\xAE\x6D\xF5\x66\x86\xF9\xCB\x9B\x19\x26\x24\xCB\x84\x78\x3B\xE1\xFC\xE1\xF5\x76\xC2\x09\xC9\x36\x21\xDE\xD0\xBF\x7A\x79\x43\xFF\x00\x9A\xFE\x82\x3E\x53\x7A\x10\x6B\xEC\xF3\x02\xDD\x75\xBE\xBB\x80\x2B\xE8\x2E\xDC\xDF\x58\xE1\xEF\xB6\x64\x89\xEE\x44\xD5\x11\xE0\x61\xBA\x33\xCE\x27\x2B\xFC\xDD\x8C\xEB\x65\xDD\x9A\x6E\x6E\x66\x52\x13\xA2\xDE\x26\xB5\x5E\x3C\x0B\x2D\x25\x66\x80\xA5\xC4\x0C\xB0\x94\x98\x01\x96\x12\x33\xC0\x52\x62\x06\x58\x4A\xCC\x00\x4B\x89\x19\x60\x29\x31\x03\x2C\x25\x66\x80\xA5\xC4\x0C\xB0\x94\x98\x01\x96\x12\x33\xC0\x52\x62\x06\x58\x4A\xCC\x00\x4B\x89\x19\x60\x29\x31\x03\x2C\x25\x66\x80\xA5\xC4\x0C\xB0\x94\x98\x01\x1E\xC6\x02\xB0\x0F\x58\x04\x8E\x02\xA7\x88\x7F\x2A\x64\xED\x3A\x35\xDB\xF7\xC5\xD9\x58\x2C\xF4\x1A\x51\xA5\x95\xED\x31\xA1\x3E\x56\x76\xF5\xF2\xB1\xB2\x13\x95\x65\x42\x7C\xB0\xFB\x7C\xE5\x83\xDD\x27\x26\xCB\x84\x18\xDE\xB5\x85\x78\x28\x59\xD6\xCB\x64\x64\x98\x90\xBD\x03\xF4\x39\xF6\x1A\xEA\xE3\x74\x86\xF5\x52\x4C\xD3\x0F\xAD\x9E\x29\x3D\x88\xBE\x5E\xB4\x0D\xBE\x5E\xB4\x00\xCF\x42\xF7\xB7\x07\xC3\xBB\x1E\x3B\xE8\x5E\x3D\xA3\x1E\x0C\x70\x7F\xBB\xA3\x1B\x48\x6C\x4F\x74\x03\xD9\x19\xE0\xFE\xAE\x8C\x6E\x20\x31\xC7\xAE\xA7\xA6\x3F\xDF\xCF\xB4\xFE\x9D\xE6\x38\xB0\xA9\xF0\x36\xA7\xE2\x04\x70\x6E\xE1\x6D\xB6\xBE\x5E\x8A\xF2\x08\xDC\x5F\xF3\x67\x2A\x1B\x76\x3A\xBA\x81\xEC\x0C\x70\x7F\x2F\x47\x37\x90\xD8\xB1\xE8\x06\xB2\x33\xC0\xFD\x3D\x13\xDD\x40\x62\x8E\x5D\x4F\x06\xB8\xBF\x83\xD1\x0D\x24\xF6\x50\x74\x03\xD9\x35\xFD\x05\x7D\xA6\xF5\x93\x12\x5E\xC8\xB1\x3E\x5E\xC8\x51\x80\x47\xE0\xFE\x4E\x02\xB7\x47\x37\x91\xD0\x6D\x94\x0F\xAF\x1A\x94\xE5\xDA\x56\x6F\x66\x98",
"\xBF\xBC\x99\x61\x42\xB2\x4C\x88\xB7\x13\xCE\x1F\x5E\x6F\x27\x9C\x90\x6C\x13\xE2\x0D\xFD\xAB\x97\x37\xF4\x0F\xA0\xE9\x2F\xE8\x33\xA5\x07\xB1\xC6\x3E\x2F\xD0\x5D\xE7\xBB\x0B\xB8\x82\xEE\xC2\xFD\x8D\x15\xFE\x6E\x4B\x96\xE8\x4E\x54\x1D\x01\x1E\xA6\x3B\xE3\x7C\xB2\xC2\xDF\xCD\xB8\x5E\xD6\xAD\xE9\xE6\x66\x26\x35\x21\xEA\x6D\x52\xEB\xC5\xB3\xD0\x52\x62\x06\x58\x4A\xCC\x00\x4B\x89\x19\x60\x29\x31\x03\x2C\x25\x66\x80\xA5\xC4\x0C\xB0\x94\x98\x01\x96\x12\x33\xC0\x52\x62\x19\x02\x5C\xFA\xF2\x3B\xDF\x92\x37\x5E\xA5\xE7\xB6\xF9\xDB\x1D\x33\x04\xF8\xB5\xC2\xDB\xDB\x5E\x78\x7B\x6A\xC7\x45\x85\xB7\xF7\x6A\xE1\xED\x15\x37\xC5\x00\x5F\x5E\x78\x7B\x6A\x47\xE9\xE7\x4C\x1B\xE0\x02\x5E\x2A\xBC\x3D\xDF\xA4\x30\x5E\xA5\x5F\xD5\xE2\x13\x47\x0B\xD8\x4F\xD9\xFB\x3B\x4F\x00\x17\x57\xDD\x03\xD5\x70\x29\xDD\xDC\x96\x5C\x2B\xDF\xAA\xBA\x07\xEB\x90\xE1\x08\xFC\xEB\xC2\xDB\x3B\x07\xF8\x4A\xE1\x6D\x2A\xDE\x57\xE9\xE6\xB6\xA4\xD2\x6B\x6F\x92\x3E\xCE\x30\x4F\x88\xB8\xA9\xE6\x4E\x68\x50\xB7\x30\xCC\x1A\xF9\x68\xCD\x9D\x18\xAB\xF3\xE8\x4E\xE7\x97\x9E\x9C\x25\xE0\xE6\x8A\xFB\xA1\x61\xDC\x02\xFC\x9B\xF2\xEB\x63\x88\xF7\x36\x4D\xD6\x61\x86\xF9\x0F\x7B\x06\x78\x00\xB8\xA4\xDE\xAE\xA8\x90\x4B\x81\x07\x19\x6E\x5D\x3C\x5E\x6F\x57\xC6\xEF\x56\x86\x9B\xA8\xE5\xFF\xB6\xDF\x01\xAE\xA7\x7B\x40\xBB\x17\x7B\xB4\x67\x81\x6E\x6E\x6E\x00\xBE\x4B\xF9\x13\x56\x6F\xAE\xCF\xD5\xD9\xAD\x7E\x9A\x7E\xDE\xCF\x0A\x5B\x81\x3F\x02\x67\x47\x37\xA2\x49\x58\xA2\xFB\x54\xD6\xFC\xCB\xD7\x32\x9C\x85\x06\xF8\x0B\xF0\xC3\xE8\x26\x34\x19\x3F\x20\x41\x78\x21\x4F\x80\xC1\x9F\x7E\x54\xCF\xDD\xD1\x0D\xCC\x2B\x53\x80\x0F\x03\x4F\x45\x37\xA1\xD1\x3B\x04\x3C\x19\xDD\xC4\xBC\x32\x05\x18\xE0\xCE\xE8\x06\x34\x6A\x67\x80\x2F\x46\x37\xB1\x16\xD9\x02\xFC\x38\x70\x7F\x74\x13\x1A\xAD\x7B\x81\x27\xA2\x9B\x58\x8B\x2C\x67\xA1\x57\xDA\x0E\xFC\x0A\xB8\x20\xBA\x11\x8D\xCA\x3F\x80\xCB\x48\x72\xF2\x6A\x59\xB6\x23\x30\x74\x77\x27\xDD\x18\xDD\x84\x46\xE7\x46\x92\x85\x17\xE0\x6D\xD1\x0D\xAC\xD3\xF3\xC0\x36\xCA\xDF\xFF\xA9\x69\xFA\x3A\xDD\xCD\x10\xAA\xE8\x1C\xE0\x31\x86\xBD\x1A\xC7\x1A\x7F\xFD\x84\xC4\x57\xDE\x65\xFC\x0E\xBC\xD2\xDB\xE9\x4E\xFB\x7F\x28\xB8\x0F\xE5\xF4\x1C\x70\x0D\xF0\xCF\xE8\x46\xD6\x2B\xE3\x77\xE0\x95\x5E\x05\x3E\x09\xFC\x22\xBA\x11\xA5\xF3\x2C\xF0\x31\x12\x87\x77\x4C\xB6\x00\x3F\x22\xFE\xE3\x98\x95\xA3\x1E\x03\xCE\x47\x4D\x39\x07\xF8\x06\xF1\x8B\xC3\x6A\xBB\xBE\x46\xE2\xEF\xBC\x53\x70\x3D\xDD\x6F\x7A\xD1\x0B\xC5\x6A\xAB\xFE\x0E\xEC\x41\x29\x5C\x08\x1C\x00\x4E\x13\xBF\x70\xAC\xF8\xFA\x1E\xDD\xCF\x8E\x4A\xE6\x5A\x86\x7D\x9A\x87\xD5\x76\x1D\xA2\x3B\xCB\xAC\xE4\xAE\x01\xBE\x4F\xF7\x9A\x96\xE8\x45\x65\x0D\x5B\x27\x81\x47\x80\xAB\x99\x80\xEC\xBF\x03\xAF\xD5\x56\x60\x1F\xDD\xC3\xDD\x3F\x4C\xF9\xC7\x90\x2A\xC6\xEB\xC0\x4F\x81\x87\x80\x45\xE0\xAF\xB1\xED\xD4\x33\xB5\x00\xAF\x74\x1E\x70\x15\xDD\xAB\x56\x76\x02\xEF\xA3\x0B\xF8\x3B\xE8\x7E\x96\xF2\x4C\x65\x5B\x4E\xD2\xBD\x66\xE7\x15\xBA\x6B\x96\x5F\x00\x7E\x03\x1C\x01\x9E\x06\x8E\xC7\xB5\x26\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x4D\xD7\x7F\x00\x1F\x00\xD6\x0A\x18\x44\x1E\xFC\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82\x03\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x46\x6F\x6C\x64\x65\x72\x04\x08\x00\x00\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\xF0\x00\x00\x00\xF0\x08\x06\x00\x00\x00\x3E\x55\xE9\x92\x00\x00\x00\x06\x62\x4B\x47\x44\x00\xFF\x00\xFF\x00\xFF\xA0\xBD\xA7\x93\x00\x00\x07\xB9\x49\x44\x41\x54\x78\x9C\xED\xDD\xCD\x8F\x55\xE5\x1D\xC0\xF1\xAF\xA3\x02\x8A\x14\xBB\x61\x14\x44\xE3\x8A\x76\x2B\xDA\xA4\xD1\xA2\xC6\x5A\xD3\x74\x03\xA8\x11\x37\xAC\x5C\xB4\x10\x09\x4D\x77\x2E\xDA\x7F\xC0\x9A\x18\x43\xA2\x2B\x2B\xBE\x80\xB6\x31\x0A\x49\x6D\x8C\x66\x00\x35\xBA\x10\x4C\x5C\x58\xEC\xAA\x35\x26\x54\x88\x82\xA1\x94\x99\x61\xEA\x74\xF1\x48\x62\x70\x2E\x73\x2F\xF7\x79\x39\xBF\x7B\xBF\x9F\xE4\xB7\x7D\xCE\x39\x73\xCE\x77\xEE\xFB\xBD\x20\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x62\xBB\xAC\xF5\x0E\x0C\x60\x39\x70\x07",
"\xB0\x1E\x58\xF7\xED\x4C\x02\x2B\x81\x15\xC0\x15\xED\x76\xAD\x2F\x73\xC0\xBF\x80\x0F\x81\xD7\x80\x57\x81\xD9\xA6\x7B\x24\x15\x36\x09\xEC\x04\x0E\x01\x33\xC0\xFC\x08\xCD\x67\xC0\xFD\xF9\xFE\x54\x52\x77\xDC\x05\xEC\x07\xCE\xD1\x3E\xB4\xD2\xF3\x38\x30\x91\xE5\xAF\x26\x35\x76\x0F\xF0\x1E\xED\xA3\xAA\x3D\xCF\x61\xC4\x0A\x6C\x35\xB0\x87\xF6\x21\x19\xB1\x34\xA0\x2D\xC0\x29\xDA\x07\xD4\x85\x31\x62\x85\xB1\x0C\x78\x86\xF6\xD1\x74\x6D\x8C\x58\x9D\xB7\x12\x38\x40\xFB\x58\xBA\x3A\x46\xAC\xCE\x9A\x04\x8E\xD0\x3E\x92\xAE\x8F\x11\xAB\x73\x7E\x80\xF1\x0E\x32\x7B\xE8\xFE\x1B\x54\x34\x26\x96\x01\x07\x69\x1F\x45\xB4\xF1\x96\x58\x9D\xF0\x34\xED\x63\x88\x3A\x46\xAC\xA6\x1E\xA2\x7D\x04\xD1\xC7\x88\xD5\xC4\x6A\x7C\x9D\xD7\x88\x15\xD6\x5E\xDA\x5F\xF8\xA3\x34\x3E\xB1\xA5\x6A\xEE\xA1\xFD\x05\x3F\x8A\xE3\x2D\xB1\xAA\x78\x97\xF6\x17\xFB\xA8\x8E\x11\xAB\xA8\x3B\x69\x7F\x91\x8F\xFA\x18\xB1\x8A\xD9\x4F\xFB\x0B\x7C\x1C\xC6\x88\x95\xDD\x24\xE3\xF1\x61\xFC\xAE\x8C\x11\x2B\xAB\xDF\x52\xF6\x82\x9D\x06\x76\x03\x9B\x80\x9B\x80\x2B\xEB\x1C\x56\xDF\x26\x48\x51\x19\xB1\x42\x3A\x44\xB9\x0B\xF5\x25\xD2\x6B\xCB\x5D\x67\xC4\x0A\x69\x39\x65\xBE\x80\x6E\x0E\xF8\x75\xC5\xE3\xC8\xC1\x88\x15\xCE\x7D\x94\xB9\x30\x7F\x53\xF3\x20\x32\x32\x62\x85\xF2\x18\xF9\x2F\xC8\x97\xAA\x1E\x41\x7E\x46\xAC\x30\x72\x5F\xA8\x67\x89\xF1\x98\x77\x31\x46\xAC\x10\x3E\x20\xEF\x45\xB8\xBB\xEE\xEE\x17\x65\xC4\xEA\xBC\x7F\x92\xF7\x02\xDC\x54\x75\xEF\xCB\x33\x62\x75\xDA\x97\xE4\xBD\xF8\x6E\xAC\xBB\xFB\x55\x4C\x00\x7F\xA2\x6E\xC4\x7E\x8A\x49\x7D\xC9\xFD\x12\x52\xD7\xDE\xA4\x91\x8B\x11\x6B\x68\x25\x7E\x9D\x70\x3E\xF3\x7A\x91\x7E\x41\x71\x50\x13\xC0\xB3\xC0\xD6\xD6\x3B\x32\x86\x66\x81\x33\xC0\x49\xE0\x04\x70\x14\xF8\x14\x38\x4C\xFA\x79\x9F\x33\xED\x76\xAD\xAD\xDC\xB7\x1A\xA3\xAE\xC5\x63\x62\xE7\xE2\x33\x43\x7A\x37\xE1\x4E\xD2\xFB\xFA\xC7\x8A\x01\x0F\xCE\x88\xBB\x3B\xE7\x80\x7D\xC0\x86\x9E\x67\x6F\xC4\x18\xF0\xA5\x31\xE2\xEE\xCF\x3B\xC0\xDD\xBD\x4E\xE0\xA8\x30\xE0\x4B\xD7\xE2\x89\x2D\x67\xF0\xD9\x0F\xAC\x5D\xF8\x14\xC6\x67\xC0\xC3\xF1\x96\x38\xC6\x9C\x02\x1E\xEC\x71\x0E\x43\x33\xE0\xE1\x19\x71\x9C\xD9\x05\x2C\x5D\xF8\x34\xC6\x64\xC0\x79\x78\x77\x3A\xCE\x4C\x91\x7E\x71\x73\x24\x18\x70\x3E\xDE\x12\xC7\x99\x23\xC0\xAA\x85\x4F\x63\x2C\x06\x9C\x97\x11\xC7\x99\x23\xA4\x5F\xE0\x0C\xCD\x80\xF3\x33\xE2\x38\xF3\x36\xC1\x1F\x13\x1B\x70\x19\x3E\x26\x8E\x33\xBB\x16\x3E\x85\x31\x18\x70\x39\x46\x1C\x67\x1E\x5E\xF8\x14\x76\x9F\x01\x97\xE5\xDD\xE9\x18\x73\x12\xB8\xAE\xC7\x39\xEC\x34\x03\x2E\xCF\x5B\xE2\x18\xF3\x7C\x8F\xF3\xD7\x69\x06\x5C\x87\xB7\xC4\xDD\x9F\x6F\x48\xBF\x11\x16\x8A\x01\xD7\xE3\x2D\x71\xF7\xE7\x60\xAF\x93\xD7\x55\x06\x5C\xD7\x04\xF0\x24\xED\x2F\x54\xA7\xF7\xFC\xAC\xE7\xD9\xEB\x20\x03\x6E\xE3\x7E\xE0\x33\xDA\x5F\xAC\xCE\xF7\x67\xDF\x45\xCE\xDB\x50\xFC\x4A\x9D\xD1\xB2\x04\xD8\x0C\x6C\x04\x6E\x25\xFD\xF0\x9B\xDF\x81\xD5\xDE\x1C\xB0\x06\x38\xDE\x7A\x47\xFA\xE1\x2D\xB0\x22\xB8\x82\xF4\x0F\x6E\x33\xE9\xD9\xE2\x69\xCA\xDE\x0A\xEF\xA8\x73\x58\xC3\x33\x60\x45\xB4\x06\xD8\x4B\xB9\x80\xA7\xEA\x1D\xCA\x70\x0C\x58\x91\x6D\x23\xDD\xE5\xCD\x7D\x1D\x4F\x03\x57\x55\x3C\x8E\x4B\x66\xC0\x8A\x6E\x3B\x65\x6E\x85\xEF\xCD\xBD\xA3\xFE\xDC\x86\xF4\x7D\xBB\x80\x57\x0A\xAC\xBB\x3E\xF7\x82\x06\x2C\x2D\xEC\x77\xA4\xEF\x87\xCE\x69\x5D\xE6\xF5\x0C\x58\xEA\xE1\x73\xE0\x2F\x99\xD7\x34\x60\xA9\xA2\xD7\x32\xAF\x97\xFD\xD3\x49\x06\x2C\xF5\x76\x38\xF3\x7A\x2B\x32\xAF\xE7\x3B\xB1\xA4\x8B\x58\x42\xDE\xC7\xC1\x33\xC0\xB2\x8C\xEB\x19\xB0\xB4\x88\x4E\x5F\xCF\xDE\x85\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29",
"\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x33\x60\x29\x30\x03\x96\x02\x2B\x11\xF0\x6C\xE6\xF5\x96\x64\x5E\x4F\xEA\x57\xEE\x6B\x6F\x26\xF3\x7A\x45\x02\xFE\x4F\xE6\xF5\xAE\xCF\xBC\x9E\xD4\xAF\xD5\x99\xD7\x3B\x9D\x79\xBD\x10\x01\xAF\xCF\xBC\x9E\xD4\xAF\xDB\x32\xAF\x17\x22\xE0\x63\x99\xD7\xDB\x94\x79\x3D\xA9\x5F\x1B\x33\xAF\xF7\xEF\xCC\xEB\x15\xF1\x1C\x30\x9F\x71\xA6\x81\x35\x55\x8F\x40\x82\xB5\xA4\x6B\x2F\xE7\xB5\xFC\x6C\xEE\x9D\x2C\x71\x0B\xFC\x69\xE6\xF5\x96\x02\x7F\xCC\xBC\xA6\xB4\x98\x27\x48\xD7\x5E\x4E\xB9\xDB\x28\xE2\x17\xE4\xFD\xAF\x75\x7E\xB6\xD5\x3C\x08\x8D\xB5\x1D\x94\xB9\x86\x7F\x5E\xF3\x20\x2E\xD5\xD5\xA4\xA7\xCB\x73\x1F\xFC\x1C\xB0\xBD\xE2\x71\x68\x3C\xED\x00\xFE\x47\xFE\xEB\x77\x1A\xB8\xAA\xE2\x71\x0C\xE5\x20\x65\xFE\x83\xCD\x03\x2F\x03\x37\xD4\x3B\x14\x8D\x89\xB5\xC0\x9F\x29\x77\xDD\x4E\xD5\x3B\x94\xE1\xED\xA4\xDC\x1F\xE2\xFC\x7F\xB3\xE7\x81\x07\x80\x9B\xF1\xCD\x1E\x1A\xDC\x12\xD2\xB5\xF3\x20\xF0\x22\xF9\x9F\xB0\xBA\x70\x1E\x2D\x71\x10\x97\x95\x58\x14\x58\x05\x7C\x0E\x5C\x59\x68\x7D\x29\x92\x39\xD2\xBD\xC6\x2F\x72\x2F\x5C\xEA\xBD\xD0\xC7\x81\xBF\x15\x5A\x5B\x8A\xE6\xAF\x14\x88\x17\xCA\x7E\x98\xC1\x97\x7E\xA4\xE4\xF1\x52\x0B\x97\x0C\xF8\x20\xF0\x6E\xC1\xF5\xA5\x08\x0E\x00\xEF\x94\x5A\xBC\xF4\xC7\x09\x7F\x5F\x78\x7D\xA9\xCB\xE6\x81\x3F\x94\xDC\x40\xE9\x80\xA7\x80\x3D\x85\xB7\x21\x75\xD5\x0B\xC0\xA1\x92\x1B\x28\xF5\x2C\xF4\x77\x5D\x0F\xFC\x1D\x58\x59\x61\x5B\x52\x57\x9C\x04\x7E\x4C\xA1\x27\xAF\xCE\xAB\xF1\x8D\x1C\xC7\x80\x47\x2A\x6C\x47\xEA\x92\x47\x28\x1C\x2F\xC0\xE5\xA5\x37\xF0\xAD\x4F\x80\x49\xF2\x7F\xBE\x52\xEA\xA2\xA7\x48\x1F\x86\x28\xAE\xC6\x5D\xE8\xF3\x96\x02\x6F\x00\x77\x57\xDC\xA6\x54\xDB\x5B\xC0\xAF\xC8\xFF\xD5\x52\x0B\xAA\x19\x30\xC0\x0A\xD2\xD3\xEA\xB7\x54\xDE\xAE\x54\xC3\xC7\xC0\x06\xE0\xEB\x5A\x1B\xAC\xFD\xAD\x94\xA7\x81\x5F\x02\x1F\x55\xDE\xAE\x54\xDA\x11\xE0\x5E\x2A\xC6\x0B\x6D\xBE\x56\xF6\x38\xE9\xBF\xD4\x9B\x0D\xB6\x2D\x95\x30\x45\x7A\x68\x78\xBC\xF6\x86\x6B\x3D\x89\x75\xA1\x59\xD2\x47\xB7\x7E\x08\xFC\xA4\xD1\x3E\x48\x39\x3C\x05\x6C\x05\xFE\xDB\x7A\x47\x5A\x79\x80\xF4\x9A\x59\xC9\x8F\x72\x39\x4E\xEE\xF9\x0A\xD8\x8C\x00\xB8\x0E\xD8\x0D\x7C\x43\xFB\x13\xE3\x38\x8B\xCD\x2B\xA4\x97\x45\x75\x81\x3B\x29\xFB\x6D\x1E\x8E\x33\xCC\x1C\x20\x3D\x7F\xA3\x45\x6C\x00\xF6\x91\x1E\x2B\xB7\x3E\x69\xCE\x78\xCF\x2C\xF0\x3A\x70\x07\x1D\x54\xFB\x75\xE0\x41\xAD\x02\xB6\x90\xBE\xDC\xFD\xA7\xE4\xFF\x9A\x4F\x69\x21\x33\xC0\xFB\xC0\xAB\xC0\x5E\xE0\x44\xDB\xDD\xE9\xAD\xEB\x01\x7F\xD7\xD5\xC0\xED\xA4\x9F\x5A\x59\x07\xFC\x88\x14\xF8\xB5\xC0\x35\xF8\xBD\x58\x1A\xCC\x2C\xE9\x67\x80\x4E\x91\xDE\xB3\x7C\x14\xF8\x07\xF0\x21\xF0\x1E\x70\xB6\xDD\xAE\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\xFA\xF5\x7F\xE6\x8F\xE9\xD0\xA2\xF0\x73\xB6\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82\x03\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x49\x6E\x66\x6F\x72\x6D\x61\x74\x69\x6F\x6E\xF6\x13\x00\x00\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\xF0\x00\x00\x00\xF0\x08\x06\x00\x00\x00\x3E\x55\xE9\x92\x00\x00\x00\x06\x62\x4B\x47\x44\x00\xFF\x00\xFF\x00\xFF\xA0\xBD\xA7\x93\x00\x00\x13\xAB\x49\x44\x41\x54\x78\x9C\xED\xDD\x79\xB4\x9D\x55\x79\xC7\xF1\xEF\x1D\x32\x49\xD2\x24\x24\x24\x08\x22\x09\x01\xB4\xC8\x20\x22\x50\x21\x8A\xD0\xAC\x85\xB4\xA2\x4C\x22\xB5\xAD\x22\x93\x50\xAA\x32\x88\x74\xD9\x2A\x94\x41\x71\x68\x0B\x69\x5D\x42\x5B\x5D\x62\x1D\x12\x2B\xB5\x16\x91\x94\x55\x28\x15\x88\x80\x46\x08\x24\x4C\x09\x19\x08\x4B\xC4\xCC\x90\x81\xE4\x92\x9C\xFE\xF1\x9C\x6B\x2E\xF1\xE6\xDE\x73\xEF\x7D\x9E\xBD\xDF\xE1\xF7\x59\xEB\x59\x61\x69\xD8\xBC\x7B\xBF\xCF\x3E\xE7\x3D\xFB\xDD\x03\x88\x88",
"\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\xE4\xD5\x96\xFB\x02\xA4\x65\x13\x80\x29\xCD\xD8\x17\x78\x7D\xF3\x7F\x9B\x00\x4C\x6C\xFE\x39\x02\x18\xDB\xFC\xFB\xC3\x81\xDD\x9A\xFF\xBC\x11\xD8\xDA\xFC\xE7\x75\xC0\x16\x60\xF5\x4E\xF1\x02\xB0\xAC\x47\xAC\x89\xAA\x88\xF8\x51\x07\x2E\x9E\x49\xC0\xA1\xCD\x38\xA4\xF9\xE7\x01\xC0\x98\xC4\xD7\xF1\x12\xB0\x08\x78\xBC\x19\x8F\x35\xE3\x37\x89\xAF\x43\xFA\xA0\x0E\x9C\x57\x07\xF0\x66\xE0\x58\x60\x7A\x33\xA6\x66\xBD\xA2\xFE\xBD\x00\xCC\x03\xEE\x07\x1E\x00\x1E\x66\xC7\xB7\xBB\x24\xA6\x0E\x9C\xDE\x81\xC0\x49\xC0\x7B\x80\x77\xB2\xE3\x31\xB7\xAC\x36\x00\x3F\x05\xEE\x04\xE6\x00\x8B\xF3\x5E\x8E\x88\xAF\x0E\xE0\x78\xE0\x9F\xB0\xE4\x6E\x54\x3C\x16\x01\x33\x81\xE3\x80\x76\x87\xF6\x13\x49\xAE\x1D\x7B\x1C\xBE\x09\xF8\x15\xF9\x3B\x55\xAE\x58\x09\x7C\x0B\x98\x81\x3A\xB3\x94\xC0\x1B\x81\xAB\x81\xE7\xC8\xDF\x79\x8A\x16\xCB\x81\xAB\x80\x37\x0C\xB6\x71\x45\x22\x74\x02\xA7\x02\x77\x00\xDB\xC8\xDF\x51\x8A\x1E\xAF\x02\x3F\x06\x4E\xC1\x7E\x5E\x88\x64\x31\x1A\xB8\x00\x78\x9A\xFC\x9D\xA2\xAC\xB1\x14\xB8\x12\x18\x37\xC0\xB6\x17\x19\xB4\xBD\x81\x2F\x02\x6B\xC9\xDF\x01\xAA\x12\x6B\x81\x1B\xB0\xC9\x29\x22\x21\xF6\xC0\x92\x6C\x13\xF9\x13\xBE\xAA\xB1\x05\xB8\x05\x75\x64\x71\x34\x01\x1B\x98\x7A\x89\xFC\x09\x5E\x97\xD8\x88\x8D\xE0\x4F\xEE\xFF\xF6\x88\xF4\x6E\x04\xF0\x69\x60\x3D\xF9\x13\xBA\xAE\xB1\x0E\xF8\x14\x36\xAF\x5B\xA4\x65\x27\x53\x8F\x49\x17\x65\x89\x45\xC0\x07\xFA\xBC\x63\x22\xC0\x9B\x80\xBB\xC9\x9F\xB0\x8A\xDE\xE3\xBF\xB1\x85\x1D\x22\xAF\xD1\x89\xBD\xCE\xD8\x4C\xFE\x24\x55\xF4\x1D\x9B\xB1\x31\x09\x3D\x56\x0B\x00\x6F\x05\x7E\x41\xFE\xC4\x54\x0C\x2C\xE6\x03\x47\xF5\x72\x3F\xA5\x26\x86\x01\xD7\x61\x33\x83\x72\x27\xA3\x62\x70\xD1\x05\xFC\x2D\xF6\x04\x25\x35\x32\x15\x5B\xCF\x9A\x3B\x01\x15\x3E\xF1\x10\xFA\x6D\x5C\x1B\xE7\x02\x2F\x93\x3F\xE9\x14\xBE\xF1\x12\x70\x36\x35\x53\xA7\x05\xFD\xA3\x80\xAF\x01\x1F\xC9\x7D\x21\x43\xB0\x19\x78\x16\xDB\xB3\x6A\x69\xF3\xCF\x17\xD9\xB1\xAF\xD5\x2A\xEC\xDD\x29\xD8\x2E\x19\x1B\x9B\xFF\xBC\x1B\x3B\x06\x7D\xC6\xB1\x63\x0F\xAD\x09\xD8\x64\x89\xA9\xD8\x5E\x5B\x53\x81\xFD\xB0\xB6\x2A\xAB\x6F\x00\x17\x03\xAF\xE4\xBE\x90\x14\xEA\xD2\x81\xA7\x02\xB7\x01\x87\xE7\xBE\x90\x01\x58\x03\xCC\x05\x7E\x89\xED\x49\x35\x1F\xEB\xBC\xDB\x83\xFF\xBB\x1D\xC0\x34\xE0\x30\x6C\x4F\xAE\xB7\x01\xC7\x00\xE3\x83\xFF\xBB\x9E\xE6\x01\xA7\x63\x4B\x18\xA5\xE4\x4E\xC4\xBE\x99\x72\x3F\xE2\xF5\x17\x2B\x81\xEF\x02\xE7\x01\x07\x51\xAC\x0F\xD7\x36\xEC\x9A\xCE\x07\xBE\x47\x79\xDA\x73\x46\x44\x63\x48\x3A\x17\x51\xEC\x51\xE6\xC7\xB0\x51\xD4\xA3\x29\xD7\xDA\xD8\x0E\xE0\x0F\x80\x6B\xB0\xA7\x83\xDC\xED\xB8\xAB\xE8\xC2\x96\x7C\x4A\xC9\xB4\x03\x5F\x26\x7F\x02\xF5\x16\x4F\x00\x9F\xC3\x76\xA3\xAC\x8A\x83\xB0\xC9\x15\x4F\x92\xBF\x7D\x7B\x8B\x1B\x28\xD6\x13\x8D\xF4\x61\x14\xF0\x03\xF2\x27\x4D\xCF\xD8\x08\x7C\x13\xFB\x2D\x59\x75\xD3\x81\x5B\x29\xDE\xB2\xCB\xD9\xC0\xC8\xC0\x7A\x8B\x83\x31\xC0\xFF\x91\x3F\x59\xBA\x63\x29\x70\x09\x3B\x4E\x4B\xA8\x93\x71\xC0\x65\xD8\x48\x79\xEE\xFB\xD0\x1D\xF7\x60\x3B\xA9\x48\x01\x8D\x07\x1E\x24\x7F\x92\x34\xB0\xCD\xCE\xCF\xA4\x5C\xBF\x6B\xA3\x74\x02\x67\x51\x9C\xE9\xAA\x73\xD1\x16\x3E\x85\x33\x09\x78\x84\xFC\xC9\xF1\x18\xB6\xEC\x4D\xBF\xB7\x7A\x37\x03\xF8\x39\xF9\xEF\xD3\x2F\xB1\x1D\x56\xA4\x00\xF6\x00\x16\x92\x37\x21\x16\x62\xBB\x2C\xAA\xE3\xF6\xAF\x0D\x38\x8D\xFC\x03\x5E\x8F\x63\x13\x5A\x24\xA3\xB1\xE4\x7D\x34\x5B\x83\x2D\x43\xD4\xD2\xB6\x81\xEB\xC4\x5E\xF1\xAC\x24\xDF\xFD\x7B\x14\xD8\x3D\xBA\xA2\xD2\xBB\x31\xE4\xFB\xCD\xBB\x0D\x3B\x2A\x45\x37\x7F\xE8\x26\x02\x37\x63\x33\xCC\x72\xDC\xCB\xB9\x68\x60\x2B\xB9\x51\xC0\xBD\xE4\xB9\xE1\x0B\xA9\xC7\xEB\xA0\xD4\xA6\x93\xEF\xB1\xFA\x6E\xF4\x8A\x29\x99\x76\xF2\xBC\xE7\xED\x5E\x7B\x3A\x22\xBE\x8A\xB5\x35\x02\x5B\xA3\xDD\x45\xFA\xFB\x3B\x0B\x8D\x61\x24\xF1\x15\xD2\xDF\xDC\xA5\xD8\x19\xBE\x92\xC6\x51\xD8\x46\x76\xA9\xEF\xF3\xE7\x53\x54\xAE\xCE\x2E\x22\xFD\x4D\xFD\x57\xF4\x1B\x29\x87\x31\xD8\xEC\xB5\xD4\xF7\xFB\xFC\x04\x75\xAB\xA5\x13\x49\xBB\x30\x61\x13\xF0\xE1\x24\x35\x93\xBE\x9C\x43\xDA\xCD\x06\xBB\x80\x3F\x4C\x52\xB3\x1A\xD9\x97\xB4\xAF\x1B\x9E\x03\x8E\x4C\x52\x33\x69",
"\xC5\xE1\xC0\x12\xD2\xDD\xFF\xD5\xD8\x1A\x72\x71\x30\x0A\x9B\x39\x93\xEA\xE6\xDD\x8B\x5E\x0F\x15\xD1\x44\xE0\x3E\xD2\xE5\xC1\xC3\x68\x64\xDA\xC5\x37\x48\x77\xD3\xB4\x62\xA5\xD8\x46\x00\xDF\x26\x5D\x3E\x7C\x2B\x4D\xB5\xAA\xEB\x5C\xD2\xDD\xAC\x6B\xD0\x6B\x84\x32\x68\xC3\x46\x8B\x53\xE5\x85\xC6\x41\x06\x69\x1A\x69\x4E\x04\xDC\x8E\x2D\x7B\x93\x72\xB9\x98\x34\xB3\xB7\x5E\x46\x5B\xD6\x0E\x58\x27\xF0\x33\xD2\x74\xDE\x8F\x27\xAA\x93\xF8\xBB\x00\x9B\xD6\x1A\x9D\x27\x0F\x63\x07\x01\x48\x8B\xAE\x25\xFE\xA6\x6C\xA3\xDC\x5B\xCC\x8A\x39\x9B\x34\x9D\xF8\xEA\x34\xD5\x29\xBF\x23\x89\x7F\xDF\xBB\x1D\xF8\x58\xAA\x0A\x49\xB8\x8B\x88\x7F\x9C\xEE\x02\x8E\x48\x55\xA1\xB2\xEA\x24\xCD\x2B\xA3\x2B\x52\x55\x48\x92\xB9\x84\xF8\xBC\x99\x8F\x1E\xA5\xFB\xF4\xD7\xC4\xDF\x84\x6B\x92\xD5\x46\x52\xBB\x81\xF8\xFC\xB9\x32\x59\x6D\x4A\xE6\x40\xE2\xA7\xCC\x7D\x0F\xBD\x2A\xAA\xB2\x36\xE0\xDF\x88\xCD\xA1\x4D\xC0\xFE\xA9\x2A\x54\x26\x77\x13\xDB\xF0\xF7\xA2\x9D\x33\xEA\x60\x24\xF1\x33\xB6\xE6\x24\xAB\x4D\x49\x9C\x4A\x6C\x83\x2F\x41\xD3\x23\xEB\x64\x22\x76\x2E\x52\x64\x4E\xBD\x37\x59\x6D\x0A\x6E\x38\xF0\x0C\x71\x0D\xBD\x99\xFA\x8C\x1E\x0E\xC7\xB6\x70\x9D\x05\x2C\xC6\x46\x4E\xBB\x9A\xFF\x3C\xAB\xF9\xFF\xD5\xE5\x29\xE4\xAD\xC4\x6E\x2E\xBF\x18\x6D\xEE\x00\xC0\x5F\x11\xFB\x49\xF9\xD1\x74\x55\xC9\xEA\x74\x6C\x15\x55\x7F\xED\xF1\x5C\xF3\xEF\xD6\xC1\x9F\x13\x9B\x5B\xB5\x9F\xC1\x37\x11\x58\x4F\x5C\x03\x7F\x3D\x5D\x55\xB2\x69\x07\x6E\x62\xE0\x6D\x73\x53\xF3\xDF\xAD\xBA\x5B\x89\xCB\xAF\xB5\xD4\xFC\xA7\x59\xE4\x01\x64\x8B\xB1\x5D\x1D\xAA\x6E\x30\x9D\xB7\x67\x27\xAE\xBA\xD1\xC4\xFE\x44\xBB\x3E\x5D\x55\x8A\x65\x4F\xEC\xD0\xAF\x88\x46\xED\xC2\x8E\xBF\xAC\xBA\xD3\x19\x7A\x5B\xD5\xE1\x71\xFA\x48\x60\x2B\x31\xB9\xB6\x01\x3B\x19\xA4\x76\x6E\x24\xEE\x53\xF1\xEA\x74\xD5\xC8\x66\x38\x3E\xBB\x54\x2C\xA3\x1E\x83\x31\xD7\x11\x97\x6F\x5F\x49\x58\x8F\x42\xD8\x9B\xB8\x49\x1B\x0B\xA9\xC7\x48\xEB\x59\xF8\xB5\xD9\x07\x13\x5F\x7B\x0E\x23\x89\xDB\x77\x7A\x13\xF6\x44\x59\x1B\x5F\x22\xA6\x21\xB7\x51\x9F\xED\x5F\x67\xE3\xD7\x6E\xB3\x13\x5F\x7B\x2E\xEF\x20\x6E\xE5\x52\x6D\x7E\x0B\x8F\xC1\x46\xEF\x22\x1A\xF1\xAB\x09\xEB\x91\x9B\xE7\x26\x6F\x4B\x12\x5F\x7B\x4E\xB7\x10\x93\x7B\xAB\xA9\xC9\xF6\xC3\x97\x12\xD3\x80\x6B\x80\x09\x09\xEB\x91\x9B\xE7\x4F\x90\xCD\x89\xAF\x3D\xA7\xDD\xB1\xCE\x16\x91\x83\x9F\x48\x58\x8F\x2C\x3A\x80\x67\x89\x69\xBC\x8B\x13\xD6\xA3\x08\xBC\xDB\xAF\x4E\xA2\xBE\x44\x96\x62\x4B\x62\x2B\x2B\x6A\xCE\xF3\x42\x2A\xDE\x70\xBD\x50\x07\x1E\xBC\x61\xC4\x0D\x68\xBD\x3F\x61\x3D\x92\xFB\x09\x31\x8D\x76\x4A\xCA\x4A\x14\x84\x3A\xF0\xD0\x9C\x41\x4C\x2E\xDE\x9E\xB2\x12\x29\xED\x43\xCC\x56\x39\xBF\xA0\x9E\x6B\x7C\xD5\x81\x87\xA6\x0D\x78\x04\xFF\x76\x7C\x15\xCB\xF5\x24\x52\xCE\x85\x3D\x0F\xFB\x0D\xEC\xED\xB3\xD4\x33\x01\x65\x68\x1A\xC0\x55\x01\xE5\x76\x50\xC1\xCD\x12\xDB\x69\x6D\xA5\xCC\x40\xE3\xE1\x94\x95\x28\x18\x7D\x03\x0F\x5D\x1B\x30\x0F\xFF\xB6\x5C\x4A\xC5\x9E\x0A\x8F\xC3\xBF\x91\x1A\xC0\x99\x29\x2B\x51\x30\xEA\xC0\x3E\x3E\x44\x4C\x6E\x1E\x93\xB2\x12\xD1\xBE\x4A\xCC\xA7\x5C\xDD\x46\x9E\x7B\x52\x07\xF6\xD1\x89\xCD\x07\xF7\x6E\xCF\x1B\x13\xD6\x21\x54\x07\xF0\x02\xFE\x0D\x74\x49\xCA\x4A\x14\x90\x3A\xB0\x9F\xCB\xF0\x6F\xCF\xE7\xA9\xC8\x7A\xEB\x13\xF0\x6F\x9C\x4D\xC0\xF8\x94\x95\x28\x20\x75\x60\x3F\xE3\x88\x59\xDA\xFA\xAE\xE8\x0B\x4F\xF1\x09\x71\x6A\x40\x99\xB3\xB1\xF9\xD4\x22\x1E\xD6\x01\xFF\x11\x50\xEE\x69\x01\x65\x26\xB7\x18\xFF\x4F\xB6\x4A\x0D\x10\x0C\x92\xBE\x81\x7D\x1D\x87\x7F\x9B\x3E\x9D\xB4\x06\x01\x0E\xC4\xBF\x51\x9E\x48\x5A\x83\xE2\x52\x07\xF6\xD5\x06\x2C\xC2\xBF\x5D\xA7\x45\x5E\x74\xF4\x23\xF4\x49\x01\x65\xCE\x0A\x28\x53\xA4\x41\x4C\x6E\x9D\x18\x50\x66\x32\x73\xF0\xFF\x44\xFB\xFD\xA4\x35\x28\x2E\x7D\x03\xFB\x3B\x18\xFF\x76\x2D\xED\xDC\xE8\x61\xF8\x8F\xEC\xCD\x4F\x5A\x83\x62\x53\x07\x8E\xB1\x10\xDF\x76\x7D\x99\xC0\xF9\x0A\x91\x8F\xD0\x87\x01\xAF\x73\x2E\xF3\x87\xCE\xE5\x89\xEC\xCC\x7B\x34\x7A\x34\x70\x88\x73\x99\xBF\x15\xD9\x81\xA7\x07\x94\x79\x67\x40\x99\x22\x3D\x45\x1C\x5C\x16\xB6\x4F\x5B\x64\x07\xF6\x7E\xD5\xB3\x0A\x5B\x3A\x28\x12\xE9\x41\x6C\x7B\x26\x4F\xEA\xC0\xC0\x5D\xD8\x8E\x82\x22\x91\xB6\x01\xFF\xE3\x5C\x66\xE9\x3A\xF0\x9E\xD8\xDE\xCF\x9E\xEE\x71\x2E\x4F\x64\x57\xFE\xD7\xB9\xBC\x7D",
"\x80\x3D\x9C\xCB\x04\xE2\x3A\xF0\xA1\x01\x65\xCE\x0D\x28\x53\xA4\x37\x0F\x04\x94\x19\x32\x90\x15\xD5\x81\xBD\x2F\x76\x2D\x15\x98\x96\x26\xA5\xB1\x00\xFF\xDF\xC1\xB5\xEE\xC0\x73\x81\xED\xCE\x65\x8A\xEC\x4A\x03\x78\xC8\xB9\xCC\x5A\x77\xE0\x79\xCE\xE5\x89\xF4\xC7\x3B\xE7\x4A\xD5\x81\x0F\x70\x2E\xEF\x31\xE7\xF2\x44\xFA\xB3\xC0\xB9\x3C\xEF\x3E\x01\xC4\x74\xE0\x09\xF8\x1F\xAC\xAD\x0E\x2C\xA9\x79\xE7\xDC\x78\x6C\xE3\x00\x57\x11\x1D\x78\x8A\x73\x79\x9B\xA8\xD7\xE1\x5B\x52\x0C\x8B\x80\x57\x9C\xCB\x9C\xE2\x5C\x5E\x48\x07\x9E\xEA\x5C\xDE\x12\x34\x81\x43\xD2\x7B\x15\x58\xEE\x5C\xE6\x14\xE7\xF2\x42\x3A\xF0\xBE\xCE\xE5\x2D\x73\x2E\x4F\xA4\x55\xDE\x4F\x7E\xDE\x5F\x6E\x21\x1D\x78\xB2\x73\x79\x4B\x9D\xCB\x13\x69\xD5\x32\xE7\xF2\xF6\x74\x2E\x2F\xA4\x03\x4F\x74\x2E\x6F\x99\x73\x79\x22\xAD\xF2\xFE\xF2\x70\x3F\xBF\x3A\x6A\x14\xDA\xD3\x8B\xCE\xE5\x89\xB4\xEA\xD7\xCE\xE5\xD5\xB2\x03\xAF\x76\x2E\x4F\xA4\x55\xDE\xB9\xE7\xFD\x74\x5A\x8A\x47\xE8\x55\xCE\xE5\x89\xB4\xCA\xBB\x03\x97\xE2\x1B\x78\x37\xE7\xF2\xF4\x0D\x2C\xB9\x78\x7F\x79\x78\xF7\x8D\x90\x0E\x3C\xC2\xB9\xBC\x0D\xCE\xE5\x89\xB4\x6A\xA3\x73\x79\xDE\x7D\x23\xA4\x03\x0F\x73\x2E\xAF\xCB\xB9\x3C\x91\x56\x6D\x71\x2E\xAF\x14\x1D\xD8\xFB\x22\xBD\x1B\x51\xA4\x55\xDE\xB9\x37\xDC\xB9\xBC\x90\x0E\xEC\x7D\x91\x5B\x9D\xCB\x13\x69\x55\x2D\xBF\x81\x25\x8D\xCD\x8E\x65\x6D\x72\x2C\x4B\x12\x8A\xE8\xC0\xDE\xDF\x98\xEE\x8F\x1D\x15\xE1\x39\xC9\x40\x93\x65\x7A\x57\xF8\x9F\x83\x11\x1D\xB8\xF0\x8F\x1D\x15\xF1\xF3\x82\x96\x55\x25\xDE\xB9\xE7\xFE\x73\x30\xA2\x03\x7B\x8F\x1A\x7B\x8F\x6A\x57\x85\xE7\x31\x33\x11\x87\x5B\x57\x41\xE1\xBF\x81\x23\xAC\xC0\xF7\x70\x28\xF7\x25\x58\x15\x31\x1C\x5B\xEE\x36\xD4\xF6\x5D\x86\x9E\x72\x76\x65\x1A\xBE\xB9\xEC\xBD\xBE\x38\xE4\x1B\xD8\xFB\xE5\xB7\xFB\xFC\xD1\x8A\xD8\x0A\x5C\xE1\x50\xCE\xE5\x94\xE4\x9B\x21\x03\xEF\xDC\xF3\xEE\x1B\x21\x1D\xD8\x7B\xFA\x99\xFB\xFC\xD1\x0A\xB9\x0D\x98\x39\x84\x7F\x7F\x66\xB3\x0C\xE9\x9D\x77\xEE\xB9\xCF\xEB\x8F\xE8\xC0\x85\x9F\x00\x5E\x31\x97\x32\xB8\x4E\x3C\xB3\xF9\xEF\xCA\xAE\x15\x7E\x65\x5D\x19\x3A\xB0\xFB\x2E\x06\x15\xB3\x1D\xF8\x24\x70\x06\x36\xFE\xD0\x9F\x15\xCD\xBF\xFB\x49\xB4\x59\x7E\x7F\xBC\x73\xCF\xBD\x03\x47\x9C\x1C\xEE\xFD\x98\x30\xC5\xB9\xBC\xAA\xBA\x0D\xB8\x1D\x38\x0D\x38\x05\x78\x3B\x3B\xF6\x27\x5B\x8E\x1D\xCD\xFA\x9F\xD8\x88\xB3\x66\xB7\xB5\xC6\x7B\x00\xD5\xFD\x11\x3A\xA2\x03\x7B\x4F\x0A\x98\xE2\x5C\x5E\x95\x6D\x05\x66\x35\x43\x86\x6E\x8A\x73\x79\xDE\x3B\x7C\x84\x3C\x42\x2F\x73\x2E\x6F\x8A\x73\x79\x22\xAD\xDA\xCF\xB9\x3C\xF7\x0D\x1A\x23\x3A\xB0\xF7\x45\x4E\x03\x3A\x9C\xCB\x14\xE9\x4F\x27\xFE\x5F\x1E\xCB\x9C\xCB\x0B\xB1\x3B\xBE\x2F\xBF\x1B\xC0\x9B\x92\xD6\x40\x04\xDE\x82\x7F\x1E\x8F\xF5\xBE\xC8\x88\x6F\xE0\x35\xC0\x7A\xE7\x32\x43\x4E\x76\x13\xE9\x83\x77\xCE\x45\xF4\x8B\xB0\xE5\x84\x8B\x9D\xCB\x3B\xD4\xB9\x3C\x91\xFE\x1C\xEC\x5C\x9E\x77\x9F\x00\xE2\x3A\xF0\xE3\xCE\xE5\xBD\xCD\xB9\x3C\x91\xFE\x78\xE7\x5C\xC8\x09\x9B\x51\x1D\xD8\xFB\x62\x8F\x41\x9B\x0F\x48\x3A\xED\x58\xCE\x79\x2A\x55\x07\xF6\xFE\x06\x1E\x0F\xBC\xD9\xB9\x4C\x91\x5D\x39\x18\xFF\x01\x27\xEF\x3E\x01\xC4\x75\xE0\xF9\x01\x65\x1E\x1B\x50\xA6\x48\x6F\xA6\x07\x94\xB9\x20\xA0\xCC\xB0\x0E\xBC\x12\x78\xDE\xB9\xCC\x13\x9C\xCB\x13\xD9\x95\xE3\x9D\xCB\x5B\x4E\x09\x4F\x18\x99\x85\xEF\x3B\xB4\xD5\x68\x42\x87\xC4\xEB\x04\xD6\xE2\x9B\xBB\xDF\x89\xBA\xD8\xC8\x81\xA1\xB9\xCE\xE5\xED\x0E\x1C\xE9\x5C\xA6\xC8\xCE\xDE\x01\x8C\x73\x2E\xF3\x01\xE7\xF2\x7E\x2B\xB2\x03\x47\x5C\xF4\x1F\x05\x94\x29\xD2\xD3\x7B\x02\xCA\xF4\xFE\x32\x4B\xA2\x13\x78\x19\xDF\x47\x91\x90\x91\x3C\x91\x1E\x9E\xC0\x37\x67\xD7\x53\xE2\x9F\x7E\x3F\xC1\x7F\x3E\xE9\x41\x49\x6B\x20\x75\x72\x18\xFE\xF9\xFA\xA3\xC8\x0B\x8E\x9E\x1C\x31\x27\xA0\xCC\x33\x03\xCA\x14\x81\x98\xDC\x8A\xE8\x03\xC9\x1C\x80\xFF\x27\xDA\x93\x49\x6B\x20\x75\xD1\x86\xCD\x57\xF6\xCE\xD7\xD2\x6F\x8B\xBC\x08\xFF\x46\xD1\xA4\x0E\xF1\x76\x3C\x25\xFC\xB2\x49\x31\xBF\xF8\xCE\x80\x32\x2F\x08\x28\x53\xEA\xED\xDC\x80\x32\x4B\xFD\xF8\xDC\xED\x38\xFC\x3F\xD9\x36\x61\xF3\xA3\xE5\xB5\x86\x03\x67\x61\x93\x68\x16\x63\xC7\xDC\x6C\xC3\x76\x82\xF8\x21\x70\x0E\xF0\xBA\x5C\x17\x57\x60\xE3\xB0\x9C\xD2\x93\x62\x2F\xDA\x81\x5F\xE1\xDF\x38\xDA\xD3\xF8\xB5\x4E\x07\x9E\xA3\xFF\x76\x5B\x89\x7D\xDB",
"\xB4\xE5\xB9\xCC\x42\xBA\x1C\xFF\xFC\x5C\x41\x85\x56\xD0\xCD\x24\xA6\x81\x74\xF0\x99\x25\xC9\x4D\x0C\xBC\xFD\xBE\x8B\x8E\x6E\x05\xCB\xA1\xE5\xF8\xE7\xE7\xDF\xA5\xAC\x44\xB4\xE9\xF8\x37\x50\x03\x7B\x5C\xAC\xBB\xC1\x74\xDE\xEE\xF8\x3E\xFA\x26\xFE\x33\x62\x72\xF3\xA8\x94\x95\x88\xD6\x4E\xCC\xA7\x5C\xDD\xCF\xB5\x3D\x9D\xA1\xB7\xE1\xC7\x93\x5F\x75\x71\xB4\x01\x8F\xE0\x9F\x97\xCF\x52\xC1\x0F\xC6\xAB\x88\xF9\xA4\xFB\xE3\x94\x95\x28\x10\xAF\xE3\x45\xD7\x61\x0B\x45\xEA\xE8\x14\x62\x72\xF2\x33\x29\x2B\x91\xCA\x1B\x80\x57\xF1\x6F\xAC\x79\x54\xF0\xD3\xAE\x05\x67\xE1\xD7\x86\x75\x1C\x10\x6C\x03\x1E\xC5\x3F\x1F\xBB\x80\xBD\x12\xD6\x23\xA9\x3B\x88\xF9\xC4\x3B\x2D\x65\x25\x0A\x62\x36\x7E\xED\x77\x5F\xE2\x6B\x2F\x82\x0F\x12\x93\x8B\xA1\x73\x9F\x73\x7B\x3F\x31\x8D\xF6\x24\xF5\x1B\x91\xF6\x78\x7C\xEE\x8E\x4D\x54\xE8\x95\x47\x0B\x86\x03\xCF\x10\x93\x8B\x27\x27\xAC\x47\x72\x1D\xC4\xCC\x37\x6D\x60\xC7\x65\xD6\xC9\x66\x7C\xDB\xAF\x4E\x13\x63\xAE\x20\x26\x07\x97\x50\xE2\xA5\x83\xAD\xFA\x04\x31\x8D\xB7\x06\x98\x98\xB0\x1E\xB9\x79\xCF\x1C\xF2\xDE\x85\xA2\xA8\x26\x61\x03\x77\x11\x39\x78\x71\xC2\x7A\x64\x33\x1A\xEB\x6C\x11\x0D\x78\x73\xC2\x7A\xE4\xA6\x47\xE8\xC1\xF9\x3A\x31\xB9\xB7\x0A\xD8\x2D\x61\x3D\xB2\xFA\x02\x31\x8D\xB8\x8D\x98\x2D\x41\x8B\x48\x83\x58\x03\x77\x1C\xB0\x9D\x98\xDC\xBB\x26\x61\x3D\xB2\xDB\x0B\xFF\xDF\x70\xDD\xF1\x24\x30\x22\x5D\x55\xB2\xD1\x6B\xA4\x81\x19\x45\xDC\xC0\xD5\x46\x60\x72\xBA\xAA\x14\xC3\xDF\x13\xD3\x98\x0D\xE0\xDA\x84\xF5\xC8\x45\x13\x39\x06\x26\xEA\xA9\xAF\x01\x7C\x29\x61\x3D\x0A\x63\x0F\xFC\x37\xBD\xEB\x8E\x2E\x6C\x7B\xD0\xAA\xD3\x54\xCA\xD6\x1C\x4B\xCC\x24\xA2\x06\x96\xC3\x93\xD2\x55\xA5\x58\xBE\x48\xDC\xA7\xE2\xB3\xC0\xEF\xA5\xAB\x4A\x36\x5A\xCC\xD0\xB7\xB1\xC0\x52\xE2\xF2\xEC\xBA\x74\x55\x29\x9E\x09\xC4\x0D\xE9\x37\x80\x6F\x26\xAB\x49\x3E\x5A\x4E\xD8\xB7\xEF\x10\x97\x5F\x6B\xA9\xD7\xFB\xF3\x5E\x7D\x8A\xB8\x06\x6E\x10\xB3\x55\x4A\x11\x69\x41\xFF\xEF\xBA\x90\xD8\xDC\xAA\xDB\xE4\xA1\x5E\x0D\x07\x9E\x26\xAE\x91\x37\x53\x9F\x23\x59\xB4\xA5\xCE\x0E\x47\x03\xAF\x10\x97\x57\x75\x9C\xBE\xBB\x4B\xEF\x23\xF6\x93\x72\x19\xF5\x9A\xA5\x55\x77\x93\xB0\x1D\x5B\x22\x73\xEA\xA4\x64\xB5\x29\x89\xBB\x88\x6D\xF0\x9F\x52\x8F\xF7\xC3\x75\x37\x0A\x3B\x8B\x28\x32\x97\x7E\x9C\xAC\x36\x25\x72\x00\x31\x3B\x03\xF6\x8C\xD9\xD4\xE3\xB7\x5F\x5D\xB5\x11\x3B\x68\xD5\xC0\x26\x6D\x4C\x4B\x55\xA1\xB2\xB9\x92\xD8\xC6\x6F\x00\xD7\x27\xAB\x8D\xA4\xF6\x65\xE2\xF3\xE7\xF2\x64\xB5\x29\xA1\x4E\x6C\x87\x8D\xE8\x9B\xF0\xE9\x54\x15\x92\x64\x2E\x25\x3E\x6F\x1E\x45\x03\x57\xFD\x3A\x02\x1B\x3D\x8D\xBC\x11\xDB\xB1\x57\x0C\x52\x0D\x7F\x49\x7C\xE7\xED\x02\x0E\x4F\x55\xA1\xB2\xBB\x9A\xF8\x1B\xB2\x0D\x38\x3B\x4D\x75\x24\xD0\xB9\xC4\xAD\x30\xEA\x19\x9F\x4B\x55\xA1\x2A\xE8\x24\x7E\x24\xB1\xFB\x9B\x58\x2F\xE3\xCB\xEB\x42\xEC\x83\x38\x3A\x4F\xEE\xA7\x06\x3B\x6D\x78\xDB\x0F\x3B\xDD\x3C\xFA\xE6\x34\x80\xCF\x26\xAA\x93\xF8\x49\x31\xE0\xD9\xC0\xA6\xFA\x4E\x49\x53\xA5\xEA\xF9\x08\x69\x6E\x52\x03\x5B\x6E\xA6\x57\x4C\xC5\xD7\x4E\x9A\xD1\xE6\xEE\xF8\x50\x9A\x6A\x55\xD7\xBF\x90\xEE\x66\xFD\x00\x9B\x08\x20\xC5\x34\x02\x5B\x84\x91\x2A\x1F\xBE\x96\xA6\x5A\xD5\x36\x12\x3B\x42\x25\xD5\x4D\xBB\x0F\x4D\xBB\x2C\xA2\x49\xA4\x19\x17\xE9\x8E\x07\xD1\xCC\x3D\x37\xFB\x00\xBF\x21\xDD\xCD\x5B\x81\x4D\x86\x97\x62\x38\x82\xD8\x35\xBD\x3B\xC7\x8B\xD8\x49\x22\xE2\x68\x06\xF1\xEF\x87\x7B\xC6\x66\xEA\xB3\x14\xB1\xC8\x3E\x46\xEC\xAA\xA2\x9D\x63\x2B\xF0\xEE\x14\x15\xAB\xA3\x0B\x48\x77\x23\xBB\xE3\x56\xEA\xB1\xB3\x47\xD1\x8C\x25\x7E\x5E\x73\x6F\x71\x4E\x8A\xCA\xD5\xD9\x0D\xA4\xBF\xA9\xCB\xA8\xCF\x76\xB5\x45\x70\x34\x71\x27\x78\xF4\x15\xB5\xDA\x1A\x36\x97\x36\x6C\xC1\x7A\xEA\x9B\xDB\x85\xED\x76\xA9\x81\x8D\x38\x23\x81\xCF\x13\xB7\x01\x5D\x5F\xF1\x6D\xF4\x1A\x31\x99\x91\xC0\x3D\xA4\xBF\xC9\x0D\x6C\x27\x86\x77\xC6\x57\xB1\x76\xDE\x4D\xEC\xCE\x2C\x7D\xC5\x5D\xE8\x83\x39\xB9\xD1\xA4\x7D\xAD\xD0\x33\xB6\x03\xFF\x8C\x6D\x8D\x2B\x43\x33\x09\x3B\xEE\x24\xC5\x7C\xE6\xDE\xE2\x7E\x6A\x74\x24\x4A\xD1\x8C\x25\xED\x3B\xE2\x9D\x63\x2D\x36\xA5\x4F\x9F\xDE\x03\x37\x0C\x9B\x87\x1E\xB9\x2B\x69\x7F\xF1\x28\xDA\x55\x32\xBB\x89\xC0\xE3\xE4\x4B\x82\x06\xF0\x14\xF0\x01\xF4\x1B\xAA\x15\xED\xC0\x99\xC4\x1D\x73\xD2\x6A\x3C\x8E\x26",
"\xEC\x14\xC6\x78\xE0\x21\xF2\x26\x44\x77\x52\xA8\x23\xEF\xDA\x0C\xD2\x6C\xD8\xD0\x5F\xCC\x43\x9D\xB7\x70\xC6\x01\x0F\x90\x3F\x39\xBA\x13\xE4\x4F\xB0\x65\x91\x75\x37\x0C\xF8\x53\xE0\x11\xF2\xDF\x97\x06\x36\x55\x76\x6C\x68\x8D\x65\xD0\x46\x03\x77\x93\x3F\x49\xBA\x63\x39\x70\x19\xF5\xFC\x9D\x35\x1E\xDB\xB4\xBF\x95\xCD\xE6\x53\xC5\x5D\x68\xC0\xAA\xF0\x46\x60\xEF\xF4\x72\x27\x4B\xCF\x78\x05\x3B\x87\x68\x06\xD5\x7F\xBC\x3E\x02\xB8\x05\xDB\xBD\x31\x77\xBB\xF7\x8C\xEF\x63\xAF\x1F\xA5\x04\xDA\x88\x3D\x4E\x72\x28\xF1\x0C\x36\x21\xE4\xE0\xB0\xDA\xA7\x77\x28\x76\xC8\x57\x8E\xD9\x53\xAD\xC4\xB5\x54\xFF\x83\xB3\x92\xCE\x27\xED\x02\x88\x81\xC6\x42\x2C\xF1\x8F\xA5\x5C\x5B\xB6\x74\x62\x53\x4B\xAF\xC7\x26\xB6\xE4\x6E\xC7\x5D\xC5\x56\xE0\xA3\x41\x6D\x20\x89\x9C\x40\xDA\xA5\x88\x83\x8D\x35\xD8\xC6\xF3\x17\x62\xDF\xCE\xED\x11\x8D\x31\x48\xED\xC0\x21\xC0\x45\xC0\xBF\x63\xEF\xBF\x73\xB7\x57\x7F\xF1\x22\x35\x58\x55\x54\x97\xC7\x8A\x37\x62\xBB\x6D\x94\xE9\x90\xB3\x75\xD8\x4C\xB3\x47\x80\xC7\xB0\x57\x54\x8B\xB0\x79\xC2\x91\x3A\x81\x03\xB1\x0E\x7B\x28\xB6\x95\xEA\x31\x94\x6B\xE4\xF6\x21\xE0\x0C\xE0\xF9\xDC\x17\x12\xAD\x2E\x1D\x18\x6C\x00\xE3\x1F\x81\xF3\x72\x5F\xC8\x10\x6C\x01\x96\x60\xAB\xA3\x96\x36\xE3\x45\x60\x75\x8F\x58\x8F\x75\xF2\x57\xB1\xD3\xE3\x01\xC6\x60\x1D\xB3\x13\xEB\x88\x13\x7A\xC4\x64\x60\xEA\x4E\x51\xE6\x99\x65\x37\x03\x97\x60\x6D\x25\x15\xF4\x61\xD2\xED\x76\xA9\x48\x17\xEB\xD0\x06\x74\xB5\xB1\x2F\x76\x5A\x61\xEE\xA4\x53\xF8\xC4\xCF\xD0\x81\x63\xB5\xD3\x89\x9D\x00\x51\xE4\x51\x6A\x45\xDF\xD1\x85\xED\xE9\x5D\xA6\x11\x7C\x71\x76\x18\xF0\x30\xF9\x93\x51\x31\xB0\x78\x14\x78\x7B\x2F\xF7\x53\x6A\xA8\x13\x5B\xDA\xB6\x81\xFC\x89\xA9\xE8\x3B\x36\x61\x4B\x38\xF5\xAD\x2B\xBF\x63\x7F\x60\x0E\xF9\x93\x54\xD1\x7B\xDC\x81\x1D\xB9\x23\xD2\xA7\x19\xC0\x02\xF2\x27\xAC\xC2\xE2\x69\xE0\xBD\x7D\xDE\x31\x91\x9D\x0C\xC7\x4E\x63\xCF\xB9\x63\x44\xDD\x63\x0D\xF6\x4E\x57\x87\x6A\xCB\xA0\xED\x8E\x8D\x56\xEB\xDD\x71\xBA\xD8\x80\x6D\x1F\x5C\xC7\x65\x98\x12\x64\x22\x96\x54\x45\x5B\x26\x57\xA5\xD8\x08\xDC\x04\xEC\xD9\xE2\x3D\x11\x19\xB0\x3D\xB1\x55\x38\xAB\xC9\x9F\xF0\x55\x89\x55\xD8\xAA\xAC\xC9\x03\xB8\x0F\x22\x43\xB2\x1B\x76\xD4\xCB\x53\xE4\xEF\x00\x65\x8D\x25\xD8\xEB\x3B\xED\x92\x21\xD9\x74\x00\xEF\x03\x6E\x27\xCF\x89\x02\x65\x8B\x2E\xE0\x47\xC0\xC9\xE8\x5D\xAE\x14\xCC\xDE\xC0\xDF\x60\xDF\x2C\xB9\x3B\x4A\xD1\x62\x31\xF0\x19\x60\xAF\x41\xB7\xAE\x48\x42\x6F\xC1\x46\xAF\xEB\xDC\x99\x9F\xC7\x06\xA5\xA6\x53\xAF\xA5\xAB\x52\x21\xED\xC0\xBB\x80\x1B\xC9\x77\xF6\x4F\xCA\x78\x0A\xF8\x07\xAC\xD3\x16\x69\x57\x11\x11\x17\xFB\x01\x7F\x81\xFD\x66\x7E\x89\xFC\x1D\x6E\xA8\xB1\x1E\xF8\x2F\x6C\xBB\x9D\xA9\x8E\xED\x24\x2D\xD0\x63\x4D\x5E\x1D\xD8\xD6\x35\xD3\xB1\x6D\x6B\xA6\x03\xFB\x64\xBD\xA2\xFE\xAD\xC0\x36\x47\x9F\x8B\x1D\x0C\xB6\x00\xD8\x96\xF5\x8A\x6A\x4C\x1D\xB8\x78\x26\x62\x7B\x51\x1D\xC2\x8E\x7D\xA9\xF6\x27\xFD\xAC\xA4\x35\xD8\xC0\x53\xF7\x7E\x5C\x0B\x80\xF9\xD8\xFB\x6F\x29\x08\x75\xE0\xF2\x18\x8B\x3D\xA2\x4E\x69\xC6\xEB\xB1\xCE\xDE\x73\x7F\xAB\x11\xCD\xBF\xD7\x8E\xCD\x1F\x1E\xDD\xFC\x77\x37\x60\xAF\x6F\xB6\x63\x8F\xBC\x5B\xB0\x8E\xB8\xAA\xF9\xE7\x4A\xE0\xD7\xD8\x49\x12\x4B\x9B\xF1\x52\x78\x8D\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\xA4\xF4\xFE\x1F\x9F\x26\x82\x4B\xC1\xE1\x03\xEE\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x4E\x6F\x6E\x65\x87\x13\x00\x00\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\xF0\x00\x00\x00\xF0\x08\x06\x00\x00\x00\x3E\x55\xE9\x92\x00\x00\x00\x06\x62\x4B\x47\x44\x00\xFF\x00\xFF\x00\xFF\xA0\xBD\xA7\x93\x00\x00\x13\x3C\x49\x44\x41\x54\x78\x9C\xED\xDD\x79\xB0\xDE\x55\x7D\xC7\xF1\xF7\x93\x9D\x35\xB9\x06\x08\x8B\x40\x22\x7B\xD9\x77\x50\xA4\x0C\x45\x04\xAC\x12\x60\xB0\x68\x3B\x78\x29\xB8\x8C\x83\x40\xAD\xCB\x50\xA8\xA5\x45\x91\x29\x5A\x8C\x4A\xAB\x32\x2D\xB4\x53\x10\x52\x29\x55\x08\x12\xC1\x22\xB6\x6C\xA1\x94\x7D\x4F\x00\x03\x62\x48\x81\xDC\x10\xB2\xDF\xDC\xA7\x7F\x7C\x9F\x3B\x09\xE1\x2E\xCF\x7D\xEE\xF7\x7B\xCE\x6F\xF9\xBC\x66\xCE\x24\x86",
"\xEB\xB9\xE7\xFB\x7B\xCE\x79\x7E\xE7\xF7\x3B\x1B\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x00\x8D\xDC\x05\x10\x37\x5D\xC0\x96\xC0\x58\x60\x73\x60\xFC\x46\xFF\xBD\x17\x58\xD6\xFA\x7B\x0F\xB0\x14\x58\x97\xAC\x74\x12\x42\x0D\xB8\xD8\x1A\xC0\xF6\xC0\xFB\x80\x5D\x80\x9D\x81\x6D\x5B\xFF\xD6\xFF\xE7\x96\xAD\xD4\x89\xB7\xB1\x86\xFC\x06\xF0\x0A\xF0\x5A\xEB\xCF\x57\x81\x05\xC0\x7C\x60\x21\x6A\xE8\x85\xA5\x06\x5C\x1C\xDB\x02\xFB\xB7\xD2\xBE\xAD\xB4\x07\x30\x29\x67\xA1\x80\xB5\xC0\x4B\xC0\x63\xC0\xE3\xAD\xF4\x28\xF0\x02\xD0\xCC\x57\x2C\x01\x35\xE0\x5C\xC6\x03\x87\x02\x87\x03\x47\xB4\xD2\x4E\x59\x4B\x34\x72\x4B\x80\xFB\x37\x48\xF7\xB1\xBE\x8B\x2E\x89\xA8\x01\xA7\xD1\x00\xF6\x03\xFE\xA0\x95\x8E\xC6\x9E\x53\xAB\xA4\x17\x78\x10\xB8\x13\xF8\x25\xD6\xA0\xD7\x64\x2D\x91\xC8\x28\x4C\x02\x8E\x03\x66\x01\x2F\x63\xDD\xCD\x3A\xA5\xE5\xC0\x2D\xC0\x67\xB0\xC7\x03\x91\xC2\x9B\x08\xCC\x04\x6E\xC4\x5E\x10\xE5\x6E\x44\x45\x49\xBD\xC0\x5D\xC0\x67\x81\xF7\x74\x7C\x75\x45\x02\x34\x80\x63\x80\x7F\xC4\x9E\x0B\x73\x37\x96\xA2\xA7\xD5\xC0\xCF\x80\x3F\xC2\xBE\xF0\x44\xB2\x98\x82\x75\x0F\x1F\x27\x7F\xA3\x28\x6B\x5A\x02\xFC\x10\x7B\x3F\x20\x92\xC4\x21\xC0\xF5\xD8\x9D\x24\x77\x03\xA8\x52\xBA\x1B\x38\x0D\x18\xD3\xFE\x47\x21\xD2\x9E\x06\xF6\x42\xEA\x16\xF2\x57\xF4\xAA\xA7\x17\x80\xAF\x02\x93\xDB\xFA\x64\x44\x86\x30\x16\xF8\x24\xF0\x14\xF9\x2B\x76\xDD\xD2\x1B\xC0\xC5\x74\x3E\xCB\x4C\x6A\x6C\x0C\x70\x3A\xF0\x34\xF9\x2B\x72\xDD\xD3\x5B\xC0\xE5\xD8\x3B\x07\x91\x61\x7D\x04\x78\x92\xFC\x15\x57\xE9\x9D\xE9\x75\xE0\x02\x60\xC2\xE0\x1F\x9D\xD4\xD9\xEF\x01\x73\xC8\x5F\x51\x95\x86\x4E\xBF\x01\xCE\x44\xB3\x08\xA5\x65\x2A\x70\x35\xB6\xE2\x26\x77\xE5\x54\x6A\x3F\xFD\x17\x1A\x7E\xAA\xB5\x06\xF6\x4D\xBE\x98\xFC\x95\x51\xA9\xB3\xB4\x16\x9B\xAA\xAA\x17\x5D\x35\xB3\x17\xF0\xDF\xE4\xAF\x80\x4A\x3E\xE9\x65\x6C\x0A\xAB\x54\x5C\x03\x9B\x3D\xB5\x9C\xFC\x95\x4E\xC9\x3F\xCD\xC6\x1E\x89\xA4\x82\xA6\x63\x13\xEA\x73\x57\x32\xA5\xD8\xB4\x08\x38\x99\x9A\xA8\xCB\x9B\xBC\x33\x81\xAB\xA8\xDE\x1A\xDC\x0D\xAD\xC4\xC6\x4C\x97\x63\x0B\xEB\x7B\x37\xFA\xEF\xE3\xB1\xF8\x27\x61\xB3\x9C\x36\x4B\x5A\xBA\xF4\xBE\x0F\x7C\x09\x9B\xF2\x5A\x59\x55\x6F\xC0\x9B\x63\x1F\xE4\xA7\x72\x17\x64\x94\xDE\x06\x9E\xC3\xA6\x19\x2E\x00\x5E\x04\x7E\x0B\xFC\xAE\x95\xFE\x0F\x7B\xA1\x33\x12\xE3\xB0\xA5\x7D\xD3\x80\xF7\xB6\xFE\x9C\x8E\xED\xBD\xB5\x0B\xB0\x1B\xB0\xD5\xE8\x8B\x9E\xD5\xC3\xD8\xAA\xA7\xE7\x73\x17\x24\x4A\x95\x1B\xF0\x7E\xD8\xBA\xDC\x3D\x73\x17\x64\x84\xDE\xC4\xB6\xA8\x99\x87\xED\x43\xF5\x18\xD6\x60\xFB\x32\x94\x65\x3B\xEC\x3A\xEE\x0F\x1C\x04\x1C\x49\xF9\xB6\xFE\x59\x86\xBD\xF7\xB8\x21\x77\x41\xA4\x7D\xA7\x51\x9E\x05\xF5\xAF\x61\xAB\x9B\xCE\xC6\x36\xB1\x2B\xFA\x97\xEA\xF6\xD8\xF5\xBD\x0A\x78\x96\xFC\xD7\xAF\x9D\xD4\x87\x4D\xC7\xD4\x4A\xA7\x82\x6B\x00\x97\x60\x1F\x58\xEE\x4A\x33\x58\x5A\x07\x3C\x00\x5C\x84\xDD\xD9\x8A\xDE\x60\x87\xB3\x23\xB6\xD3\xC6\x1C\xEC\x39\x3C\xF7\xF5\x1D\x2A\xCD\x41\xAB\x9C\x0A\x6B\x53\xE0\x26\xF2\x57\x92\xC1\xEE\x00\xF7\x00\xE7\x62\xDD\xD2\xAA\xDA\x0C\x5B\x04\x72\x33\xB0\x8A\xFC\xD7\x7D\xA0\xF4\x34\xB6\xCF\xB6\x14\xC8\x54\xE0\x5E\xF2\x57\x8E\x8D\xD3\x8B\xC0\x5F\x62\x2F\x87\xEA\xA6\x0B\x38\x07\xDB\x9D\x32\xF7\xE7\xB0\x71\x5A\x04\x1C\x1C\x17\xBA\x8C\xC4\x74\x8A\xB5\xEC\xAF\x17\xEB\x09\x7C\x18\x3D\x73\xF5\xDB\x0F\x1B\x0D\x58\x4A\xFE\xCF\xA7\x3F\x2D\x03\x8E\x8F\x0C\x5A\x86\xB7\x0F\x76\x0C\x48\xEE\xCA\xD0\x5F\x21\xBE\x8B\xBA\x67\x43\x99\x8C\x8D\xCD\x2E\x24\xFF\xE7\xD5\xC4\xF6\xAD\xFE\x44\x68\xC4\x32\xA8\xFD\x29\xC6\x42\x84\x1E\xE0\xAF\xB1\x2E\xA3\xB4\x67\x3C\x36\xB9\xE6\x39\xF2\x7F\x7E\xBD\xAD\xB2\x48\x42\x07\x62\x0B\xBC\x73\x37\xDC\x4B\xD0\x4E\x11\xA3\x31\x0E\x6B\x3C\xCF\x93\xF7\xB3\x5C\x87\x0D\xE3\x49\x02\x07\x61\x93\x1D\x72\x7D\xD8\x6B\xB0\xE7\xB9\xAD\xA3\x03\xAD\x91\x09\xC0\x79\xE4\xFD\x52\xEE\xC3\x5E\xBA\x49\xA0\x3D\xC8\xDB\x6D\xBE\x8D\xF2\xCD\xEC\x2A\x93\x29\xC0\xB7\xB0\x2F\xC9\x1C\x9F\x6F\x2F\xF0\xF1\xF0\x28\x6B\x6A\x27\xF2\xBD\xFC\x78\x19\x9B\x7D\x24\x69\xEC\x4B\xBE\xF5\xDA\xAB\x81\x13\xE2\x43\xAC\x97\xAD\xC9\x33\x6D\xAF",
"\x0F\xDB\xF1\xA1\xCA\xAB\x98\x8A\xAA\x01\x7C\x9A\x3C\x43\x4F\xCB\x81\xF7\xC7\x87\x58\x0F\x13\xC8\xB3\x8E\xF7\x25\xE0\xD8\xF8\xF0\x64\x18\xDB\x01\xB7\x92\xFE\xF3\x7F\x1D\xD8\x35\x41\x7C\x95\xD6\x00\xFE\x85\xF4\x1F\xDE\xB5\x68\x9F\xA5\x22\x69\x00\x5F\x20\xFD\xF4\xCC\x27\xD1\xDC\xE9\x51\xB9\x88\xB4\x1F\xD8\x32\x34\x26\x58\x64\x07\x92\x7E\xEC\x78\x2E\x36\xDC\x25\x23\x74\x22\x69\xB7\x7A\x7D\x02\xBD\x61\x2E\x83\x2D\xB0\xBD\xAF\x52\x36\xE2\x2B\x92\x44\x56\x21\x3B\x61\xBB\x4C\xA4\xFA\x80\xB4\xCC\xAC\x5C\x1A\xD8\x01\x68\xA9\xBE\xE0\xFB\xD0\x28\x44\xDB\x26\x62\xBB\x51\xA4\xFA\x60\x2E\x45\x8B\x0E\xCA\xEA\xA3\xD8\x63\x4F\x8A\xBA\xB2\x04\xDB\x6A\x48\x86\x31\x8B\x34\x1F\xC8\x5A\xE0\xAC\x44\x31\x49\x9C\x83\xB1\xE5\x81\x29\xEA\xCC\x43\xE8\x6C\xA6\x21\x1D\x47\x9A\xDD\x34\xDE\xC6\x0E\x31\x93\x6A\x98\x01\x3C\x43\x9A\x46\x7C\x59\xA2\x98\x4A\xA7\x0B\x9B\xF1\x14\xFD\x01\x2C\x45\x83\xF4\x55\x34\x0D\x7B\x11\x19\x5D\x7F\x7A\x81\xA3\x12\xC5\x54\x2A\xD7\x13\x7F\xF1\x7B\x80\x23\x52\x05\x24\xC9\x6D\x0D\x3C\x4A\x7C\x3D\x5A\x80\xBD\x0D\x97\x96\x8F\x90\xE6\xCE\x7B\x58\xAA\x80\x24\x9B\xA9\xA4\x69\xC4\xDF\x49\x15\x50\xD1\x6D\x8A\x6D\x58\x1E\x79\xB1\x57\x00\xBF\x9F\x2A\x20\xC9\x6E\x1B\xE2\x9F\x89\xD7\xA1\xDE\x1C\x00\x7F\x47\xEC\x85\x5E\x83\x0D\x37\x48\xBD\xCC\xC0\x4E\xAF\x88\xAC\x5B\x0F\x51\xF3\x59\x5A\xFB\x62\x2F\x05\x22\x2F\xF2\x67\x92\x45\x23\x45\x73\x00\xF1\xE3\xC4\xE7\x25\x8B\xA6\x80\xE6\x12\x7B\x71\xBF\x95\x2E\x14\x29\xA8\x93\x88\xBD\x49\xBC\x49\x4D\x8F\x34\x3D\x89\xD8\xC6\x3B\x07\x18\x9B\x2C\x1A\x29\xB2\xAF\x10\x5B\xD7\xAE\x4C\x17\x4A\x31\x8C\x03\x9E\x22\xEE\x82\xBE\x88\x9D\xBC\x27\x02\x36\x77\xFA\xDF\x89\xAB\x6F\xAB\xB1\xD3\x1C\x6B\xA3\x9B\xB8\x8B\xB9\x0A\x38\x24\x59\x24\x52\x16\x5B\x10\x7B\x00\xC0\x75\xE9\x42\xC9\x6B\x1C\xB1\xDB\x88\x5E\x90\x2E\x14\x29\x99\x83\x89\xDB\x30\xAF\x17\xD8\x2B\x5D\x28\xF9\x9C\x45\x5C\xE3\xBD\x93\xF2\x9F\xF6\x27\xB1\x22\x37\x89\xA8\xFC\x5D\x78\x2C\x30\x9F\x98\x8B\xD7\x83\x1D\x75\x29\x32\x94\xB1\xD8\x49\x91\x51\x77\xE1\x4A\x6F\x0A\x71\x1A\x71\xDF\x7E\x9F\x4B\x18\x87\x94\xDB\x1E\xC4\xED\xAF\xF5\x83\x84\x71\x24\x17\xB5\xD7\xEF\xFD\x68\x51\xBE\x8C\xCC\xA5\xC4\xD4\xC5\x15\xC0\x56\x09\xE3\x48\xE6\x30\x62\x2E\xD8\x5A\x60\xEF\x84\x71\x48\x35\x4C\x22\xEE\x65\xEA\x5F\x24\x8C\x23\x99\xA8\xED\x61\xAF\x4A\x19\x84\x54\xCA\x29\xC4\xD4\xC9\x57\xA8\xD8\x1C\xE9\xC9\xD8\x6E\xF7\xDE\x17\xEA\x2D\x6C\x21\xB7\x48\xA7\xEE\x24\xA6\x11\x57\x6A\xC7\x97\xCF\x13\x73\x91\x2E\x4A\x19\x84\x54\xD2\xA1\xC4\xD4\xCD\x9B\x52\x06\x11\xED\x21\xFC\x2F\xD0\xEB\x68\x57\x04\xF1\x11\x71\x74\xCB\x1A\x6C\x5D\x72\xE9\xED\x45\xCC\x37\xDC\x85\x29\x83\x90\x4A\x8B\xBA\x0B\x57\x62\xA9\xE1\xD7\xF0\xBF\x30\x4B\xD1\xD9\x45\xE2\xEB\x17\xF8\xD7\xD3\x5F\x27\x8D\x20\x48\xC4\x4E\x81\xDF\x4E\x1A\x81\xD4\xC1\x89\xF8\xD7\xD3\x75\xC0\xF6\x29\x83\xF0\xB6\x27\xFE\x17\xA5\x17\x98\x9E\x30\x06\xA9\x87\x06\x31\x4B\x5C\xCF\x8D\x2C\x74\xF4\xEC\xA5\x3F\x0C\xC8\xF3\x76\xEC\xEC\x5E\x11\x4F\x4D\x62\xA6\x41\x7E\x2C\x20\xCF\x64\x22\xC6\xD8\x4E\x49\x1A\x81\xD4\xC9\x54\xFC\xE7\x48\xAF\xC4\x76\x5E\x2D\x9D\xCD\xF0\xBF\x18\x8B\x80\xF1\x29\x83\x90\xDA\xB9\x11\xFF\x9B\xCE\x09\x51\x85\x8D\xEC\x42\x1F\x83\x9D\x34\xE8\xE9\x27\xD8\xDC\x67\x91\x28\xD7\x07\xE4\x79\x7C\x40\x9E\xE1\x2E\xC7\xFF\x9B\xEC\xE8\xA4\x11\x48\x1D\x4D\xC4\x86\x29\x3D\xEB\xED\x43\x49\x23\x70\x72\x37\xFE\xDD\x67\xED\x32\x29\x29\x5C\x87\x6F\xDD\x5D\x0B\x6C\x1E\x51\xD0\xA8\x2E\xF4\x78\xFC\x37\x96\xBB\x1D\x1B\x57\x13\x89\x76\x9B\x73\x7E\xE3\xB0\xD9\x5E\xEE\xA2\x1A\xF0\x01\xF8\xBF\x79\x9B\xEB\x9C\x9F\xC8\x60\xEE\xC0\xEE\x9C\x9E\x8E\x74\xCE\x0F\x88\x6D\xC0\x9E\x9A\xD8\x45\x15\x49\x61\x31\xF0\x88\x73\x9E\x07\x39\xE7\x07\xC4\x35\xE0\xFD\x9C\xF3\x7B\x1A\x5B\x7D\x24\x92\x8A\xF7\x3C\xE6\x90\x5D\x63\xCA\xD2\x80\xEF\x71\xCE\x4F\x64\x38\xF7\x39\xE7\xB7\x1B\xB0\x89\x73\x9E\x61\x0D\x78\x1F\xE7\xFC\xEE\x77\xCE\x4F\x64\x38\xDE\x0D\x78\x2C\xB6\x1B\xA6\xAB\x88\x06\xDC\x85\xFF\xB9\x44\xDE\xCF\x23\x22\xC3\x59\x08\xBC\xE1\x9C\xE7\xAE\xCE\xF9\x85\x34\xE0\xE9\xCE\xF9\xAD\xC3\x9E\x81\x45\x52\x7B\xC2\x39\xBF\xE9\xCE\xF9\x95\xA2\x01\xCF\xC7\x26\x84\x17\xC1\x04\xE0\x0C\xE0\x06\xAC\x5C\x6B\x5B\x69\x7E\xEB\xDF\xCE\x68\xFD\x4C\x2E\x2A\x9F\xAF\xC2\x37\xE0\x08\x17\xE0\x3B",
"\x8B\x65\x4E\xDA\xE2\x0F\xEA\x34\xAC\x5B\x35\x5C\x79\x17\xB6\x7E\x56\xE5\x2B\x57\xF9\x06\xE2\x5D\x97\x6F\x4D\x5B\xFC\xCE\x5C\x86\x6F\xD0\xDF\x4F\x5B\xFC\x77\x19\x03\xCC\x62\xE4\xE5\x9E\x45\x9A\xD3\x22\x54\xBE\x38\xDE\xFB\x46\x3F\x98\xB6\xF8\x9D\xF9\x11\xBE\x41\x7F\x39\x6D\xF1\xDF\xA5\x93\xCA\xB7\x61\x25\x54\xF9\x8A\x5D\xBE\xA1\x1C\x48\xE7\x65\x1F\x28\xBD\x90\xB6\xF8\x9D\xF1\x3E\x09\xFD\xCC\xB4\xC5\x7F\x07\x8F\xC3\xD8\x22\xBB\x83\x2A\x5F\xAC\x1D\x86\x28\x57\x27\xA9\x27\x6D\xF1\x3B\xF3\x2B\x7C\x83\xCE\xB5\xC3\xFD\x04\xEC\x1B\x73\xB4\xE5\x7F\x09\xFF\x75\xD1\x2A\x5F\x1A\x9B\xB4\x51\xBE\x91\xA4\x3E\x9C\x8F\x5C\x89\x78\xC6\xF0\x9E\x6D\xE2\x3D\x16\xD7\xAE\x53\x81\x19\x0E\xF9\xEC\x0C\xCC\x74\xC8\x67\x63\x2A\x5F\xBC\x95\xF8\x8E\x80\x34\x70\x5E\xE4\x13\xD1\x80\xBD\xBF\x2D\x57\x38\xE7\xD7\x2E\xCF\xBD\xB7\x4E\x75\xCC\xAB\x9F\xCA\x97\x86\x77\xFD\x73\xDD\x12\xAA\x0C\x0D\x78\x8D\x73\x7E\xED\xF2\x5C\xBF\x19\xB1\x16\x54\xE5\x4B\x63\xB5\x73\x7E\xAE\xED\x23\xA2\x01\x7B\x6F\x3A\x97\x6B\x0F\xAC\xED\x0A\x9A\x57\x44\x9E\x75\x2C\x5F\xBB\xBC\x6F\x20\xAE\x13\x55\x22\x1A\x70\x9F\x73\x7E\x0D\xE7\xFC\x72\xFC\xDE\x88\x18\x54\xBE\x34\xBC\xDB\x88\x6B\xFB\x88\x68\xC0\xDE\x77\xCC\x5C\x53\xEB\x5E\x2B\x68\x5E\x11\x79\xD6\xB1\x7C\xED\xF2\x7E\x24\x74\xED\x92\x47\x34\xE0\x42\x77\x39\x46\xE0\xE1\x82\xE6\x15\x91\x67\x1D\xCB\xD7\x2E\xEF\xFA\xE7\xDA\x3E\x22\x1A\xB0\xF7\x43\xFF\x64\xE7\xFC\xDA\xF5\x53\xC7\xBC\xFE\xC3\x31\xAF\x7E\x2A\x5F\xBC\x06\xFE\x67\x50\xE7\x7A\x29\xDB\xB6\xB9\xF8\x0E\x7E\xE7\x3A\x4A\x65\x33\x6C\x2B\xDB\xD1\x96\x7F\x51\x2B\x2F\x95\xAF\x58\xE5\x6B\xC7\x94\x36\xCB\xD8\x6E\x5A\x83\xF3\xF3\x7C\xC4\x1D\xD8\x7B\xE2\xC5\x54\xE7\xFC\xDA\xB5\x1C\xB8\xD8\x21\x9F\x8B\x5B\x79\x79\x53\xF9\xE2\x79\x6F\x4C\xB1\x04\x6B\xC8\x85\xF6\x3D\x7C\xBF\xB5\x2E\x49\x5A\xFA\x77\xFB\x31\x9D\x97\xFD\xC7\x2A\x5F\xE1\xCB\x37\x94\x0F\xD2\x79\xD9\x07\x4A\x4F\xA6\x2D\x7E\x67\x2E\xC1\x37\xE8\x6B\x53\x16\x7E\x00\x13\x80\xD9\x8C\xBC\xDC\xB3\x49\xF3\x02\x4E\xE5\x8B\x73\x26\xBE\x75\xD9\x7B\xA7\xCB\x10\xE7\xE0\x1B\xF4\x5D\x69\x8B\x3F\xA0\x06\xF0\x05\xDA\x3B\x33\x67\x69\xEB\x67\x53\x8E\x5D\xAA\x7C\x31\xFE\x0A\xDF\xBA\x7C\x43\xDA\xE2\x77\xE6\x78\x7C\x83\x5E\x94\xB6\xF8\x43\xEA\x02\xBE\x88\x7D\x93\xAE\x60\x7D\x19\x57\xB4\xFE\xED\x8B\xAD\x9F\xC9\x45\xE5\xF3\x35\x9A\xEE\xFF\x40\xE9\x9B\x69\x8B\xDF\x99\xDD\xF1\x0D\xBA\x09\x6C\x9D\x34\x82\xF6\x75\x51\xAC\x0A\xB7\x31\x95\x6F\x74\x9E\xC0\xB7\x1E\x7F\x36\x6D\xF1\x3B\x33\x09\xDB\x49\xD2\x33\xF0\x63\x93\x46\x20\x62\xCF\xDF\x6B\xF0\xAD\xC7\x1F\xF6\x2E\x64\xC4\x30\xD2\x2A\x6C\x11\xB6\xA7\x9C\xAB\x51\xA4\x9E\xF6\xC7\x7F\x61\xCE\x33\xCE\xF9\x85\x6D\x1A\xE6\xBD\x1D\x67\xC8\xC9\x6E\x22\x43\xF8\x80\x73\x7E\x4B\xB1\x1D\x37\x5D\x45\x35\xE0\xC7\x9C\xF3\x3B\x92\x62\xBC\x95\x94\xFA\x38\xC2\x39\xBF\x27\xB1\x6E\xB4\xAB\xB2\xDC\x81\xB7\xC1\xFF\xBC\x25\x91\xC1\x34\x80\x63\x9C\xF3\x7C\xDC\x39\x3F\x20\xAE\x01\xCF\x0B\xC8\xD3\xFD\x05\x80\xC8\x20\x0E\x04\xA6\x39\xE7\x19\xB2\x27\x74\x54\x03\x7E\x11\xFF\xF1\xDB\x13\x9C\xF3\x13\x19\x4C\xC4\xCD\xC2\xFB\xB4\xC3\x70\x37\xE1\xFB\x0A\x7E\x0D\xFE\x93\xCB\x45\x06\x72\x3F\xBE\x75\xF7\x4D\x82\x6E\x96\x91\x47\x57\xDC\xEB\x9C\xDF\x78\xE0\x64\xE7\x3C\x45\x36\xB6\x33\x70\x98\x73\x9E\xF7\xE2\xBF\xD5\x14\x10\xDB\x80\x7F\x19\x90\xE7\xE9\x01\x79\x8A\x6C\xE8\x74\xFC\x47\x3C\xEE\x72\xCE\x2F\x89\x06\xF0\x2A\xBE\x5D\x91\xB5\xC0\xF6\x29\x83\x90\xDA\x79\x04\xDF\x3A\xDB\x04\xF6\x4E\x1A\x81\xA3\x7F\xC6\xFF\x62\x5C\x98\x34\x02\xA9\x93\xC3\xF1\xAF\xAF\x2F\x47\x16\x38\xFA\xF8\xC6\xDB\x03\xF2\x3C\x9B\xFC\xC7\x4E\x4A\x35\x9D\x1D\x90\xE7\xDC\x80\x3C\x93\xD9\x02\x3B\x5B\xC6\xFB\x5B\xED\xA3\x29\x83\x90\x5A\x78\x0F\xF0\x36\xFE\x75\x35\xD7\xE1\x7C\x6E\x7E\x8A\xFF\x45\xF9\x55\xCA\x00\xA4\x16\x2E\xC6\xBF\x9E\x2E\x21\xFF\xAE\x22\xA3\xF6\x27\xF8\x5F\x98\x26\x70\x70\xCA\x20\xA4\xD2\x26\xE2\xFF\xC2\xB5\x09\x5C\x93\x32\x88\x28\x5B\x12\xD3\x8D\xF6\xDC\x77\x58\xEA\xED\x5C\x62\x6E\x32\x27\xA6\x0C\x22\xD2\xBF\x12\x73\x81\xBC\x07\xDC\xA5\x7E\x26\x01\xAF\xE0\x5F\x37\x5F\xC5\xF9\x30\xEF\x9C\x8E\x21\xA6\x01\xFF\x3C\x61\x0C\x52\x4D\x7F\x46\x4C\xDD\xFC\x7A\xCA\x20\xA2\x35\x80\xE7\x88\xB9\x50\x5A\xE4\x20\x9D\xEA\x02\x5E\xC7\xBF\x4E\xF6\x01\xBB\x24\x8C\x23\x89\xAF\x10\xD3",
"\x80\x9F\xA4\x42\x5D\x15\x49\xCA\xFB\x10\x82\xFE\x74\x47\xCA\x20\x52\xE9\x22\x66\x9C\xAD\x09\x9C\x9F\x30\x0E\xA9\x86\x7D\xB0\xA9\xB9\x11\xF5\xB1\xF4\x63\xBF\x83\x89\xFA\xC6\x7B\x1B\x98\x91\x30\x0E\x29\xB7\x31\xC0\x3D\xC4\xD4\xC5\x67\xA8\xF0\x4C\xC1\x19\x40\x2F\x31\x17\xEE\xB6\x84\x71\x48\xB9\x9D\x4F\x4C\x1D\x6C\x62\x27\x93\x54\x5A\x27\xE7\xE4\xB4\x9B\x3E\x91\x30\x0E\x29\xA7\x5D\x80\x65\xC4\xD4\xBF\x57\xB1\x61\xA9\x4A\xDB\x1B\xFF\x8D\xDF\xFB\xD3\x4B\xD8\xAC\x1A\x91\x81\x8C\xC3\x16\xD7\x47\xDD\x40\xCE\x4B\x17\x4A\x5E\xD7\x11\x77\x11\xCF\x48\x18\x87\x94\xCB\x25\xC4\xD5\xBB\x97\xA9\xC1\xDD\xB7\xDF\xEE\xC4\xBD\x01\xBC\x31\x61\x1C\x52\x1E\xC7\x12\xF7\xFE\xA5\x09\x7C\x3E\x5D\x28\xC5\xF0\x23\x62\x2E\xE4\x0B\x29\x83\x90\x52\xD8\x11\x58\x4C\x5C\xE3\x7D\x9E\x0A\xAC\x3A\x1A\xA9\x69\xB4\x77\x5E\xEC\x48\xD3\x8A\x94\x41\x48\xE1\x4D\xC2\x7F\x97\xC9\x8D\x53\x6D\x37\x5B\xFC\x32\xFE\x17\x73\x79\xD2\x08\xA4\xC8\x1A\xC4\x2D\xA4\xE9\x4F\x11\x9B\x37\x96\xC6\x34\xD4\x85\x96\x38\x97\x13\xDB\x78\xD7\x02\xFB\x26\x8B\xA6\x80\xBA\xF1\xBF\xA8\xB3\x53\x06\x20\x85\x15\xB5\xC6\x77\xC3\x74\x45\xB2\x68\x0A\x6A\x0E\xFE\x17\xB5\x3B\x65\x00\x52\x48\xDD\xD8\x8A\xA0\xC8\xC6\xBB\x00\xD8\x34\x51\x3C\x85\xD4\x05\xAC\xC6\xF7\xA2\xAE\x6E\xE5\x2B\xF5\x75\x3A\xB1\xC3\x45\x4D\xEC\xCB\xE1\x43\xA9\x02\x2A\xAA\x6E\xFC\x2F\xEC\x9C\x94\x01\x48\xE1\x7C\x92\xB8\xF9\x05\x1B\xA6\x7F\x4A\x15\x50\x91\xA9\xFB\x2C\x9E\x3E\x4D\xDC\x14\xDD\x0D\xD3\x7C\x6C\xBB\xE4\x5A\x53\xF7\x59\x3C\x7D\x95\xF8\x67\xDE\x26\x76\x77\x3F\x22\x51\x4C\x85\xD6\x8D\xFF\xC5\x55\xF7\xB9\x7E\xC6\x02\x7F\x4F\x7C\xC3\xED\x4F\x5F\x4B\x13\x56\xF1\xA9\xFB\x2C\xA3\xB5\x25\x70\x0B\xE9\x1A\xEF\x1D\xD8\x17\x46\xED\x4D\xC1\xBF\xFB\xAC\xC3\xBF\xEB\x65\x77\x6C\x2F\xB4\x54\x8D\x77\x21\xB0\x75\x92\xC8\x4A\xA0\x1B\xFF\x0B\xAC\xEE\x73\x7D\x9C\x4A\xCC\x1C\xFA\xC1\xD2\x2A\xE0\xD0\x24\x91\x95\x84\xBA\xCF\xD2\x89\x49\xC0\x55\xA4\x6B\xB8\xFD\x29\xE2\xC4\xC2\xD2\xD2\xDB\x67\xE9\xC4\xBE\xC0\x63\xA4\x6F\xBC\xDF\x4C\x11\x5C\x99\x9C\x85\xFF\x45\xBE\x35\x69\x04\x92\xD2\x38\x6C\x88\x68\x15\xE9\x1B\xEF\x6C\x2A\xBC\xBB\x64\xA7\xD4\x7D\x96\x76\x1D\x0C\xFC\x2F\xE9\x1B\x6E\x13\xF8\x35\x35\xDA\x1E\xA7\x5D\x7A\xFB\x2C\xED\x98\x02\xCC\x22\x7E\x3E\xF3\x60\xE9\x11\xF4\x48\x36\xA0\x6E\xFC\x2F\xB6\xDE\x3E\x57\xC7\x38\xE0\x73\xC0\x6B\xE4\x69\xB8\x4D\xE0\x09\x60\xAB\xE8\x40\xCB\x4A\xDD\x67\x19\x48\x03\x1B\x1A\x7A\x86\x7C\x0D\xB7\x89\xED\x6B\xB5\x5D\x70\xAC\xA5\x55\xD6\xB7\xCF\x93\x81\xE3\x80\x8B\xB0\x03\xC5\xE7\x63\xF3\x61\xD7\xB6\xFE\x7E\x03\xB6\x8D\x6D\xED\x36\x34\x73\xD0\x00\x3E\x06\x3C\x48\xDE\x86\xDB\x04\x9E\x06\x76\x88\x0D\xB7\xDC\xBA\xF1\xBF\xE8\xDE\xDD\xE7\xF1\xC0\x21\xD8\xF6\xA0\xD7\x02\x4F\xD1\xFE\xEA\x96\xDF\x01\x17\xA2\x67\xA7\x76\x8C\x03\x3E\x0E\x3C\x4C\xFE\x86\xDB\x04\x1E\xC5\xB6\x76\x92\x21\x14\xB1\xFB\xBC\x2B\xB6\x7E\xF4\x3B\xD8\x6E\xFD\x2B\x1D\xCA\xB4\x0C\xB8\x12\xD8\x6D\x94\x65\xAB\xA2\xC9\xC0\x97\xB0\xD3\x33\x72\x37\xDA\xFE\x34\x0F\xBD\x04\x1D\x56\x11\xBA\xCF\x5B\x01\x27\x61\x3B\xF3\xDF\x46\xCC\xA1\xCE\x1B\xA6\x3E\x6C\xF2\xFB\xA9\xD8\x9D\xBD\xCE\x8E\xC4\x16\xC0\x47\x1D\x2D\xDB\x69\xFA\x39\x5A\xD7\xDB\x96\x6E\xFC\x2F\xFE\x50\xDD\xE7\x49\x58\xA5\x39\x1F\x3B\xC2\x65\x7E\xC0\xEF\x1F\x49\x5A\x8C\x1D\xAB\x5A\xA7\x75\xA4\x33\xB0\x47\x8A\xC7\xC9\xDF\x50\x07\x4A\x57\xA3\x43\xE1\xDB\x16\xD9\x7D\x1E\x03\xEC\x05\x7C\x0A\x9B\x27\xFB\x3F\xD8\xD8\x70\xEE\x0A\x32\x58\x9A\x0F\xFC\x2D\xF0\x7E\xAA\x37\xCB\x67\x0F\x6C\x9F\xEF\xFB\x49\xB3\xB8\xBE\x93\xD4\x87\xBD\x90\x94\x36\x45\x74\x9F\x9B\xD8\x22\xEE\x3B\x81\x9E\x80\xBC\x53\xA5\x45\xC0\x35\xC0\x1F\x03\xDB\x76\x7A\x81\x33\xDA\x1C\x7B\x2C\xF9\x36\xF0\x2C\xF9\xAF\xE7\x70\x69\x29\x30\x33\xE4\x4A\x64\xD4\x08\xCE\xBF\x1B\xAB\xA4\x32\xB4\x26\xB6\xBE\xF5\x1E\xE0\xBE\x56\x7A\x2E\x6B\x89\xDE\x6D\x3B\xE0\x70\xEC\xF1\xE4\x03\xAD\xBF\x97\xA5\x1B\xFA\x2C\x70\x0A\x36\x5C\x54\x29\xD1\x0D\x78\x0E\xF6\x2D\x2D\x23\xD7\x83\x0D\x71\x3C\xD6\x4A\xCF\x61\x7B\x11\xFF\x36\xF8\xF7\x4E\xC5\x0E\xC1\xDE\x1D\x5B\x05\xD4\x9F\xDE\x1B\xFC\x7B\xA3\xDC\x8C\xDD\x48\xDE\xCA\x5C\x8E\x10\x91\x0D\xB8\x0B\xEB\x26\x6A\x92\x83\xAF\x15\xC0\x8B\xD8\xD8\xF3\xAB\xAD\xB4\x04\x6B\xF0\x3D\x58\x57\xB1\x7F\xFC\xBA\xA7\xF5\xFF\xD9\x82\xF5\x77\xCB\x2E\x6C",
"\x48\x67\x72\xEB\xEF\x3B\x00\xDB\xB4\xFE\xDC\x19\x9B\x8B\x5C\x05\x2B\x81\x3F\x07\xFE\x21\x77\x41\xCA\xAA\x9B\xFC\xCF\x3D\x4A\xF5\x4C\x4F\x00\xFB\x50\x03\x91\x6F\x42\x4F\x0F\xCC\x5B\x64\x20\xEB\xB0\x97\x6A\x87\x62\x8D\xB8\xF2\xA2\xBA\xD0\xEA\x3E\x4B\x6A\x4F\x03\x7F\x8A\x0D\x63\xD5\x46\xD4\x1D\xF8\x64\xD4\x78\x25\x8D\xD5\xC0\xD7\x81\x83\xA8\x59\xE3\x85\xB8\x61\x00\x75\x9F\x25\x85\x3B\xB0\x63\x44\x8B\x36\xE4\x96\x4C\x44\x17\x5A\xDD\x67\x89\xB6\x10\x9B\xF5\x55\xFB\xB3\xA0\x23\xEE\xC0\xEA\x3E\x4B\x94\x25\xC0\xE5\xC0\x77\xB1\x8D\xEE\x6A\x2F\xA2\x01\x6B\xE2\x86\x78\x5B\x89\x4D\x9F\xBD\x0C\x78\x33\x73\x59\x0A\x25\xA2\x01\x1F\x12\x90\xA7\xD4\xD3\x0A\xE0\x07\xC0\x15\xD8\x63\x99\x6C\x24\xE2\x19\x78\x05\xB0\x49\x40\xBE\x52\x1F\x4B\x81\x1F\x62\x63\xBA\x8B\x33\x97\xA5\xD0\xCA\x32\x19\x3D\xB7\xE5\xC0\x43\xD8\xFE\x4D\x87\x03\x47\xE5\x2D\x4E\x65\x2D\xC0\x9E\x6F\xAF\xC1\x76\x37\x91\x0C\x5E\x20\xFF\x54\xBA\xD1\xA4\x5E\x6C\x11\xC1\xD5\xC0\x39\xC0\x7E\xBC\xFB\x58\xC9\x03\xB0\xAE\xDD\xB2\x02\x94\xB7\xEC\x69\x1D\xB6\x3B\xC6\x4C\xAA\xB7\x46\xBA\x94\x6E\x24\x7F\xA5\x18\x49\x5A\x08\xFC\x1B\xB6\x5F\xD3\xD1\xD8\x3A\xD7\x76\x6D\x89\x6D\x82\x57\x84\x9D\x15\xCB\x96\x5E\x01\xFE\x06\x5B\x40\x21\x05\x72\x06\xF9\x2B\xC7\x60\xA9\x07\xDB\x08\xE0\x1B\xD8\x70\x97\xE7\x3E\xC0\x7B\x02\x97\x52\xFE\x1E\x48\x64\x7A\x03\xEB\xD9\x1C\x8B\x0E\xCB\x76\x11\xF1\x12\x6B\x22\xB6\x80\x3A\xF7\x37\xEB\x5A\x6C\x1D\xED\x03\xD8\xEE\x83\xF3\xB0\x72\xF5\x05\xFF\xDE\x06\xF6\x9C\x3C\xB3\x95\xF6\x08\xFE\x7D\x45\xB7\x18\x3B\x80\xEE\x66\xE0\x17\xD8\x96\x47\xE2\x24\x6A\x31\xC3\x69\xC0\x4F\x82\xF2\x1E\xCC\x02\xDE\xD9\x58\x1F\xA6\x18\x83\xFD\x7B\x61\x1B\x98\x7F\x08\xDB\xC9\xA2\xEA\x87\x66\xF5\x61\xEF\x10\xE6\x02\x3F\xC3\x3E\x93\xE8\x2F\xCD\xDA\x8A\x5C\xD0\x3F\x0B\x38\x2F\x28\xEF\x37\x58\xDF\x50\xFB\xD3\xEB\x41\xBF\xCB\xD3\x26\xC0\x07\xB1\xD3\x1E\x8E\xC2\x26\xE0\x4F\xCC\x5A\xA2\xD1\xEB\xC3\x8E\x45\xB9\x1B\xF8\x4F\xE0\x2E\xEC\xF3\x91\x04\x22\x1B\xF0\x18\x6C\x93\xF3\xD1\x36\xE2\x55\xD8\xDD\x74\xC3\xC6\x3A\x7F\x94\x79\x16\xC5\x44\xEC\x18\xCD\x23\x80\xC3\x80\xFD\xB1\x4D\xE1\x8B\xFC\x7C\xB8\x10\xDB\x2E\x76\x1E\xB6\xFA\xE7\x01\x6C\xDC\x56\x32\x88\xDE\x13\x0B\xAC\x3B\x7D\x25\xB0\x63\x1B\x3F\xDB\x87\x3D\xA7\x6E\xD8\x58\x1F\xC5\x9E\x67\xEB\x62\x13\x60\x6F\x6C\xF8\x6A\x37\xEC\x04\x89\x5D\xB1\x7D\xAA\x52\x6D\x44\xBE\x0A\x7B\x24\xE9\x4F\xCF\x63\x0B\xE4\x1F\x67\xFD\x36\x3D\x52\x00\x29\x1A\x30\xD8\xE2\x86\x53\xB1\x97\x3A\x87\xB0\xFE\x05\xD7\x6F\xB0\xDD\x18\xE7\x61\xDF\xE4\x0F\xA2\x6F\xF3\xA1\x74\x61\x6F\xCE\xB7\x6F\xFD\x39\x8D\xF5\xFB\x5B\x4D\xC1\x86\xB5\x36\x6B\xFD\xEC\x98\xD6\xBF\x83\x6D\xE8\xB6\xAE\xF5\xF7\x95\xAD\xFF\xBD\xB4\x95\x7A\xB0\x23\x3D\x5F\xC3\x36\xCC\x5B\xDC\x4A\xCD\xD8\x50\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x04\xFE\x1F\x5E\x25\x15\x9E\xA9\x3B\xF3\x73\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82\x03\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x51\x75\x65\x73\x74\x69\x6F\x6E\x33\x16\x00\x00\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\xF0\x00\x00\x00\xF0\x08\x06\x00\x00\x00\x3E\x55\xE9\x92\x00\x00\x00\x06\x62\x4B\x47\x44\x00\xFF\x00\xFF\x00\xFF\xA0\xBD\xA7\x93\x00\x00\x15\xE8\x49\x44\x41\x54\x78\x9C\xED\x9D\x79\x94\x5E\x55\x91\xC0\x7F\xDD\xE9\x74\x27\x24\x99\x24\x24\x24\x01\x04\x12\xC2\xA2\xC8\x8E\x80\x4A\x10\xC4\x1C\x81\x19\x40\x90\x55\x87\x51\x30\x80\x30\xB8\xB0\x88\xCC\xA8\xA3\xEC\xA2\x28\x43\x10\x8F\xE0\x20\x8B\x23\xBB\x38\x32\x80\x30\x38\x20\x83\x10\x43\x34\x10\x02\x61\x4B\x48\x37\xCB\x91\x25\x1B\x09\xD9\x3B\xC9\x37\x7F\xD4\xD7\xA6\xE9\x74\x7A\xFB\xAA\xEA\xBE\xA5\x7E\xE7\xD4\x49\x0E\xC6\xFB\xDD\xAA\x5B\xF5\xDE\x7D\xF7\xD6\xAD\x0B\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x90\x96\xBA\xD4\x1D\x08\x7A\xCC\x08\x60\x6C\x55\xB6\x01\x36\xAF\xFE\xB7\x11\xC0\xC8\xEA\x9F",
"\x4D\xC0\xD0\xEA\xBF\x6F\x04\x06\x55\xFF\xBE\x0C\x58\x5D\xFD\xFB\xBB\xC0\x2A\x60\x41\x07\x79\x13\x68\x69\x27\x0B\xAD\x14\x09\xF4\x88\x00\xCE\x1E\xA3\x80\x5D\xAB\xB2\x4B\xF5\xCF\xED\x81\x21\xCE\xFD\x58\x02\xCC\x06\x9E\xAD\xCA\xCC\xAA\xBC\xE3\xDC\x8F\xA0\x0B\x22\x80\xD3\xD2\x0F\xF8\x20\xB0\x1F\x30\xA1\x2A\xE3\x92\xF6\xA8\x7B\xDE\x04\xA6\x03\x8F\x03\x4F\x00\xD3\x58\xFF\x76\x0F\x9C\x89\x00\xF6\x67\x07\xE0\x50\xE0\x10\x60\x7F\xD6\x4F\x73\xF3\xCA\x52\xE0\x31\xE0\x01\xE0\x41\x60\x4E\xDA\xEE\x04\x81\x2E\xFD\x80\x4F\x02\xD7\x20\xCE\x5D\x29\xB8\xCC\x06\xAE\x06\x0E\x00\xEA\x15\xEC\x17\x04\xEE\xD4\x23\xD3\xE1\xC9\xC0\x5F\x49\x1F\x54\xA9\x64\x1E\xF0\x4B\x60\x22\x11\xCC\x41\x0E\xD8\x1A\xB8\x00\x78\x8D\xF4\xC1\x93\x35\x79\x15\xF8\x1E\xF0\x81\xBE\x1A\x37\x08\x2C\x68\x00\x8E\x02\xEE\x07\xD6\x92\x3E\x50\xB2\x2E\x6B\x80\xFB\x80\x23\x91\xCF\x8B\x20\x48\xC2\x60\xE0\x34\xE0\x25\xD2\x07\x45\x5E\xA5\x19\x38\x1F\x18\xD6\x4B\xDB\x07\x41\x9F\xD9\x12\xF8\x01\xB0\x88\xF4\x01\x50\x14\x59\x04\x5C\x8E\x24\xA7\x04\x81\x09\x9B\x21\x4E\xB6\x9C\xF4\x0E\x5F\x54\x59\x05\x5C\x47\x04\x72\xA0\xC8\x08\x64\x61\x6A\x09\xE9\x1D\xBC\x2C\xB2\x0C\x59\xC1\x1F\xDD\xFD\xF0\x04\x41\xE7\x34\x01\xDF\x04\x16\x93\xDE\xA1\xCB\x2A\xEF\x02\xDF\x40\xF2\xBA\x83\xA0\xC7\x1C\x4E\x39\x92\x2E\xF2\x22\xB3\x81\x63\xBB\x1C\xB1\x20\x00\x76\x04\x1E\x26\xBD\xC3\x86\x74\x2E\xFF\x83\x1C\xEC\x08\x82\xF7\xD1\x80\x6C\x67\xAC\x20\xBD\x93\x86\x74\x2D\x2B\x90\x35\x89\x98\x56\x07\x00\xEC\x0E\xFC\x85\xF4\x8E\x19\xD2\x3B\x79\x06\xD8\xA7\x93\xF1\x0C\x4A\x42\x7F\xE0\x12\x24\x33\x28\xB5\x33\x86\xF4\x4D\x5A\x81\x0B\x91\x19\x54\x50\x22\xC6\x21\xE7\x59\x53\x3B\x60\x88\x8E\x3C\x49\x7C\x1B\x97\x86\x49\xC0\x7B\xA4\x77\xBA\x10\x5D\x59\x02\x9C\x44\xC9\x28\xD3\x81\xFE\x81\xC0\xCF\x80\x2F\xA6\xEE\x48\x0D\xAC\x00\x5E\x41\x6A\x56\x35\x57\xFF\x7C\x9B\xF5\x75\xAD\xE6\x23\x7B\xA7\x20\x55\x32\x96\x55\xFF\x3E\x88\xF5\x8B\x3E\xC3\x58\x5F\x43\x6B\x04\x92\x2C\x31\x0E\xA9\xB5\x35\x0E\xD8\x16\xB1\x55\x5E\xB9\x01\x38\x13\x58\x99\xBA\x23\x1E\x94\x25\x80\xC7\x01\x77\x03\x7B\xA4\xEE\x48\x2F\x58\x08\x4C\x01\x9E\x42\x6A\x52\x3D\x83\x04\xEF\x3A\xE3\xDF\xED\x07\x8C\x07\x76\x43\x6A\x72\xED\x09\x7C\x1C\x18\x6E\xFC\xBB\x9A\x4C\x07\x8E\x46\x8E\x30\x06\x39\xE7\x60\xE4\xCD\x94\x7A\x8A\xD7\x9D\xCC\x03\x6E\x05\x4E\x01\x76\x22\x5B\x0F\xD7\x3A\xA4\x4F\xA7\x02\xB7\x91\x1F\x7B\x4E\xB4\x30\x46\xE0\xC7\x19\x64\x7B\x95\x79\x26\xB2\x8A\xBA\x2F\xF9\x3A\x1B\xDB\x0F\xF8\x28\x70\x11\x32\x3B\x48\x6D\xC7\x8D\x49\x2B\x72\xE4\x33\xC8\x19\xF5\xC0\x15\xA4\x77\xA0\xCE\xE4\x79\xE0\xBB\x48\x35\xCA\xA2\xB0\x13\x92\x5C\xF1\x02\xE9\xED\xDB\x99\x5C\x4E\xB6\x66\x34\x41\x17\x0C\x04\x7E\x4D\x7A\xA7\x69\x2F\xCB\x80\x9B\x90\x6F\xC9\xA2\x33\x01\xB8\x99\xEC\x1D\xBB\xBC\x03\x18\x60\xA8\x77\xA0\xC0\x10\xE0\xFF\x48\xEF\x2C\x6D\xD2\x0C\x9C\xC5\xFA\xDB\x12\xCA\xC4\x30\xE0\x1C\x64\xA5\x3C\xF5\x38\xB4\xC9\x23\x48\x25\x95\x20\x83\x0C\x07\xA6\x92\xDE\x49\x2A\x48\xB1\xF3\xE3\xC8\xD7\x77\xAD\x15\x0D\xC0\x09\x64\x27\x5D\x75\x0A\x51\xC2\x27\x73\x8C\x02\x9E\x26\xBD\x73\xCC\x44\x8E\xBD\xC5\xF7\x56\xE7\x4C\x04\xFE\x4C\xFA\x71\x7A\x0A\xA9\xB0\x12\x64\x80\xCD\x80\x59\xA4\x75\x88\x59\x48\x95\xC5\x08\xDC\xEE\xA9\x03\x3E\x4B\xFA\x05\xAF\x67\x91\x84\x96\x20\x21\x43\x49\x3B\x35\x5B\x88\x1C\x43\x8C\xA3\x6D\xBD\xA7\x01\xD9\xE2\x99\x47\xBA\xF1\x9B\x01\x6C\x6A\xAD\x68\xD0\x39\x43\x48\xF7\xCD\xBB\x16\xB9\x2A\x25\x06\xBF\x76\x46\x02\xD7\x22\x19\x66\x29\xC6\x72\x0A\xB1\xB0\xE5\xCE\x40\xE0\x51\xD2\x0C\xF8\x2C\xCA\xB1\x1D\xE4\xCD\x04\xD2\x4D\xAB\x1F\x26\xB6\x98\xDC\xA8\x27\xCD\x3E\x6F\xDB\xD9\xD3\x26\x7B\x15\x4B\x4B\x13\x72\x46\xBB\x15\xFF\xF1\xBD\x9D\x58\xC3\x70\xE1\x47\xF8\x0F\x6E\x33\x72\x87\x6F\xE0\xC3\x3E\x48\x21\x3B\xEF\x71\xBE\xCC\x43\xB9\x32\x73\x06\xFE\x83\x7A\x3D\xF1\x8D\x94\x82\x21\x48\xF6\x9A\xF7\x78\x9F\xEA\xA0\x5B\x29\x39\x18\xDF\x83\x09\xCB\x81\x2F\xB8\x68\x16\x74\xC5\x97\xF0\x2D\x36\xD8\x0A\x7C\xCA\x45\xB3\x12\xB1\x0D\xBE\xDB\x0D\xAF\x01\x7B\xBB\x68\x16\xF4\x84\x3D\x80\xB9\xF8\x8D\xFF\x02\xE4\x0C\x79\xA0\xC0\x40\x24\x73\xC6\x6B\xF0\x1E\x25\xB6\x87\xB2\xC8\x48\xE0\x8F\xF8\xF9\xC1\x34\x62\x65\x5A\x85\x1B\xF0\x1B\xB4\x38\xB1\x92\x6D\x9A\x80\x5F\xE1\xE7\x0F\xBF\xF4\x51\xAB\xB8\x4C\xC2\x6F\xB0",
"\x2E\x22\xB6\x11\xF2\x40\x1D\xB2\x5A\xEC\xE5\x17\xB1\x0E\xD2\x47\xC6\xE3\x73\x23\xE0\x3A\xE4\xD8\x5B\x90\x2F\xCE\xC4\x27\x7B\xEB\x3D\xA2\x64\x6D\xAF\x69\x00\xFE\x84\x4F\xF0\x7E\xD5\x49\xA7\x40\x9F\xD3\x90\xB4\x56\x6B\x3F\x99\x86\x5C\x04\x10\xF4\x90\x8B\xB1\x1F\x94\xB5\xE4\xBB\xC4\x6C\x20\x9C\x84\x4F\x10\x5F\xE0\xA3\x4E\xFE\xD9\x1B\xFB\xFD\xDE\x75\xC0\x97\xBD\x14\x0A\xCC\x39\x03\xFB\xE9\x74\x2B\xB0\x97\x97\x42\x79\xA5\x01\x9F\x2D\xA3\xF3\xBC\x14\x0A\xDC\x38\x0B\x7B\xBF\x79\x86\x98\x4A\x77\xC9\xB7\xB1\x1F\x84\x8B\xDC\xB4\x09\xBC\xB9\x1C\x7B\xFF\x39\xDF\x4D\x9B\x9C\xB1\x03\xF6\x29\x73\xB7\x11\x5B\x45\x45\xA6\x0E\xF8\x4F\x6C\x7D\x68\x39\xB0\x9D\x97\x42\x79\xE2\x61\x6C\x0D\xFF\x28\x51\x39\xA3\x0C\x0C\xC0\x3E\x63\xEB\x41\x37\x6D\x72\xC2\x51\xD8\x1A\x7C\x2E\x91\x1E\x59\x26\x46\x22\xF7\x22\x59\xFA\xD4\x61\x6E\xDA\x64\x9C\x46\xE0\x65\xEC\x0C\xBD\x82\x58\x3D\x2C\x23\xBB\x63\x5B\x5C\x7E\x0E\x51\xDC\x01\x80\x7F\xC1\xF6\x49\x79\xB2\x9F\x2A\x41\xC6\xF8\x27\x6C\x7D\xAB\xF4\x19\x7C\x23\x81\xC5\xD8\x19\xF8\x17\x7E\xAA\x04\x19\xE5\x66\xEC\xFC\x6B\x11\x25\xFF\x34\xB3\xBC\x80\x6C\x0E\x52\xD5\x21\x28\x37\x83\xB1\xFD\x44\xBB\xD4\x4F\x95\x6C\x31\x06\xB9\xF4\xCB\xC2\xA8\xAD\xC8\xF5\x97\x41\x00\x92\xDD\xB7\x1A\x1B\x5F\x5B\x8A\xDC\x0C\x52\x3A\xAE\xC2\xEE\xA9\x78\x81\x9F\x1A\x41\x4E\xB8\x04\x3B\x7F\xFB\x91\xA3\x1E\x99\x60\x4B\xEC\x92\x36\x66\x11\xFB\xBD\xC1\x86\x0C\xC0\xAE\xEE\xF4\x72\x64\x46\x59\x1A\x7E\x88\x8D\x21\xD7\x12\xE5\x5F\x83\x8D\xF3\x31\xEC\x4E\x2E\x95\xE6\x5B\x78\x08\xB2\x7A\x67\x61\xC4\x9F\x3A\xEA\x11\xE4\x93\xEB\xB0\xF1\xBD\x05\x94\xA4\xFC\xF0\xD9\xD8\x18\x70\x21\x30\xC2\x51\x8F\x20\x9F\x6C\x8A\x04\x9B\x85\x0F\x7E\xCD\x51\x0F\xC0\x3F\xB1\xBF\x1F\xB2\xA4\xBF\xAD\x41\xDB\x5F\xA1\x9C\x6F\xE0\x7A\x60\x4F\x60\x7F\x60\x2C\xB0\x35\xB0\x55\xF5\xCF\x21\xC8\x4A\xFF\x62\xA4\x3C\xD1\x32\x24\xC5\x70\x6A\x55\x66\x20\x2B\xF6\x65\xE3\x6C\xE0\x4A\x83\x76\x5B\x90\xF2\x3B\x6B\x0C\xDA\xCE\x04\x56\x39\xCF\xB3\x90\xB3\xC4\x65\x61\x38\x72\xEB\xFD\xCD\xC0\x5B\xF4\xDD\x6E\xCB\x91\xC4\xFF\xB3\xAA\x6D\x96\x85\xFE\xD8\x2D\x68\x7D\xC6\x51\x0F\x77\x7E\x87\x8D\xD1\x8E\xF4\x54\x22\x21\x5B\x03\x93\xB1\xD9\x3F\x5F\x09\xDC\x09\x4C\x74\xD3\x26\x2D\xC7\x60\xE3\x8B\xF7\x7A\x2A\xE1\xC9\x56\xD8\x94\xCA\xF9\x0B\xC5\x3F\xE3\xBB\x23\x52\x1F\xDB\x2A\x19\xA1\xA3\x4C\xA3\xF8\x57\xA8\xD6\x01\x4F\xA3\x6F\xBB\x35\x88\xAF\x17\x8E\x0B\xB1\x71\xB6\x43\x3D\x95\x70\xA6\x11\xF8\x3E\xBE\x77\x42\xB5\xC9\x5A\x64\xC5\xB6\xC8\x53\xEB\x23\xB0\xB1\xDD\x77\x3C\x95\xF0\xA0\x1E\xB9\x6F\xC8\xE2\x4D\x51\x54\x3E\x08\x4C\xC7\x3F\x70\x3B\xCA\x02\xA4\x7C\x6B\x11\x67\x39\x75\xD8\xD8\xB8\x99\x82\xD9\xEB\x00\x6C\x9C\xEB\x38\x4F\x25\x9C\xA8\x43\x02\x66\x29\xE9\x83\xB7\xBD\xDC\x48\x31\x0B\xBA\x7D\x1E\x1B\x7B\x15\xEA\x13\xE4\xA7\xD8\x3C\xE5\x8A\xB6\xF2\x5C\x07\x5C\x4D\xFA\x60\xDD\x98\x3C\x44\xF1\x4E\x78\x35\x20\xDB\x3F\xDA\xB6\xBA\xCA\x51\x07\x53\xFA\x01\x6F\xA2\x6F\xA0\xB3\x3C\x95\x70\x20\xEB\xC1\xDB\x26\xD3\x80\xD1\x46\x36\x48\xC5\x39\xE8\xDB\xE9\x0D\xE4\xD3\x31\xF7\x1C\x84\xBE\x71\x96\x53\xAC\xC5\x95\x3A\xE0\x27\xA4\x0F\xCE\x9E\xCA\xCB\x14\x2B\xEB\x6D\x18\x36\x5B\x73\x9F\xF0\x54\xC2\x0A\x0B\xC7\xBC\xD1\x55\x03\x7B\xAE\x24\x7D\x50\xF6\x56\x7E\x4F\xB1\x3E\x61\x2C\xCA\xD1\x16\x62\x1A\x3D\x07\x7D\xC3\x14\x69\x81\xC0\xBA\x22\xA7\xA5\xFC\xD8\xC0\x1E\xA9\x38\x00\x7D\xFB\xBC\xE4\xAA\x81\x01\x3B\xA0\x6F\x94\xE7\x5D\x35\xB0\xA5\x11\x59\x8C\x4B\x1D\x88\xB5\xC8\x89\xEA\x56\x49\x43\x1D\x30\x1B\x7D\xFB\x8C\xB7\xEC\xB4\xF5\x47\xB6\x45\x92\xC5\xED\x06\x6D\xA6\xE2\x28\xE4\x00\x42\x9E\xB9\x0E\x49\xF1\xCC\x3B\x15\x6C\x7C\xEB\x60\x83\x36\xDD\x78\x10\xFD\x27\xDA\x87\x5C\x35\xB0\xE5\x0E\xD2\xBF\x41\x35\xE4\x16\x6D\xC3\x24\x62\x67\xF4\x6D\x93\xDB\xDC\xE8\xFE\xE8\xAF\xEC\x3D\xE3\xAA\x81\x3D\xAF\x90\x3E\xF8\x34\x64\x1D\xB0\xAF\xB2\x6D\x52\x31\x0B\x5D\xDB\xBC\x87\xE1\x62\x9F\xE5\x14\x7A\x37\x60\x13\xE5\x36\xFF\x4B\xB9\xBD\xD4\x6C\x91\xBA\x03\x4A\xD4\x21\x2B\xAE\x45\x48\x1F\xFC\x8D\x72\x7B\x83\x81\x5D\x94\xDB\xFC\x1B\x96\x01\x3C\xC1\xA0\xCD\x07\x0C\xDA\x4C\x49\x25\x75\x07\x14\xF9\x28\x70\x78\xEA\x4E\x28\x60\x71\x71\x99\x59\x9D\x36\xCB\x00\xD6\xDE\xEA\x99\x8F\x1C\x1D\x2C\x12\x6F\xA5\xEE\x80\x32\x93\x52\x77\x40\x81\xA9\x48\x79\x26\x4D",
"\x22\x80\x91\x3C\xDC\xB5\xCA\x6D\xA6\xA6\x68\x0F\xA4\x43\x90\xEB\x72\xF2\xCC\x5A\xE0\x7F\x95\xDB\xCC\x5D\x00\x8F\x41\x6A\x3F\x6B\xF2\x88\x72\x7B\x59\x40\xFB\x9B\xBE\x82\x54\x3D\x99\x84\xAC\xD6\x6F\x02\x0C\x44\xB6\x79\x8E\x46\xB2\x8D\x56\x2A\xFF\x66\x7B\x1A\x81\xE3\x0D\xDB\xF7\xE2\x0F\xCA\xED\x6D\x05\x6C\xA6\xDC\xA6\x29\x9F\x46\x7F\xA5\xB3\x48\xDB\x47\x6D\x34\xA1\x77\x8F\xED\x54\x60\xD7\x1E\xFC\xE6\x18\x64\xDB\xC7\x6A\x45\x7A\x6A\x9F\x2C\x91\x2D\x76\x41\xDF\x2E\x07\xB9\x6A\x50\x23\xE7\xA2\xAB\xFC\x42\x0A\x72\xB2\xA3\x13\x8E\xA5\x76\xFB\xFC\x9C\xDE\x6F\x55\x4C\x42\x2A\x52\x5A\x04\x71\xDE\x0F\x3A\xD4\xA1\x5F\x7A\xF6\xEB\xAE\x1A\xD4\xC8\x4D\xE8\x2A\x7F\x9F\x6B\xEF\xFD\xB9\x86\xBE\xDB\xE6\x3A\xFA\xBE\x7D\x73\x72\x0D\xBF\xDB\x95\xE4\xEA\x6D\xB3\x11\xB4\x0B\x30\x5E\xEF\xDB\xFD\xDA\xD0\x2E\x53\x72\xA1\x6F\xF7\xDD\xA9\xA7\x6F\x41\x7C\x0D\xB5\xCF\x4C\x6E\xE8\xC3\xEF\x76\x27\x45\xB8\xF8\xFA\x62\x74\x6D\xF2\xA4\x6F\xF7\x6B\x63\x09\xBA\xCA\x1F\xED\xDB\xFD\x64\x1C\x87\x1C\x04\xEF\xCE\x1E\x6F\xA0\x57\x4E\x68\x34\xFA\xE3\x75\xB3\x52\xDF\x52\x72\x3C\xBA\x36\xD1\xDE\x9A\x32\x63\x04\xFA\x4F\xF4\xED\x5D\x35\x48\x4B\x13\x72\xC2\xE7\x2E\xE4\xA4\xD2\x9A\xAA\x34\x57\xFF\xDB\x89\xD5\x7F\xA3\xC9\xF5\xE8\x8E\x57\x11\x52\x5E\x3F\x84\xBE\x1F\x0F\x73\xD5\xA0\x8F\xEC\x85\xAE\xD2\xCB\x90\xB2\x3C\x81\x1D\x87\xA0\x3B\x66\x45\x48\x50\x69\x40\xFF\x0A\xDC\xDD\xB5\x3B\x69\xB1\xB2\x3B\x4E\xB9\xBD\xB9\x14\x2F\x81\x23\x6B\x4C\x57\x6E\xAF\x08\x95\x3A\xD6\x20\x5B\x7C\x9A\x8C\x55\x6E\xCF\x24\x80\xB7\x51\x6E\xAF\x45\xB9\xBD\x60\x43\xE6\xA1\xFB\x90\x2C\x4A\xF9\xD9\xB9\xCA\xED\x69\xBF\xDC\x4C\x02\x58\xBB\x62\x61\xB3\x72\x7B\x41\xE7\x44\x00\x6F\x48\x8B\x72\x7B\x63\x94\xDB\x33\x09\x60\xED\x5C\xD8\x16\xE5\xF6\x82\x0D\x19\x83\xA4\x41\x6A\x51\x84\x29\x34\xE8\xBF\x3C\xD4\x13\x5C\x2C\x02\x58\xBB\x93\x6F\x2B\xB7\x17\x6C\x88\xF6\xE2\x4A\x6E\xB6\x4C\xBA\x41\x7B\x31\xAE\x94\x01\xBC\x40\xB9\xBD\x60\x43\xB4\xF7\xD9\x73\x5F\x8D\xB1\x8A\xB6\xEF\xA9\x9F\xD4\xCA\xC3\x14\x7A\xBE\x72\x7B\xC1\xFB\xD9\x1C\xF8\x9C\x72\x9B\x11\xC0\x9D\x93\x8B\x37\xF0\x20\xE5\xF6\xE2\x0D\x6C\xCB\x65\xE8\x8F\xD9\xCB\xCA\xED\xA5\x42\xFB\xE5\xA1\x6D\x67\x93\x00\xD6\xCE\x12\x5A\xAA\xDC\x5E\xB0\x9E\x49\xC0\x49\x06\xED\x16\xE5\x0D\xBC\x4C\xB9\x3D\xED\xD8\x30\x61\x11\x25\x4C\x3F\xCB\x21\xA7\x60\x73\x71\x78\x2B\x39\x3B\xBC\xDE\x05\xC3\xD1\xB5\xCD\x22\xDF\xEE\xF7\x8D\xE5\xE8\x2A\x3D\xD0\xB7\xFB\x85\x67\x0B\xE0\x56\xF4\x03\xB7\x4D\x7E\xEF\xA7\x8A\x39\x9B\xA0\x6B\x1B\xED\x37\xBA\xC9\x7E\x9D\xE6\x7E\x22\xC0\x6A\xE5\xF6\xCA\xC6\x26\x48\x72\xCD\x3E\xC0\x61\xC8\x29\x26\xED\x31\x6A\xCF\x9D\x86\x6D\x7B\xB3\x4A\xB9\xBD\x5C\x4C\xA1\xB5\xA7\x65\x71\x90\xA1\xE7\x34\x02\x27\x20\x57\x84\xCC\xC1\xAE\xE2\xC6\xC6\x64\x35\xF9\x2F\x6A\xD7\x9E\x7E\xE8\xDA\x67\x8D\x6F\xF7\xFB\x46\x4C\xA1\xD3\x70\x34\xF0\x1A\xBE\x01\xDB\x51\x2C\x6A\x2A\xA7\x24\xF3\x53\x68\x0B\x62\x11\xCB\x97\x7A\x60\x32\x69\x03\xB7\x4D\x3E\x6D\xAC\xAB\x37\xA5\x5C\xC4\x7A\x07\x5D\xA5\x8B\xB2\xA2\x69\x45\x56\x82\x57\xBB\x96\x72\x16\x18\x83\xAE\x8D\x72\x71\x4E\xFA\x75\x74\x95\x56\x3F\x82\x55\x20\x8E\x26\x7D\xE0\x56\x90\xCB\xCD\x3E\x62\xAC\x6B\x0A\xC6\xA3\x6B\x27\xED\xF3\xC5\x26\x89\x1C\xDA\xF3\xFC\x22\x2D\x8A\x68\xD2\x08\x5C\x91\xBA\x13\x55\xEE\xA2\x78\xB7\x4C\x80\xBE\xEF\xA9\x7F\x03\x5B\x04\xB0\x76\xFA\x59\xDE\x6B\x0C\x5B\xF1\x59\xB2\x31\x3B\x59\x0C\xFC\x6B\xEA\x4E\x18\xA1\xED\x7B\xEA\x79\xFD\x16\x01\x9C\xF9\x04\xF0\x82\x70\x54\xEA\x0E\x20\xD3\xC2\x93\xD1\xAF\x5C\x91\x15\x32\x7F\xB2\x2E\x0F\x01\xAC\x5E\xC5\xA0\x20\xEC\x9D\xBA\x03\xC8\x14\xBE\x68\x77\x36\xB7\x47\xDB\xF7\x72\x11\xC0\xDA\xD3\x84\xB1\xCA\xED\x15\x85\xCD\x13\xFF\xFE\xA3\xC0\xB7\x13\xF7\xC1\x1A\xED\x4F\x94\x5C\x4C\xA1\xB5\x2B\x68\x8C\x55\x6E\xAF\x28\x54\x12\xFE\xF6\x4C\xA4\xF0\x79\x2E\x32\x8B\x6A\x60\xAC\x72\x7B\xEA\xDB\x48\x16\x01\xDC\xA2\xDC\xDE\x58\xE5\xF6\x8A\x42\xAA\x3D\xC5\x29\xC0\x81\xC8\x7E\x7F\xD1\xD9\x56\xB9\xBD\x66\xE5\xF6\x4C\x02\x58\xBB\x93\xE3\x89\x7C\xE8\xCE\xF8\x73\x82\xDF\x7C\x10\xC9\xB6\xCA\x45\x46\x51\x8D\x34\xA0\xFF\xF2\x68\x51\x6E\xCF\x84\x4D\xD1\x4F\x14\xD8\xD1\x55\x83\x7C\x70\x02\xBE\xC9\x1A\x37\x62\x7B\x8A\x29\x6B\x7C\x18\x7D\x1B\x0E\x75\xD5\xA0\x06\xDE\x45\x57\xF1\x63\x7C\xBB\x9F\x0B\x1A",
"\x91\xED\x1B\xEB\xC0\x7D\x13\xD9\x73\x2E\x1B\xDA\x0F\x48\x93\xD2\x50\x56\x97\x66\xCF\x51\x6E\xAF\x27\x37\xCF\x97\x8D\xD5\xC0\x79\xC6\xBF\x71\x13\xB0\x13\xF0\x1B\xE3\xDF\xC9\x22\x3B\x2B\xB7\xA7\x1D\x13\x80\x5D\x00\x3F\xAB\xDC\xDE\x9E\xCA\xED\x15\x85\xBB\x81\xAB\x0D\xDA\x7D\x18\x98\x88\x24\x69\x94\xE1\x7B\xB7\x33\xB4\x7D\x6E\xA6\x72\x7B\xA6\x9C\x8D\xEE\xF4\x63\x21\x76\x0F\x9B\xBC\xA3\x75\x9C\x70\x15\xF2\xC6\xDD\xCD\xB5\xF7\xD9\xA4\x1E\xFD\xCF\xC0\xAF\xBA\x6A\x50\x23\x13\xD1\xFF\x16\xDB\xC9\x55\x83\xFC\xD1\x97\x03\xFD\x8B\x80\x7B\x80\xAF\x93\x3E\x31\x24\x4B\xEC\x8A\xBE\xFF\x1E\x68\xD1\x51\xAB\x3B\x6C\x2C\x2E\x78\xDE\x0F\x78\xDE\xA0\xDD\xA2\x70\x37\x70\x2F\xB2\xE0\x74\x24\x72\xBC\x6F\x1B\xE4\xCD\x3A\x0F\x49\xB0\x99\x5F\xFD\xFB\x0B\xC0\x1F\x80\xA7\x88\xAB\x5B\x3B\x63\x82\x41\x9B\xCF\x19\xB4\x69\x8A\xF6\xB9\xE0\xDB\x7C\xBB\x1F\x94\x98\xBB\xD0\xF5\xDD\x16\xD7\xDE\x2B\x71\x3B\xBA\x46\x58\x40\x24\x74\x04\xF6\x34\xA0\x5F\x16\xEA\x16\xAB\xCE\x5A\x2E\x0C\x4D\x51\x6E\x6F\x53\xB2\x71\x02\x27\x28\x36\x1F\x43\xBF\x0E\xDB\x13\xCA\xED\xFD\x0D\xCB\x00\xB6\xE8\xF4\xDF\x1B\xB4\x19\x04\xED\x39\xC4\xA0\x4D\xED\x97\x99\x0B\x0D\xC0\x7B\xE8\x4E\x45\xB4\xF7\x97\x83\xA0\x23\xCF\xA3\xEB\xB3\x8B\xC9\xF1\xA7\xDF\xEF\xD0\x35\x46\x85\xD8\x4E\x0A\xEC\xD8\x0D\x7D\x7F\xBD\xC7\xB2\xC3\xD6\xC9\x11\x16\x85\xBE\x8F\x33\x68\x33\x08\xC0\xC6\xB7\x72\x5D\xEC\x7E\x7B\xF4\x9F\x68\x2F\xB8\x6A\x10\x94\x85\x3A\x24\x5F\x59\xDB\x5F\xB3\x50\x78\xB0\x26\x66\xA3\x6F\x94\xFD\x5C\x35\x08\xCA\xC0\x27\xC9\xE1\xCB\xC6\x23\xBF\xF8\x01\x83\x36\x4F\x33\x68\x33\x28\x37\x93\x0C\xDA\xCC\xF5\xF4\xB9\x8D\x03\xD0\x7F\xB2\x2D\x47\xEE\xAD\x09\xDE\x4F\x67\xB7\x13\xB6\x56\xFF\x7E\x7B\xF5\x7F\x2B\xD3\xA1\xFC\x9E\x32\x0C\xFD\x4B\xF9\x0A\x33\x53\xAC\x07\xFE\x8A\xBE\x71\xCE\xF6\x54\x22\x07\xF4\xF4\x30\xC3\x6B\xD5\x7F\x1B\xAC\xE7\x5C\xF4\xFD\xF3\x75\x0A\x74\x82\xEE\x6A\x6C\x0C\xD4\xDF\x53\x89\x8C\xD2\xD7\xE3\x84\x93\x29\x90\x83\xD5\x40\x7F\xE4\xCE\x22\x6D\xFF\xFC\xB1\xA7\x12\xD6\x4C\x40\xDF\x40\x15\x64\x4A\x58\x76\x6A\x39\x0B\x3C\x39\x41\x7F\xB3\xC6\x89\xD8\xF8\xE6\x3E\x9E\x4A\x58\x53\x8F\xCD\x53\x2E\x45\x65\xC6\x2C\xA1\x71\x3B\x61\x99\xA7\xD3\x75\xC0\xD3\xE8\xFB\xE5\x2B\xD5\xB6\x0B\xC5\xF7\xB0\x79\xD2\xFD\x83\xA7\x12\x19\x42\xAB\xA8\x5D\x0B\xD0\xE4\xDB\xF5\xCC\x70\x24\x36\x3E\xF9\x2D\x4F\x25\xBC\xF8\x00\x52\xC9\x5F\xDB\x58\xD3\x29\xE0\xD3\xAE\x07\x68\x56\x4D\x3C\xDE\xB9\xEF\x59\xA0\x0E\x98\x81\xBE\x3F\xB6\x02\x5B\x38\xEA\xE1\xCA\xFD\xD8\x3C\xF1\xCA\x58\xF6\xF4\x0E\xF4\xEC\x77\x87\x73\xDF\xB3\xC0\xF1\xD8\xF8\xA2\x69\xEE\x73\x6A\x3E\x83\x8D\xD1\x5E\xA0\x7C\x2B\xD2\x9A\x35\xA1\x8B\x7A\x3D\xE8\xC6\x68\x04\x5E\xC6\xC6\x17\x0F\x77\xD4\xC3\x9D\x7E\xD8\xE4\x9B\x56\x90\xC2\x6C\x65\x62\x05\x7A\xB6\x5B\xE1\xDC\xF7\xD4\x9C\x87\x8D\x0F\xCE\x25\xC7\x47\x07\x7B\xCA\xD7\xB0\x31\xDE\x42\x60\xA4\xA3\x1E\xA9\x59\x89\x9E\xED\x56\x3A\xF7\x3D\x25\xA3\xD0\x2F\x19\xDB\x26\x67\x3A\xEA\x91\x8C\xC1\x48\xB0\x59\x18\xF0\x5A\x47\x3D\x52\xA3\xB9\x2D\xF7\xAA\x73\xDF\x53\xF2\x0B\x6C\x7C\x6F\x3E\x30\xC8\x51\x8F\xA4\x7C\x1F\x1B\x23\xAE\xC5\xA6\x24\x68\x16\xF9\x2D\x7A\x76\xFB\xAD\x73\xDF\x53\x71\x00\xB0\x0E\x1B\xDF\xBB\xC8\x51\x8F\xE4\x6C\x81\xEE\x37\x5C\x7B\x79\x81\x72\xEC\x6B\x9E\x8C\x9E\xCD\x4E\xF2\xED\x7A\x12\x06\x62\xB7\x70\xB5\x0C\x18\xED\xA7\x4A\x36\xB8\x12\x1B\x63\x56\x80\x8B\x1D\xF5\x48\xC5\x20\xE4\x92\xEF\x5A\x6D\xF5\x16\xE5\x98\xFA\x59\xCD\xFA\x2A\xC0\x0F\x1D\xF5\xC8\x0C\x9B\xA1\x5F\xF4\xAE\x4D\x5A\x91\xF2\xA0\x45\xE7\x14\x6A\xB7\xD5\x29\xEE\xBD\xF6\x67\x3F\x6C\x92\x88\x2A\x88\x0F\x8F\xF2\x53\x25\x5B\xFC\x00\xBB\xA7\xE2\x2B\xC0\xDF\xF9\xA9\x92\x8C\xDB\xE8\xBB\x8D\xCA\x70\xDB\xC5\x50\xA0\x19\x3B\x3F\xBB\xC4\x4F\x95\xEC\x31\x02\xBB\x25\xFD\x0A\x72\xDB\x5E\xD1\x69\x04\xEE\xA4\xF7\xB6\xB9\x93\x72\x1C\xEE\xBF\x05\x3B\xFF\x5A\x44\x14\x96\xE0\x1B\xD8\x19\xB8\x82\x4D\xA9\x94\xAC\x51\x87\x5C\x5F\xB9\x98\xEE\xED\xB1\xB8\xFA\x6F\xCB\x90\x3F\x7E\x3A\xB6\xBE\x55\xB6\xE4\xA1\x4E\x69\x04\x5E\xC2\xCE\xC8\x2B\x28\xCF\x95\x2C\xC3\x81\x73\x80\xC7\x78\x7F\x89\x98\xE5\xD5\xFF\x76\x0E\xE5\x79\x63\xEC\x8B\x6E\xB2\x4B\x47\x29\x63\xFA\xEE\x46\x39\x02\xDB\x27\x65\x0B\xE5\xCA\xD2\x6A\x63\x38\xE5\x09\xD8\xF6\x8C\x42\xFF\x76\xCC\x8E\x72\xA8\x9B\x36",
"\x39\xE1\x21\x6C\x0D\xFE\x18\xE5\xD8\x1F\x2E\x3B\x03\x91\xBB\x88\x2C\x7D\xE9\x3E\x37\x6D\x72\xC4\xF6\xD8\x54\x06\x6C\x2F\x77\x50\x8E\x6F\xBF\xB2\x52\x87\xED\xA2\x55\x05\x49\xDA\x18\xEF\xA5\x50\xDE\x38\x1F\x5B\xE3\x57\x80\x4B\xDD\xB4\x09\xBC\xB9\x02\x7B\xFF\x39\xD7\x4D\x9B\x1C\xD2\x80\x54\xD8\xB0\x1E\x84\x6F\x7A\x29\x14\xB8\x71\x36\xF6\x7E\x33\x83\x58\xB8\xEA\x96\xBD\x90\x4C\x2A\xCB\x81\x58\x87\x6C\x31\x04\xC5\xE0\x2B\xD8\x07\x6F\x2B\xB0\x87\x97\x42\x79\xE7\x02\xEC\x07\x64\x2D\xE5\x48\xE2\x2F\x3A\x93\xB0\x3B\x61\xD4\x5E\xBE\xEB\xA5\x50\x11\x68\xC0\x7E\x25\xB1\xED\x4D\x1C\x9B\xF1\xF9\xE5\x74\xE4\x41\x6C\xED\x27\x8F\x53\x82\x4A\x1B\xDA\x6C\x4B\xCF\x32\x8B\x34\xE4\xDF\x9C\x74\x0A\xF4\xF0\x58\xF0\xAC\x20\xA9\xBE\x63\x7D\x54\x2A\x1E\x5F\xC4\x67\x90\x2A\xC8\x71\xB3\xD8\x62\xCA\x3E\xF5\xF8\xAC\x36\xB7\xC9\xE7\x7D\xD4\x2A\x2E\xFF\x81\xDF\x60\xFD\x1A\x49\x04\x08\xB2\x49\x13\x70\x2B\x7E\xFE\xF0\x33\x1F\xB5\x8A\xCD\x00\xE4\x0A\x15\xAF\x41\xFB\x23\xE5\x4C\xBB\xCC\x3A\xA3\xF0\x59\x17\x69\x93\xA9\x44\xE6\x9E\x1A\x5B\x01\xEF\xE0\x37\x78\xAF\x23\xC9\xF0\x41\x36\xD8\x0B\xDB\x33\xBD\x1D\xE5\x6D\xE4\x26\x91\x40\x91\x89\xD8\xEF\x0F\xB7\x97\x15\x94\xE3\x28\x62\xD6\xF9\x32\xB6\xA7\x8A\x3A\xCA\x6A\xE0\x40\x0F\xC5\xCA\xC8\x69\xF8\x0D\x64\x9B\xDC\x4C\x39\x2A\x7B\x64\x8D\xA1\xD8\xE7\x35\x77\x26\x5F\xF2\x50\xAE\xCC\x5C\x8E\xFF\xA0\xB6\x50\x9E\x72\xB5\x59\x60\x5F\xEC\x6E\xF0\xE8\x4A\x4A\x55\x1A\x36\x15\x75\xC0\xED\xF8\x0F\x6E\x2B\x52\xED\x32\x16\x36\xEC\x18\x00\x5C\x86\x5D\x01\xBA\xAE\xE4\x57\xC4\x36\xA2\x1B\x03\x80\x47\xF0\x1F\xE4\x0A\x52\x89\x61\x7F\x7B\x15\x4B\xC7\x81\xD8\x56\x66\xE9\x4A\x1E\x22\x1E\xCC\xEE\x0C\xC6\x77\x5B\xA1\xBD\xAC\x03\x7E\x8E\x94\xC6\x0D\x6A\x63\x14\x72\xDD\x89\x47\x3E\x73\x67\xF2\x38\xE5\xA8\x8B\x9D\x49\x86\xE2\xBB\x47\xDC\x51\x16\x21\x29\x7D\xF1\xF4\xEE\x3D\xFD\x91\x3C\x74\xCB\xAA\xA4\xDD\xC9\x0C\xCA\x59\x72\x28\x53\x8C\x04\x9E\x25\x9D\x13\x54\x80\x17\x81\x63\x89\x6F\xA8\x9E\x50\x0F\x1C\x87\xDD\x35\x27\x3D\x95\x67\x89\x84\x9D\xCC\x30\x1C\x78\x92\xB4\x0E\xD1\xE6\x14\x11\xC8\x1B\x67\x22\x3E\x05\x1B\xBA\x93\xE9\x44\xF0\x66\x8E\x61\xC0\x13\xA4\x77\x8E\x36\x07\xF9\x1C\x72\x2C\xB2\xEC\xF4\x07\xFE\x11\x78\x9A\xF4\xE3\x52\x41\x52\x65\x87\x9A\x6A\x1C\xF4\x99\xC1\xC0\xC3\xA4\x77\x92\x36\x79\x95\x72\xD5\x62\x6E\xCF\x70\xA4\x68\xFF\x6B\xA4\x1F\x87\x36\x79\x88\x58\xB0\xCA\x3C\x4D\xC8\x9E\x5E\x6A\x67\x69\x2F\x2B\x91\xAB\x4C\x26\x52\xFC\xE9\xF5\x5E\xC0\x75\x48\xF5\xC6\xD4\x76\x6F\x2F\x77\x22\xDB\x8F\x41\x0E\xA8\xC3\xF6\x3A\xC9\x5A\xE4\x65\x24\x21\x64\x67\x33\xED\xFD\xD9\x15\xB9\xE4\x2B\x45\xF6\x54\x4F\xE4\x62\x8A\xFF\xE0\x2C\x24\xA7\xE2\x7B\x00\xA2\xB7\x32\x0B\x71\xFC\xFD\xC8\x57\xC9\x96\x06\x24\xB5\xF4\x52\x24\xB1\x25\xB5\x1D\x37\x26\xAB\x91\x8B\xD0\x83\x1C\x73\x10\xBE\x47\x11\xFB\x2A\x0B\x91\xC2\xF3\xA7\x23\x6F\xE7\x7A\x0B\x63\xF4\x91\x7A\x60\x17\xE0\x0C\xE0\x2E\x64\xFF\x3B\xB5\xBD\xBA\x93\xB7\x29\xC1\xA9\xA2\xB2\x4C\x2B\xB6\x46\xAA\x6D\xE4\xE9\x92\xB3\x77\x91\x4C\xB3\xA7\x81\x99\xC8\x16\xD5\x6C\x24\x4F\xD8\x92\x06\x60\x07\x24\x60\x77\x45\x4A\xA9\x7E\x9C\x7C\xAD\xDC\x3E\x09\x1C\x03\xBC\x91\xBA\x23\xD6\x94\x25\x80\x41\x16\x30\x7E\x42\xBE\x6F\xA4\x5F\x05\xCC\x45\x4E\x47\x35\x57\xE5\x6D\x60\x41\x3B\x59\x8C\x04\xF9\x1A\xE4\xF6\x78\x80\x21\x48\x60\x36\x20\x81\x38\xA2\x9D\x8C\x06\xC6\x75\x90\x3C\x67\x96\x5D\x0B\x9C\x85\xD8\x2A\x28\x20\x5F\xC0\xAF\xDA\x65\x88\x9F\xBC\x4B\x14\xA0\x2B\x0D\xDB\x20\xB7\x15\xA6\x76\xBA\x10\x1D\xF9\x13\x71\xE1\x58\xE9\x68\x40\x6E\x80\xC8\xF2\x2A\x75\x48\xD7\xD2\x8A\xD4\xF4\xCE\xD3\x0A\x7E\xA0\xCC\x6E\xC0\x34\xD2\x3B\x63\x48\xEF\x64\x06\xF0\x91\x4E\xC6\x33\x28\x21\x0D\xC8\xD1\xB6\xA5\xA4\x77\xCC\x90\xAE\x65\x39\x72\x84\x33\xDE\xBA\xC1\x06\x6C\x07\x3C\x48\x7A\x27\x0D\xE9\x5C\xEE\x47\xAE\xDC\x09\x82\x2E\x99\x08\x3C\x47\x7A\x87\x0D\x11\x79\x09\x38\xAC\xCB\x11\x0B\x82\x0E\x34\x22\xB7\xB1\xA7\xAC\x18\x51\x76\x59\x88\xEC\xE9\xC6\xA5\xDA\x41\x9F\xD9\x14\x59\xAD\x8E\xBD\x63\x3F\x59\x8A\x94\x0F\x2E\xE3\x31\xCC\xC0\x88\x91\x88\x53\x65\xED\x98\x5C\x91\x64\x19\x30\x19\x18\xD3\xC3\x31\x09\x82\x5E\x33\x06\x39\x85\xB3\x80\xF4\x0E\x5F\x14\x99\x8F\x9C\xCA\x1A\xDD\x8B\x71\x08\x82\x9A\x18\x84\x5C\xF5\xF2\x22\xE9\x03\x20\xAF\x32\x17\xD9",
"\xBE\x8B\x2A\x19\x41\x32\xFA\x01\x47\x00\xF7\x92\xE6\x46\x81\xBC\x49\x2B\x70\x0F\x70\x38\xB1\x97\x1B\x64\x8C\x2D\x81\xEF\x20\x6F\x96\xD4\x81\x92\x35\x99\x03\x7C\x0B\xD8\xA2\xCF\xD6\x0D\x02\x47\x3E\x8C\xAC\x5E\x97\x39\x98\xDF\x40\x16\xA5\x26\x50\xAE\xA3\xAB\x41\x81\xA8\x07\x3E\x01\x5C\x45\xBA\xBB\x7F\x3C\xE5\x45\xE0\xDF\x91\xA0\xCD\x52\x55\x91\x20\x50\x61\x5B\xE0\x9F\x91\x6F\xE6\x25\xA4\x0F\xB8\x5A\x65\x31\xF0\xDF\x48\xB9\x9D\x71\x8A\x76\x0A\x7A\x40\x4C\x6B\xD2\xD2\x0F\x29\x5D\x33\x01\x29\x5B\x33\x01\xD8\x2A\x69\x8F\xBA\xE7\x75\xA4\x38\xFA\x14\xE4\x62\xB0\xE7\x80\xB5\x49\x7B\x54\x62\x22\x80\xB3\xC7\x48\xA4\x16\xD5\x2E\xAC\xAF\x4B\xB5\x1D\xFE\x59\x49\x0B\x91\x85\xA7\xB6\x7A\x5C\xCF\x01\xCF\x20\xFB\xDF\x41\x46\x88\x00\xCE\x0F\x43\x91\x29\xEA\xD8\xAA\x6C\x8E\x04\x7B\xFB\xFA\x56\x4D\xD5\x7F\x57\x8F\xE4\x0F\x0F\xAE\xFE\x7F\x97\x22\xDB\x37\xEB\x90\x29\xEF\x2A\x24\x10\xE7\x57\xFF\x9C\x07\xBC\x85\xDC\x24\xD1\x5C\x95\x25\xE6\x1A\x05\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x10\x04\x41\x90\x7B\xFE\x1F\x25\x9C\xCB\x0D\x81\x4D\x43\xA2\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82\x03\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x57\x61\x72\x6E\x69\x6E\x67\x4E\x10\x00\x00\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\xF0\x00\x00\x00\xF0\x08\x06\x00\x00\x00\x3E\x55\xE9\x92\x00\x00\x00\x06\x62\x4B\x47\x44\x00\xFF\x00\xFF\x00\xFF\xA0\xBD\xA7\x93\x00\x00\x10\x03\x49\x44\x41\x54\x78\x9C\xED\xDD\x79\x90\x5D\x45\x15\xC7\xF1\xEF\x64\x60\x30\x09\x44\x03\x08\x84\x40\x58\x54\x16\x71\x05\x54\x10\x95\x45\x01\xA3\x28\x18\x8C\xE0\x96\x0A\x05\xEE\x08\x8A\x5A\x50\x28\x88\x22\x11\x15\x45\x10\x41\x50\x0A\x14\x64\x11\x0D\x41\x51\x70\x03\x14\x37\x16\x23\x2E\x41\x84\x10\x34\x2E\x09\x0A\x89\x04\x98\xEC\x13\xFF\xE8\x19\x8D\x43\x26\x33\xEF\xBD\xFE\x9D\xBB\xFD\x3E\x55\x5D\x54\xA5\x86\xFB\xCE\xE9\xDB\x7D\xEF\x7B\x77\x39\x0D\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\xB5\xD0\x55\x74\x00\x96\x55\x37\xB0\x19\x30\x1E\xD8\xB4\xFF\xBF\xAB\x80\xC5\xFD\x6D\x51\x7F\xB3\x9A\xF0\x04\xAE\xB6\xAD\x81\x03\x80\x3D\xFB\xDB\xF3\x81\x31\xC3\xFC\x3F\x8B\x80\x3B\xFB\xDB\x1D\xC0\x4D\xC0\x12\x61\x8C\x66\xB6\x96\xF1\xC0\x34\xE0\x3B\xC0\x4A\x60\x4D\x87\x6D\x69\xFF\xB6\xA6\x01\x63\x03\xF3\x30\x6B\x94\xED\x80\x0B\x81\xE5\x74\x3E\x69\x87\x6A\x8B\x80\x53\x80\x71\x41\x39\x99\xD5\xDE\x44\xE0\x7C\xB4\x13\x77\x70\x7B\x18\xF8\x08\xB0\x71\x40\x7E\x66\xB5\x35\x95\x34\x99\xA2\x26\xEE\xE0\xF6\x00\xB0\x9F\x3A\x49\xB3\xBA\xD9\x02\xB8\x96\xE2\x26\xEE\xDA\xAD\x8F\xF4\xD5\x7D\xB8\x8B\x63\x66\x06\xEC\x0E\x2C\xA0\xF8\x89\x3B\xB8\xDD\x01\x6C\x29\xCC\xDB\xAC\xF2\x0E\x00\x1E\xA1\xF8\xC9\x3A\x54\x9B\x07\xEC\x24\xCB\xDE\xAC\xC2\x8E\x20\xF6\x42\x55\xBB\xED\x41\xD2\xB7\x04\x33\xEB\xB7\x3F\xB0\x82\xE2\x27\xE7\x48\xDB\x02\xD2\x6D\x2D\xB3\xC6\xDB\x85\x74\xFF\xB5\xE8\x49\xD9\x6A\x9B\x03\x3C\x45\xD0\x1F\x66\x95\xB1\x19\x70\x3F\xC5\x4F\xC6\x76\xDB\x8D\xC0\xA8\xEC\xBD\x62\x56\x11\x97\x53\xFC\x24\xEC\xB4\x1D\x97\xBD\x57\xCC\x2A\x60\x32\xC5\x4F\xBE\x1C\xED\x71\x60\xC7\xCC\x7D\x63\x56\x6A\x63\x49\xB7\x64\x8A\x9E\x7C\xB9\xDA\x0D\x79\xBB\xC7\xAC\xDC\x3E\x4B\xF1\x93\x2E\x77\x7B\x63\xD6\x1E\x32\x2B\xA9\xA7\x53\x8D\xFB\xBD\xAD\xB6\xBF\xE1\xD7\x11\xC3\x75\x17\x1D\x40\x03\x5D\x4E\xBA\x75\x54\x37\xE3\x48\xD5\x3F\x6E\x29\x38\x0E\x33\x99\x57\x53\xFC\x99\x52\xD9\x7A\x81\xED\x73\x75\x96\x0D\xCF\x67\xE0\x38\x3D\xC0\x2C\x60\xF3\x80\xCF\x5A\x06\xCC\x06\x7E\x4B\xBA\x58\xB6\x8C\x74\xCF\x59\x7D\xCF\x76\x43\xD2\xFB\xCB\xD7\x88\x3F\xC7\x2C\xDC\x07\xD0\x9F\x01\x6F\x20\x9D\xE5\x7B\xD6\xF1\xF9\xE3\x48\x65\x73\x7E\x1B\x10\xC7\x7E\xED\x77\x93\x59\xF9\x6C\x09\xFC\x1B\xDD\x84\xF9\x3B\x70\xF0\x08\x63\xE9\x02\xDE\x43\xFA\xBA\xAB\x8A\xE7\x2E\xFC\xED\xCE\x6A\xE4\x2B\xE8\x26\xCB\x3D\xC0\xB6\x6D\xC4\xB4\x0F\xDA\x83\xCA\x3B\xDB\x88\xC9\xAC\x74\xF6\x00\x56\xA3\x99\x24\x0F\x01\x3B\x74\x10\xDB\x41\xC2\xD8\xFE\x45\xAA\xA0\x69\x56\x59\x5D",
"\xC0\xAD\xE8\xCE\x72\xD3\x32\xC4\x78\xAE\x30\xBE\xCF\x67\x88\xCF\xAC\x30\x6F\x42\x37\x39\x7E\x4E\x9E\xC2\xFC\x9B\xA0\x2B\xE1\xB3\x12\x78\x56\x86\x18\xCD\xC2\x8D\x06\xFE\x8C\x66\x62\xAC\x06\x5E\x90\x31\xD6\xB7\x89\xE2\x5C\x03\xFC\x28\x63\x9C\x66\x61\x3E\x8E\x6E\x52\x7C\x39\x73\xAC\xA3\x80\xDB\x85\xF1\xBE\x36\x73\xBC\x66\x52\xDB\x92\x5E\xB3\x53\x4C\x86\x25\xC0\x56\x82\x98\x5F\x4C\x2A\x21\xAB\x88\x79\x2E\xB0\x91\x20\x66\x33\x89\x6B\xD0\x9D\xCD\x4E\x10\xC6\x7D\xA5\x30\xEE\x13\x85\x71\x9B\x65\xF3\x12\x74\x67\xB2\xFB\xD0\x9E\xC9\xB6\x01\x1E\x13\xC5\xBE\x04\x98\x20\x8C\xDD\xAC\x63\xDD\xA4\xA7\x90\x54\x67\xB1\x57\x05\xE4\xF0\x51\x61\xFC\x97\x04\xC4\x6F\xD6\xB6\x77\xA1\x1B\xFC\x3F\x08\xCA\x61\x34\x69\x4D\x24\x45\x0E\x7D\xC0\x0B\x83\xF2\x30\x6B\xC9\x78\xD2\xD3\x47\x8A\x81\xBF\x02\xD8\x39\x2E\x15\xDE\x20\xCA\x63\x0D\xF0\x4B\xBC\xB0\xBC\x95\xD0\x39\xE8\x06\xFD\x59\x81\x79\x0C\xB8\xA5\xCD\x58\x47\xD2\xDE\x12\x97\x86\xD9\xF0\x76\x45\xB7\xB2\xC2\x83\x14\x53\x40\xFD\x79\xA4\x0A\x1B\x8A\x9C\x16\xE0\x45\xC4\xAD\x44\x6E\x40\x77\xB6\x3A\x26\x30\x8F\xC1\xBE\xB4\x9E\xB8\x3A\x6D\x67\x04\xE6\x61\x36\xA4\x43\xD1\x0D\xF2\xD9\x14\xFB\x5E\xED\xA6\xA4\x37\x9E\x14\xB9\x2D\x07\x9E\x11\x97\x8A\xD9\x13\xF5\x00\x7F\x42\x37\x81\x5F\x16\x97\xCA\x90\xDE\x87\x2E\xBF\x6F\x05\xE6\x61\xF6\x04\x27\xA2\x1B\xDC\x57\x04\xE6\xB1\x3E\x1B\x00\xBF\x47\x97\xE7\x41\x71\xA9\x98\xFD\xCF\x96\xE8\x16\xE3\xEE\xA5\x5C\xCB\x77\xBE\x02\xDD\x04\x9E\x43\x3A\x48\x98\x85\xBA\x04\xDD\xA0\x3E\x35\x30\x8F\x91\xFA\x36\xBA\x7C\xDF\x13\x98\x87\x99\xB4\x4C\xCE\x7C\x60\x4C\x5C\x2A\x23\xF6\x34\x52\x79\x5A\x45\xCE\x8B\x88\x29\xB7\x6B\x26\x2F\x93\x33\x35\x2E\x95\x96\x7D\x1A\x5D\xDE\x5F\x08\xCC\xC3\x1A\xEC\xAD\xE8\x06\xF1\xCF\x28\xF7\x63\x86\x9B\x00\xFF\x40\x93\xFB\x2A\xE0\x39\x71\xA9\x58\x13\x6D\x4C\xAA\xC1\xAC\x18\xC0\xAB\x49\x5F\xCD\xCB\xEE\x28\x74\x07\xB0\x1F\x07\xE6\x61\x0D\x74\x06\xBA\xC1\x7B\x41\x60\x1E\x9D\x18\x05\xDC\x86\xAE\x1F\x5E\x17\x97\x8A\x35\xC9\x8E\xC0\x52\x34\x83\x76\x31\xF0\xD4\xB8\x54\x3A\xB6\x37\xBA\xA2\x05\xF7\x03\x4F\x8A\x4B\xC5\x9A\x62\x26\xBA\xB3\xCE\xF1\x81\x79\xE4\x72\x39\xBA\xFE\x38\x39\x30\x0F\x6B\x80\x03\xD0\x0D\xD6\xBB\x49\xAB\xFA\x55\xCD\x44\xE0\x51\x34\x7D\xF2\x28\xB0\x75\x5C\x2A\x56\x67\xDD\x68\x57\xF4\x7B\x65\x5C\x2A\xD9\x7D\x04\x5D\xBF\x7C\x2D\x30\x0F\xAB\xB1\x63\xD1\x0D\xD2\x6F\x07\xE6\xA1\xB0\x11\xA9\xD0\x9E\xA2\x6F\xFA\x48\x05\x02\xCD\xDA\xA6\x2C\x93\xB3\x1C\xD8\x29\x2E\x15\x99\xC3\xD1\x1D\xE0\xEE\x44\xBF\x28\xB9\xD5\xD8\x79\xE8\x06\xE7\xA7\x02\xF3\x50\xFB\x3E\xBA\x7E\x9A\x1E\x97\x86\xD5\xC9\x33\x49\x8B\x73\x29\x06\xE5\x42\xE0\xC9\x71\xA9\xC8\xA9\xFB\xCA\xE5\x77\xAC\x65\xCA\xB3\xCA\x51\x81\x79\x44\xF9\x22\xBA\xFE\x3A\x33\x30\x0F\xAB\x81\x29\xE8\x06\xE3\xAF\xA9\xE7\xEF\x3A\x75\xF9\x9D\x3A\x5C\x2F\xB0\x00\x3D\xC0\xBD\x68\x06\x62\xDD\xAF\xAC\xBE\x17\xDD\x81\x6F\x56\x60\x1E\x56\x61\x27\xA3\x1B\x84\x97\x05\xE6\x51\x84\x6E\xE0\x77\xE8\xFA\xAF\xCA\xF7\xCC\x2D\xC0\x56\xE8\xCA\xE4\x3C\x0E\x4C\x8A\x4B\xA5\x30\x7E\x6A\xCD\x0A\x73\x19\xBA\xC1\xF7\xE1\x80\xF8\x7B\x80\x23\x81\xAB\x48\x6B\xF2\xAE\xEC\x6F\x73\xFB\xFF\xED\xC8\xFE\xBF\x51\xBB\x16\x5D\x3F\x1E\x17\x10\xBF\x55\xD0\x5E\xE8\xDE\xB0\x99\x87\xFE\x0D\x9B\xC3\x49\xE5\x78\x86\x8B\x65\x7E\xFF\xDF\x2A\x29\xDF\xDC\x72\xF9\x1D\x7B\x82\x2E\xB4\xEF\xB8\x4E\x11\xC6\x3E\x8A\xF6\xD6\x65\x3A\x07\xED\xD5\xF0\x19\x6D\xC4\x34\xD2\x76\xBE\x30\x6E\xAB\xA0\xE9\xE8\x06\xDB\x4D\xE2\xD8\x3B\x59\x54\xED\x1C\x61\x5C\xCA\xEA\x25\xAB\x80\xE7\x0A\x63\xB7\x0A\xA9\x72\x9D\xA7\x1C\xCF\x21\x2B\xBF\x4E\x4F\xCB\x10\xDF\x50\xED\x56\xCA\x5D\x3F\xCC\x82\x9C\x89\x6E\x90\x9D\x27\x8C\xBB\x87\xF4\xDB\xBA\xD3\x18\xFF\x4C\x7A\xAB\x48\xA1\x0B\xF8\x55\x86\x18\x87\x6A\xAF\x17\xC5\x6D\x15\x51\xE5\x5A\xC7\x47\x66\x8C\xF5\x08\x61\x9C\x4D\xAC\xA1\x6D\x41\xAE\x43\x77\x76\x38\x56\x1C\xFB\xD5\x19\x63\xBD\x5A\x1C\xEB\x57\x33\xC6\x3A\xB8\x9D\x22\x8E\xDD\x4A\xEA\xE5\xE8\x06\xD5\x1C\xF4\x0F\x1C\xE4\xF8\xFA\x3C\xD0\xE6\x89\x63\x6D\xD2\x3A\x52\x16\x40\xBD\xE2\xDE\xC1\x01\x39\xE4\xBC\xCF\xBA\x34\x20\xDE\x93\x32\xC6\x3B\xB8\x7D\x3D\x20\x7E\x2B\x91\xE3\xD1\x0D\xA6\x99\x41\x39\xE4\x8E\x5B\x4D\xFD\x92\xC8\x4B\x03\x72\xB0\x12\xA8\xCB\xAA\xF3\x55\x9B\xC0\x00\x87\x09\xE2\x1E\x68",
"\xB3\xA9\xE7\x6B\x9A\x36\xC8\x05\xE8\x06\xD1\x8C\xC0\x3C\xAA\x38\x81\x01\x6E\x14\xC4\x3E\xD0\x8E\x0E\xCC\xC3\x0A\xB0\x1B\xF5\x29\xFD\x52\xD5\x09\xBC\x2B\xB0\x42\x10\xFF\x1A\xE0\x41\xEA\x55\xAA\xC8\x06\xB9\x19\xDD\xD1\x7F\x5A\x60\x1E\x64\x8E\x3D\x72\x02\x03\x9C\x9B\x39\xF6\xB5\xDB\x67\x02\xF3\xB0\x40\x53\xD1\x0D\x9A\x22\xCA\x9F\x56\x79\x02\xAB\xCB\xF5\xEE\x1C\x97\x8A\x45\x18\x0D\x3C\x80\x66\xC0\xF4\x01\x2F\x8A\x4B\xE5\xBF\xAA\x3C\x81\x01\xDE\xDD\x61\xBC\xEB\x6B\xD7\x07\xE6\x61\x01\x4E\x45\x37\x58\x2E\x8D\x4B\xE3\xFF\x54\x7D\x02\x77\x03\x77\x75\x10\xEF\x70\x6D\x72\x5C\x2A\xA6\x34\x11\x78\x0C\xCD\x20\x29\x72\x11\xAE\xAA\x4F\x60\x80\xFD\x5B\x8C\xB1\x95\x76\x1F\x31\xD5\x47\x4C\xEC\x0A\x74\x83\xE4\xA4\xC0\x3C\x06\xAB\xC3\x04\x06\xF8\xE6\x30\x71\x75\xD2\xDE\x1F\x98\x87\x09\xD4\x79\x21\xEA\xBA\x4C\xE0\x49\xA4\x82\x7F\x8A\x7D\xF4\x08\xA9\x50\xA1\x55\xD0\x28\xE0\x76\x74\x47\xF7\x43\xE3\x52\x59\xA7\xBA\x4C\x60\x80\xD3\xC9\x9F\xCF\x40\xBB\x30\x30\x0F\xCB\xE8\x68\x74\x83\xE2\xC7\x81\x79\x0C\xA5\x4E\x13\x78\x0C\xF0\x17\xF2\xE7\xB4\x86\xF4\x2E\xF2\x9E\x71\xA9\x58\x0E\xCA\x32\x39\x2B\x81\x67\xC7\xA5\x32\xA4\x3A\x4D\x60\x80\x37\xA3\x3B\xE0\xFE\x1C\x97\xDF\xA9\x94\xB3\xD0\x0D\x06\x65\x21\xB8\x56\xD4\x6D\x02\x77\x01\x3F\x45\xB7\xDF\x94\x55\x47\x2C\xA3\xA7\xA3\x2B\x93\xF3\x30\xB0\x59\x5C\x2A\xEB\x55\xB7\x09\x0C\xB0\x3B\xBA\xF2\x3B\x7F\x05\xC6\xC6\xA5\x62\xED\xBA\x1E\xDD\x51\xFC\x5D\x81\x79\x0C\xA7\x8E\x13\x18\xE0\x62\x74\xFB\xEF\xB4\xB8\x34\xAC\x1D\x07\xA2\xDB\xF9\x7F\x20\x55\xF2\x28\x8B\xBA\x4E\xE0\x2D\x80\x7F\xA3\xD9\x87\xBD\xC0\xF6\x61\x99\x58\x4B\x36\x04\xEE\x41\x37\x81\x0F\x8C\x4B\x65\x44\xEA\x3A\x81\x01\x3E\x84\x6E\x3F\x5E\x15\x98\x87\xB5\xE0\x04\x74\x3B\xFD\x9A\xC0\x3C\x46\xAA\xCE\x13\xB8\x07\xF8\x13\xBA\xFD\xB9\x6F\x5C\x2A\x36\x12\x5B\x00\x8B\xD1\xEC\xEC\xA5\xC0\x0E\x71\xA9\x8C\x58\x2F\xF9\x72\x7C\x3C\x38\xF6\x91\x78\x0D\xBA\x09\xFC\x1B\xD2\xCB\x14\x56\x12\x17\xA1\xDB\xD9\xA7\x07\xE6\xD1\x8A\x2A\x95\x95\x6D\xD7\xF7\xD0\xED\xD7\xB7\x07\xE6\x61\xEB\xF1\x7C\xD2\x1A\x44\x8A\x9D\xFC\x37\xCA\x7B\xEB\xA1\x4A\x85\xDD\xDB\xB5\x0B\xBA\xF2\x3B\xFF\x04\x9E\x12\x97\x8A\x0D\xE5\x27\xE8\x8E\xD2\x6F\x0A\xCC\xA3\x55\x55\x59\x5A\xA5\x53\x67\xA3\xDB\xBF\x9F\x0B\xCC\xC3\xD6\x21\xE7\x20\x1E\xDC\x7E\x41\xB9\x1F\xBF\xAB\xC2\xE2\x66\x39\x8C\x03\x16\xA0\xD9\xC7\x2B\x49\x85\x0E\xAD\x00\xA3\x49\x83\x4F\xB1\x63\x57\x03\x2F\x0C\xCB\xA4\x7D\x65\x5F\x5E\x34\x97\x77\xA0\x3B\x50\xFF\x30\x30\x0F\x5B\xCB\x69\xE8\x76\xEA\xC5\x71\x69\x74\xAC\xAC\x0B\x7C\xE7\x34\x0A\xB8\x03\xDD\xFE\x3E\x24\x2E\x15\x03\xD8\x06\x5D\x99\x9C\x25\xC0\x84\xB8\x54\x3A\x36\x8A\xF6\x26\xF1\x39\x54\x6B\x25\x83\x7D\xD0\x15\x67\x98\x4B\xB9\x7F\x46\xD4\x4E\xCE\x2B\xB0\x83\xDB\x87\x02\xF3\xC8\xE9\x70\xD2\x7A\xB9\xC3\xE5\x37\x9F\x6A\x7C\x6D\x5E\x17\xE5\x7E\xFF\x60\x60\x1E\x8D\xE6\x23\xF1\xD0\x7A\x48\x17\xF6\xAE\x22\xE5\xB2\xB2\xBF\xCD\xED\xFF\xB7\x23\xA9\x76\xA1\xB7\x6D\xF1\x37\xAF\x4A\xF3\x6F\x21\x3B\x0D\xDD\xFE\xAF\xD2\xB5\x8F\x4A\xF2\xD5\x48\xF3\xDD\x87\x8A\xF2\xFD\x40\x1B\xD0\xE4\xFB\xFF\x95\xE5\x27\x72\x6C\x6D\x4D\x7D\x02\xAF\x92\xFC\x4C\xAC\x0D\xD6\xD4\x67\xE0\x2B\xC9\x6F\xA5\xD8\xBA\x28\xDF\x42\xFB\x78\x60\x1E\xB5\x76\x08\xBA\x9D\xE4\xF7\x42\xAB\xAD\x89\xEF\x81\x57\x8A\x2B\x33\xD8\x70\x9A\x56\x89\xA5\x52\x5C\x1B\xC9\x86\xD3\xB4\x5A\x68\x95\xE1\xEA\x84\x36\x52\x4D\xAA\x46\x5A\x19\xAE\x0F\x6C\xAD\x68\x4A\x3D\xF0\x4A\x70\x85\x7E\x6B\x55\x53\x56\xE4\x28\x3D\xAF\x91\x63\xED\x6A\xC2\x9A\x58\xA5\xE7\x55\xEA\xAC\x5D\x4D\x58\x95\xB2\xD4\xBC\x4E\xAC\x75\xEA\x18\x74\x27\x80\x1F\x05\xE6\x51\x49\xCA\x95\xDA\x2F\x0A\xCC\xC3\x8A\x33\x0A\xB8\x1D\xDD\x38\x3A\x34\x2E\x95\x6A\x99\x44\x5A\x21\x40\xD1\xE9\x8F\x00\x5B\xC5\xA5\x62\x05\xDB\x1B\x5D\xD1\x87\xFB\x81\x27\xC5\xA5\x52\x1D\xDF\x44\x77\xD4\x7C\x7F\x60\x1E\x56\x0E\x57\xA0\x1B\x4F\x27\x05\xE6\x51\x09\xFB\xA3\xEB\xEC\xFB\xA8\x76\x19\x19\x6B\xCF\x44\x74\xE5\x77\x1E\x05\xB6\x8E\x4B\xA5\xDC\xBA\x81\xBB\xD0\x4D\xE0\xC9\x71\xA9\x58\xC9\x9C\x8A\x6E\x5C\x5D\x1A\x97\x46\xB9\xBD\x1B\x5D\x27\x5F\x1F\x98\x47\x19\xD4\xBD\xA8\x5D\xAB\x46\x03\x0F\xA0\x19\x5B\x7D\xC0\x8B\xE2\x52\x29\xA7\xF1\xC0\xBF\xD0\x74\xF0\x72\x60\xE7\xB8\x54\x0A\xD7\x84\xB2\xB2\xED\x98\x8A\xEE\x04\x71\x27",
"\xD5\xAA\xAD\x9D\xDD\xB9\xE8\x3A\xF7\x33\x81\x79\x14\xA9\x29\x85\xDD\x3B\x71\x33\xBA\x71\xF6\xD6\xC0\x3C\x4A\x65\x57\x74\x65\x72\x1E\x04\x9E\x1C\x97\x4A\xA1\x9A\xB0\xB4\x4A\xA7\x76\x23\xFD\x94\x50\x8C\xB5\x85\xA4\x82\x8B\x8D\x73\x23\xBA\xA3\xE2\xD1\x81\x79\x14\xA9\x29\x8B\x9B\xE5\x70\x01\xBA\xF1\x36\x23\x30\x8F\x52\x38\x0C\x5D\x67\xCE\xA6\x19\x5F\x0D\x9B\xB2\xBC\x68\x2E\x9B\x02\x0F\xA1\x19\x73\xCB\x81\x67\xC4\xA5\x52\xAC\x1E\xE0\x5E\x34\x1D\xD9\x07\xBC\x34\x2E\x95\x42\x35\x65\x81\xEF\x9C\x8E\x47\x77\xE2\x98\x19\x98\x47\xA1\x4E\x42\xD7\x89\x5F\x0F\xCC\xA3\x68\x39\x17\xFA\xBA\x3A\x38\xF6\xA2\x6C\x00\xFC\x1E\xDD\xF8\x3B\x38\x2E\x95\x62\x6C\x49\x7A\x2E\x59\xD1\x79\xBD\xC0\x76\x71\xA9\x14\x2E\xC7\xD7\xE7\x81\x36\x2F\x38\xF6\x22\xBD\x1C\xDD\x04\x9E\x43\xAA\xD1\x55\x5B\x5F\x45\xD7\x79\xA7\x04\xE6\x51\x06\x4B\xC9\xD7\x77\x4B\x83\x63\x2F\xDA\x75\xE8\xC6\xE1\xB1\x81\x79\x84\xDA\x03\x5D\x99\x9C\xF9\xA4\x77\x89\x9B\x24\x67\xF9\x98\x65\xC1\xB1\x17\xED\x69\xE8\xCA\xEF\x2C\x02\x36\x8F\x4B\x25\x46\x17\xF0\x33\x74\x47\xBD\xD7\xC7\xA5\x52\x1A\x39\x0B\x1F\xFC\x25\x38\xF6\x32\xF8\x14\xBA\xF1\x78\x5E\x60\x1E\x21\xA6\xA1\xEB\xAC\x5B\x69\x66\x99\x9C\x59\xE4\xEB\xC3\x59\xC1\xB1\x97\x81\xB2\xFC\xCE\x2A\xE0\x39\x71\xA9\x68\x6D\x0C\xFC\x1D\x5D\x47\x3D\x37\x2E\x95\x52\x39\x8A\x7C\xFD\x38\x3D\x36\xF4\xD2\x98\x8E\xEE\xC4\x72\x53\x5C\x1A\x5A\x33\xD0\x75\xD2\xF9\x81\x79\x94\xCD\x58\xD2\x63\x7C\x9D\xF6\xE1\x42\x9A\x5B\x66\xB7\x0B\xB8\x0D\xDD\xF8\x9C\x12\x97\x8A\xC6\x8E\xE4\xBD\x5A\xBA\x76\xAB\xE5\xC5\x82\x16\xE5\x28\xE0\x76\x4C\x78\xD4\xE5\xB2\x17\xBA\xF2\x3B\xF3\xA8\x78\xF9\x9D\x6B\xD1\x1D\xDD\x8E\x0B\xCC\xA3\xCC\xAE\xA4\xFD\x3E\xBC\xB2\x80\x78\xCB\xE8\x32\x74\xE3\xF4\xC3\x81\x79\x64\xB5\x2F\xBA\x4E\xB9\x9B\x9A\xDF\x30\x6F\x41\x0F\xF0\x0D\x5A\xEF\xC3\x6F\xD0\xAC\x97\xFB\xD7\x67\x22\xA9\x4C\x8E\x62\xAC\x3E\x4A\x5A\xE7\xAB\x72\x6E\x41\x37\x81\x0F\x8A\x4B\xA3\x12\xBA\x80\xF7\x32\xB2\xA7\xDC\x1E\xE9\xFF\xDB\x26\x5E\xB9\x5F\x9F\x93\xD1\x8D\xD7\xB3\x02\xF3\xC8\x62\x07\x74\xBF\x2B\xAE\x0B\xCC\xA3\x6A\xC6\x93\xD6\xCB\xFD\x29\xE9\xD1\xD2\x81\x3E\xEB\xED\xFF\xB7\x13\xFA\xFF\xC6\x9E\x68\x23\x74\x2F\xD9\x2C\xA4\x62\x0B\xC9\xAB\x5E\x58\x58\x0E\xEC\x14\x98\x47\xD5\x8D\xC7\x13\xB6\x15\x53\xD0\x9D\x85\xF7\x8B\x4B\xA3\x73\xB3\xD1\x74\xC2\x99\x91\x49\x58\x23\x7D\x1F\xCD\xD8\xFD\x62\x64\x12\x9D\x98\x80\xA6\x03\x16\x90\x9E\x9E\x31\x53\x7A\x36\x9A\xF2\x3B\x95\x79\x5C\xF5\x50\x34\x13\x78\x7A\x60\x0E\xD6\x6C\xE7\xA1\x19\xC3\x95\x58\xDE\xE7\x13\xE4\x4F\xBC\xF1\xE5\x3B\x2D\x94\xAA\xDC\xF1\xAB\x73\x07\xAA\x98\x14\xBB\x67\xDE\xDE\x1A\xD2\x6D\x8F\xBE\xCC\xDB\x35\x1B\xCA\x62\xE0\x63\x82\xED\xEE\x21\xD8\x66\x76\xB9\x4B\x96\x34\xA9\x4C\x8E\x95\xC7\x06\xA4\x07\x86\x72\x8E\xE5\x8B\x73\x07\xA9\x38\x03\xE7\x7E\xEA\xE4\x92\xCC\xDB\x33\x1B\x89\x55\xC0\xE5\x99\xB7\x99\xFD\xD9\xFD\xDC\x13\xB8\x9B\xFC\x41\xDE\x91\x79\x7B\x66\x23\x75\x67\xE6\xED\x95\x7E\x02\x8F\xCD\xBC\xCD\xC7\x48\x8F\xFE\x99\x15\x61\x41\xE6\xED\x65\x5F\x2D\x24\xF7\x04\x6E\x5A\x6D\x25\xAB\xB7\xDC\xCF\x8B\x2F\xCF\xBC\xBD\xEC\x13\x78\x05\x79\xAF\x16\x6F\x8C\x1F\xDE\xB0\xE2\x4C\xC8\xBC\xBD\xC7\x33\x6F\x4F\x72\x11\x2B\x77\x89\xD2\x4A\x5C\x7A\xB7\x5A\xDA\x33\xF3\xF6\x7A\x33\x6F\x4F\x32\x81\x73\x3F\x32\x76\x58\xE6\xED\x99\x8D\x54\xEE\xB1\xB7\x30\xF3\xF6\x24\x13\xF8\xDE\xCC\xDB\x9B\x86\xDF\xA8\xB1\x78\x2F\x21\xFF\x19\x78\x4E\xE6\xED\x55\x62\x02\x8F\x07\x4E\xCF\xBC\x4D\xB3\xF5\xD9\x10\x38\x5B\xB0\xDD\xBB\x05\xDB\xCC\xEE\x8D\xE4\x7F\x86\xB4\x0F\x98\x1A\x99\x84\x35\xDA\xB9\x68\x5E\x66\xD8\x2E\x32\x89\x76\x6D\x81\x66\x09\x95\x65\xC0\x1B\x02\xF3\xB0\xE6\xE9\x26\x9D\x79\x15\x93\x37\xF7\x37\x53\xA9\x5F\xA3\xE9\x84\x3E\xE0\x4B\xB8\x9C\xAC\xE5\xF7\x2C\xD2\x2A\x1F\x8A\x71\xBB\x06\xCD\x57\x72\x99\x33\xD0\x75\xC4\x1A\x52\xA5\xBF\x0B\x49\xAF\x67\xE5\xBE\x57\x67\xCD\x30\x06\xD8\x99\xF4\x9E\xF9\x77\xD1\x2D\xBC\x37\xD0\x24\x85\x18\x55\x95\x09\x77\x02\xEE\x11\x6E\xDF\xAC\x4A\x16\x92\x7E\xFF\xAE\xC8\xBD\x61\xD5\x4B\xF2\xF7\x52\xA3\xB5\x61\xCC\x3A\x74\x21\x82\xC9\x0B\xDA\x52\x97\xBD\xF8\xA2\x93\xD9\x0A\xE0\x2D\xA4\x17\x73\xB2\x53\x96\xA9\x99\x45\x45\xEE\x7B\x99\x09\x5D\x81\xE0\x09\xAC\x01\xEA\xDF\xA8\xAF\x22\x5D\x20\x30\x6B\xA2\xC7\x80\x5D\x48\xCB\xEB",
"\x4A\xA8\x0B\xC5\x7D\x0F\xF8\xA1\xF8\x33\xCC\xCA\x6A\x06\xC2\xC9\x0B\x31\x57\x89\x77\x21\xDD\x17\x1E\x13\xF0\x59\x66\x65\x31\x97\x54\x63\x5A\xFA\x8E\x7C\xC4\x7A\x2D\x0F\x91\x4A\x74\xBE\x26\xE0\xB3\xCC\xCA\x60\x19\x30\x19\xF8\xAB\xFA\x83\xA2\x16\x5C\x9A\x4D\x7A\xD2\xE5\x99\x41\x9F\x67\x56\xA4\x63\x81\xEB\x23\x3E\x28\xF2\x41\x8B\x71\xC0\xCD\xE4\xAF\x1B\x6D\x56\x26\x97\x02\x47\x45\x7D\x58\xF4\x93\x52\x9B\x93\x96\xB9\xDC\x35\xF8\x73\xCD\x22\xCC\x04\x8E\x20\x95\xA4\x0D\x51\xC4\xA3\x8E\x93\x80\x9F\x00\xDB\x17\xF0\xD9\x66\x2A\xB3\x48\x0F\x2E\xAD\x8C\xFC\xD0\x22\xD6\x1B\x9A\x0F\xEC\x05\xDC\x56\xC0\x67\x9B\x29\x5C\x4A\x3A\xF3\x86\x4E\xDE\xA2\x6D\x44\xAA\x7C\xAF\x7C\x03\xC4\xCD\x4D\xD9\x56\x02\x27\x52\xA0\xA8\xAB\xD0\xEB\xB2\x1A\xB8\x96\x54\x3C\xFB\x65\xA4\x09\x6D\x56\x15\x0F\x00\x53\x48\x8F\x4A\x36\xDE\x24\x74\x2B\xA3\xBB\xB9\xE5\x6C\x2B\x80\x4F\xE2\x07\x93\xD6\x69\x32\x70\x3B\xC5\xEF\x24\x37\xB7\xC1\x6D\x35\xF0\x2D\x60\x37\x6C\x58\x87\x90\xCE\xC8\xAB\x28\x7E\xC7\xB9\x35\xBB\x2D\x05\x2E\x22\x15\xA9\x28\x9D\xB2\x57\xCC\x98\x08\xBC\x99\x74\x79\xFE\x79\x14\xFB\x9B\xDD\x9A\xA3\x97\xF4\x22\xCE\x4C\xD2\xDB\x74\x4B\x8A\x0D\x67\x68\x65\x9F\xC0\x6B\xDB\x04\xD8\x1B\xD8\x87\x54\xCB\x68\x1B\x52\x99\x92\x09\x78\x62\x5B\xEB\x96\x01\x8B\x80\xC5\xC0\xC3\xC0\x1F\x49\x8F\xFC\xFE\x86\xB4\x48\xBD\x17\xEA\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\xAB\x80\xFF\x00\x35\x85\x34\xED\x1E\xFC\xAB\x96\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x4D\x65\x73\x73\x61\x67\x65\x42\x6F\x78\x43\x6F\x6D\x70\x6F\x6E\x65\x6E\x74\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x50\x72\x65\x63\x6F\x6D\x70\x69\x6C\x65\x64\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x0F\x00\x00\x00\x00\x00\x00\x00\x0F\x00\x00\x00\x43\x6C\x61\x73\x73\x4E\x61\x6D\x65\x52\x65\x63\x6F\x72\x64\x0B\x00\x00\x00\x00\x00\x00\x00\x26\x00\x00\x00\x00\x00\x00\x00\x26\x00\x00\x00\x67\x61\x63\x6C\x69\x62\x5F\x63\x6F\x6E\x74\x72\x6F\x6C\x73\x3A\x3A\x43\x6F\x6C\x6F\x72\x43\x6F\x6D\x70\x6F\x6E\x65\x6E\x74\x43\x6F\x6E\x74\x72\x6F\x6C\x23\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x67\x61\x63\x6C\x69\x62\x5F\x63\x6F\x6E\x74\x72\x6F\x6C\x73\x3A\x3A\x43\x6F\x6C\x6F\x72\x44\x69\x61\x6C\x6F\x67\x43\x6F\x6E\x74\x72\x6F\x6C\x22\x00\x00\x00\x00\x00\x00\x00\x22\x00\x00\x00\x67\x61\x63\x6C\x69\x62\x5F\x63\x6F\x6E\x74\x72\x6F\x6C\x73\x3A\x3A\x43\x6F\x6C\x6F\x72\x44\x69\x61\x6C\x6F\x67\x57\x69\x6E\x64\x6F\x77\x21\x00\x00\x00\x00\x00\x00\x00\x21\x00\x00\x00\x67\x61\x63\x6C\x69\x62\x5F\x63\x6F\x6E\x74\x72\x6F\x6C\x73\x3A\x3A\x46\x69\x6C\x65\x44\x69\x61\x6C\x6F\x67\x57\x69\x6E\x64\x6F\x77\x22\x00\x00\x00\x00\x00\x00\x00\x22\x00\x00\x00\x67\x61\x63\x6C\x69\x62\x5F\x63\x6F\x6E\x74\x72\x6F\x6C\x73\x3A\x3A\x46\x69\x6C\x65\x50\x69\x63\x6B\x65\x72\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x67\x61\x63\x6C\x69\x62\x5F\x63\x6F\x6E\x74\x72\x6F\x6C\x73\x3A\x3A\x46\x6F\x6E\x74\x4E\x61\x6D\x65\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x67\x61\x63\x6C\x69\x62\x5F\x63\x6F\x6E\x74\x72\x6F\x6C\x73\x3A\x3A\x46\x6F\x6E\x74\x53\x69\x7A\x65\x43\x6F\x6E\x74\x72\x6F\x6C\x25\x00\x00\x00\x00\x00\x00\x00\x25\x00\x00\x00\x67\x61\x63\x6C\x69\x62\x5F\x63\x6F\x6E\x74\x72\x6F\x6C\x73\x3A\x3A\x46\x75\x6C\x6C\x46\x6F\x6E\x74\x44\x69\x61\x6C\x6F\x67\x57\x69\x6E\x64\x6F\x77\x27\x00\x00\x00\x00\x00\x00\x00\x27\x00\x00\x00\x67\x61\x63\x6C\x69\x62\x5F\x63\x6F\x6E\x74\x72\x6F\x6C\x73\x3A\x3A\x53\x69\x6D\x70\x6C\x65\x46\x6F\x6E\x74\x44\x69\x61\x6C\x6F\x67\x57\x69\x6E\x64\x6F\x77\x29\x00\x00\x00\x00\x00\x00\x00\x29\x00\x00\x00\x67\x61\x63\x6C\x69\x62\x5F\x63\x6F\x6E\x74\x72\x6F\x6C\x73\x3A\x3A\x4D\x65\x73\x73\x61",
"\x67\x65\x42\x6F\x78\x42\x75\x74\x74\x6F\x6E\x54\x65\x6D\x70\x6C\x61\x74\x65\x21\x00\x00\x00\x00\x00\x00\x00\x21\x00\x00\x00\x67\x61\x63\x6C\x69\x62\x5F\x63\x6F\x6E\x74\x72\x6F\x6C\x73\x3A\x3A\x4D\x65\x73\x73\x61\x67\x65\x42\x6F\x78\x57\x69\x6E\x64\x6F\x77\x00\x00\x00\x00\x00\x00\x00\x00",
};
class GuiFakeDialogServiceUIResourceLoaderPlugin : public Object, public IGuiPlugin
{
public:
GUI_PLUGIN_NAME(GacGen_GuiFakeDialogServiceUIResourceLoader)
{
GUI_PLUGIN_DEPEND(GacUI_Res_Resource);
GUI_PLUGIN_DEPEND(GacUI_Res_TypeResolvers);
#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA
GUI_PLUGIN_DEPEND(GacUI_Instance_Reflection);
GUI_PLUGIN_DEPEND(GacUI_Compiler_WorkflowTypeResolvers);
#endif
}
void Load(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override
{
if (controllerRelatedPlugins)
{
List<GuiResourceError> errors;
MemoryStream resourceStream;
GuiFakeDialogServiceUIResourceReader::ReadToStream(resourceStream);
resourceStream.SeekFromBegin(0);
GetResourceManager()->LoadResourceOrPending(resourceStream, GuiResourceUsage::InstanceClass);
}
}
void Unload(bool controllerUnrelatedPlugins, bool controllerRelatedPlugins)override
{
}
};
GUI_REGISTER_PLUGIN(GuiFakeDialogServiceUIResourceLoaderPlugin)
}
}
}
/***********************************************************************
.\UTILITIES\SHAREDSERVICES\GUISHAREDASYNCSERVICE.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
using namespace collections;
/***********************************************************************
SharedAsyncService::TaskItem
***********************************************************************/
SharedAsyncService::TaskItem::TaskItem()
:semaphore(0)
{
}
SharedAsyncService::TaskItem::TaskItem(Semaphore* _semaphore, const Func<void()>& _proc)
:semaphore(_semaphore)
,proc(_proc)
{
}
SharedAsyncService::TaskItem::~TaskItem()
{
}
/***********************************************************************
SharedAsyncService::DelayItem
***********************************************************************/
SharedAsyncService::DelayItem::DelayItem(SharedAsyncService* _service, const Func<void()>& _proc, bool _executeInMainThread, vint milliseconds)
:service(_service)
,proc(_proc)
,status(INativeDelay::Pending)
, executeUtcTime(DateTime::UtcTime().Forward(milliseconds))
,executeInMainThread(_executeInMainThread)
{
}
SharedAsyncService::DelayItem::~DelayItem()
{
}
INativeDelay::ExecuteStatus SharedAsyncService::DelayItem::GetStatus()
{
return status;
}
bool SharedAsyncService::DelayItem::Delay(vint milliseconds)
{
SPIN_LOCK(service->taskListLock)
{
if(status==INativeDelay::Pending)
{
executeUtcTime =DateTime::UtcTime().Forward(milliseconds);
return true;
}
}
return false;
}
bool SharedAsyncService::DelayItem::Cancel()
{
SPIN_LOCK(service->taskListLock)
{
if(status==INativeDelay::Pending)
{
if(service->delayItems.Remove(this))
{
status=INativeDelay::Canceled;
return true;
}
}
}
return false;
}
/***********************************************************************
SharedAsyncService
***********************************************************************/
SharedAsyncService::SharedAsyncService()
:mainThreadId(Thread::GetCurrentThreadId())
{
}
SharedAsyncService::~SharedAsyncService()
{
}
void SharedAsyncService::ExecuteAsyncTasks()
{
auto now=DateTime::UtcTime();
Array<TaskItem> items;
List<Ptr<DelayItem>> executableDelayItems;
SPIN_LOCK(taskListLock)
{
CopyFrom(items, taskItems);
taskItems.RemoveRange(0, items.Count());
// TODO: (enumerable) foreach:indexed(alterable(reversed))
for(vint i=delayItems.Count()-1;i>=0;i--)
{
Ptr<DelayItem> item=delayItems[i];
if(now >= item->executeUtcTime)
{
item->status=INativeDelay::Executing;
executableDelayItems.Add(item);
delayItems.RemoveAt(i);
}
}
}
for (auto item : items)
{
item.proc();
if(item.semaphore)
{
item.semaphore->Release();
}
}
for (auto item : executableDelayItems)
{
if(item->executeInMainThread)
{
item->proc();
item->status=INativeDelay::Executed;
}
else
{
InvokeAsync([=]()
{
item->proc();
item->status=INativeDelay::Executed;
});
}
}
}
bool SharedAsyncService::IsInMainThread(INativeWindow* window)
{
return Thread::GetCurrentThreadId()==mainThreadId;
}
void SharedAsyncService::InvokeAsync(const Func<void()>& proc)
{
ThreadPoolLite::Queue(proc);
}
void SharedAsyncService::InvokeInMainThread(INativeWindow* window, const Func<void()>& proc)
{
SPIN_LOCK(taskListLock)
{
TaskItem item(0, proc);
taskItems.Add(item);
}
}
bool SharedAsyncService::InvokeInMainThreadAndWait(INativeWindow* window, const Func<void()>& proc, vint milliseconds)
{
Semaphore semaphore;
semaphore.Create(0, 1);
SPIN_LOCK(taskListLock)
{
TaskItem item(&semaphore, proc);
taskItems.Add(item);
}
#ifdef VCZH_MSVC
if(milliseconds<0)
{
return semaphore.Wait();
}
else
{
return semaphore.WaitForTime(milliseconds);
}
#else
return semaphore.Wait();
#endif
}
Ptr<INativeDelay> SharedAsyncService::DelayExecute(const Func<void()>& proc, vint milliseconds)
{
Ptr<DelayItem> delay;
SPIN_LOCK(taskListLock)
{
delay=Ptr(new DelayItem(this, proc, false, milliseconds));
delayItems.Add(delay);
}
return delay;
}
Ptr<INativeDelay> SharedAsyncService::DelayExecuteInMainThread(const Func<void()>& proc, vint milliseconds)
{
Ptr<DelayItem> delay;
SPIN_LOCK(taskListLock)
{
delay=Ptr(new DelayItem(this, proc, true, milliseconds));
delayItems.Add(delay);
}
return delay;
}
}
}
/***********************************************************************
.\UTILITIES\SHAREDSERVICES\GUISHAREDCALLBACKSERVICE.CPP
***********************************************************************/
namespace vl
{
namespace presentation
{
/***********************************************************************
SharedCallbackService
***********************************************************************/
SharedCallbackService::SharedCallbackService()
{
}
SharedCallbackService::~SharedCallbackService()
{
}
bool SharedCallbackService::InstallListener(INativeControllerListener* listener)
{
if(listeners.Contains(listener))
{
return false;
}
else
{
listeners.Add(listener);
return true;
}
}
bool SharedCallbackService::UninstallListener(INativeControllerListener* listener)
{
if(listeners.Contains(listener))
{
listeners.Remove(listener);
return true;
}
else
{
return false;
}
}
INativeCallbackInvoker* SharedCallbackService::Invoker()
{
return this;
}
void SharedCallbackService::InvokeGlobalTimer()
{
// TODO: (enumerable) foreach
for(vint i=0;i<listeners.Count();i++)
{
listeners[i]->GlobalTimer();
}
}
void SharedCallbackService::InvokeClipboardUpdated()
{
// TODO: (enumerable) foreach
for(vint i=0;i<listeners.Count();i++)
{
listeners[i]->ClipboardUpdated();
}
}
void SharedCallbackService::InvokeGlobalShortcutKeyActivated(vint id)
{
// TODO: (enumerable) foreach
for (vint i = 0; i < listeners.Count(); i++)
{
listeners[i]->GlobalShortcutKeyActivated(id);
}
}
void SharedCallbackService::InvokeNativeWindowCreated(INativeWindow* window)
{
// TODO: (enumerable) foreach
for(vint i=0;i<listeners.Count();i++)
{
listeners[i]->NativeWindowCreated(window);
}
}
void SharedCallbackService::InvokeNativeWindowDestroying(INativeWindow* window)
{
// TODO: (enumerable) foreach
for(vint i=0;i<listeners.Count();i++)
{
listeners[i]->NativeWindowDestroying(window);
}
}
}
}