160 lines
6.3 KiB
C
160 lines
6.3 KiB
C
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
// NoesisGUI - http://www.noesisengine.com
|
||
|
|
// Copyright (c) Noesis Technologies S.L. All Rights Reserved.
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
|
||
|
|
#ifndef __GUI_FREEZABLE_H__
|
||
|
|
#define __GUI_FREEZABLE_H__
|
||
|
|
|
||
|
|
|
||
|
|
#include <NsCore/Noesis.h>
|
||
|
|
#include <NsGui/DependencySystemApi.h>
|
||
|
|
#include <NsGui/DependencyObject.h>
|
||
|
|
#include <NsGui/ISealable.h>
|
||
|
|
|
||
|
|
|
||
|
|
namespace Noesis
|
||
|
|
{
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
/// Type of change occurred in the freezable
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
enum FreezableEventReason: int32_t
|
||
|
|
{
|
||
|
|
FreezableEventReason_Frozen,
|
||
|
|
FreezableEventReason_PropertyChanged
|
||
|
|
};
|
||
|
|
|
||
|
|
NS_WARNING_PUSH
|
||
|
|
NS_MSVC_WARNING_DISABLE(4251 4275)
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
/// Defines an object that has a modifiable state and a read-only (frozen) state.
|
||
|
|
///
|
||
|
|
/// Classes that derive from Freezable provide detailed change notification, can be made immutable,
|
||
|
|
/// and can clone themselves. The Freezable class provides special features that can help improve
|
||
|
|
/// application performance when using objects that are expensive to modify or copy.
|
||
|
|
///
|
||
|
|
/// A class that derives from Freezable gains the following features:
|
||
|
|
///
|
||
|
|
/// * Special states: a read-only (frozen) state and a writable state.
|
||
|
|
/// * Thread safety: a frozen Freezable object can be shared across threads.
|
||
|
|
/// * Detailed change notification: Unlike other DependencyObject objects, a Freezable object
|
||
|
|
/// provides change notifications when sub-property values change
|
||
|
|
/// * Easy cloning: the Freezable class has already implemented several methods that produce
|
||
|
|
/// deep clones
|
||
|
|
///
|
||
|
|
/// https://docs.microsoft.com/en-us/dotnet/api/system.windows.freezable
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
class NS_GUI_DEPENDENCYSYSTEM_API Freezable: public DependencyObject, public ISealable
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
Freezable();
|
||
|
|
virtual ~Freezable() = 0;
|
||
|
|
|
||
|
|
/// Gets a value that indicates whether the object can be made unmodifiable.
|
||
|
|
/// \prop
|
||
|
|
bool CanFreeze() const;
|
||
|
|
|
||
|
|
/// Gets a value that indicates whether the object is currently modifiable.
|
||
|
|
/// \prop
|
||
|
|
bool IsFrozen() const;
|
||
|
|
|
||
|
|
/// Makes the current object unmodifiable and sets its IsFrozen property to true.
|
||
|
|
void Freeze();
|
||
|
|
|
||
|
|
/// Creates a modifiable clone of the Freezable, making deep copies of the object's values.
|
||
|
|
/// When copying the object's dependency properties, this method copies expressions (which
|
||
|
|
/// might no longer resolve) but not animations or their current values.
|
||
|
|
/// The cloned Freezable::IsFrozen property is false even if the source's IsFrozen property is
|
||
|
|
/// true.
|
||
|
|
/// \note The cloned element is not initialized
|
||
|
|
Ptr<Freezable> Clone() const;
|
||
|
|
|
||
|
|
/// Creates a modifiable clone (deep copy) of the Freezable using its current values.
|
||
|
|
/// The cloned object's IsFrozen property is false even if the source's IsFrozen property is
|
||
|
|
/// true.
|
||
|
|
/// \note The cloned element is not initialized
|
||
|
|
Ptr<Freezable> CloneCurrentValue() const;
|
||
|
|
|
||
|
|
/// Creates a frozen copy of the Freezable, using base (non-animated) property values. Because
|
||
|
|
/// the copy is frozen, any frozen sub-objects are copied by reference.
|
||
|
|
/// The copy's IsFrozen property is set to true.
|
||
|
|
/// Throws if the Freezable cannot be frozen because it contains expressions or animated
|
||
|
|
/// properties.
|
||
|
|
/// \note The cloned element is not initialized
|
||
|
|
Ptr<Freezable> GetAsFrozen() const;
|
||
|
|
|
||
|
|
/// Creates a frozen copy of the Freezable using current property values. Because the copy is
|
||
|
|
/// frozen, any frozen sub-objects are copied by reference.
|
||
|
|
/// The copy's IsFrozen property is set to true.
|
||
|
|
/// \note The cloned element is not initialized
|
||
|
|
Ptr<Freezable> GetCurrentValueAsFrozen() const;
|
||
|
|
|
||
|
|
/// Occurs when the Freezable or an object it contains is modified.
|
||
|
|
typedef Delegate<void (Freezable*, FreezableEventReason)> FreezableChangedEvent;
|
||
|
|
FreezableChangedEvent& Changed();
|
||
|
|
|
||
|
|
/// From ISealable
|
||
|
|
//@{
|
||
|
|
bool CanSeal() const final override;
|
||
|
|
bool IsSealed() const final override;
|
||
|
|
void Seal() final override;
|
||
|
|
//@}
|
||
|
|
|
||
|
|
NS_IMPLEMENT_INTERFACE_FIXUP
|
||
|
|
|
||
|
|
protected:
|
||
|
|
/// Makes the Freezable object unmodifiable or tests whether it can be made unmodifiable.
|
||
|
|
virtual bool FreezeCore(bool isChecking);
|
||
|
|
|
||
|
|
/// Makes the instance a clone (deep copy) of the specified Freezable using base (non-animated)
|
||
|
|
/// property values.
|
||
|
|
virtual void CloneCore(const Freezable* source);
|
||
|
|
|
||
|
|
/// Makes the instance a modifiable clone (deep copy) of the specified Freezable using current
|
||
|
|
/// property values.
|
||
|
|
virtual void CloneCurrentValueCore(const Freezable* source);
|
||
|
|
|
||
|
|
/// Makes the instance a frozen clone of the specified Freezable using base (non-animated)
|
||
|
|
/// property values.
|
||
|
|
virtual void GetAsFrozenCore(const Freezable* source);
|
||
|
|
|
||
|
|
/// Makes the current instance a frozen clone of the specified Freezable. If the object has
|
||
|
|
/// animated dependency properties, their current animated values are copied.
|
||
|
|
virtual void GetCurrentValueAsFrozenCore(const Freezable* source);
|
||
|
|
|
||
|
|
/// Called at the end of CloneCommon (this implies this method is called at the end of
|
||
|
|
/// CloneCore, CloneCurrentValueCore, GetAsFrozenValue and GetCurrentValueAsFrozenCore
|
||
|
|
virtual void CloneCommonCore(const Freezable* source);
|
||
|
|
|
||
|
|
/// When implemented in a derived class, creates a new instance of the Freezable derived class.
|
||
|
|
virtual Ptr<Freezable> CreateInstanceCore() const = 0;
|
||
|
|
|
||
|
|
/// Called when the current Freezable object is modified.
|
||
|
|
virtual void OnChanged(FreezableEventReason reason);
|
||
|
|
|
||
|
|
/// Raises modification event
|
||
|
|
void RaiseEvent(FreezableEventReason reason);
|
||
|
|
|
||
|
|
/// From DependencyObject
|
||
|
|
//@{
|
||
|
|
bool OnPropertyChanged(const DependencyPropertyChangedEventArgs& e) override;
|
||
|
|
//@}
|
||
|
|
|
||
|
|
private:
|
||
|
|
void CloneCommon(const Freezable* source, bool useBaseValue, bool cloneFreezables);
|
||
|
|
|
||
|
|
private:
|
||
|
|
FreezableChangedEvent mFreezableChangedEvent;
|
||
|
|
|
||
|
|
NS_DECLARE_REFLECTION(Freezable, DependencyObject)
|
||
|
|
};
|
||
|
|
|
||
|
|
NS_WARNING_POP
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|