Initial release

This commit is contained in:
civ
2026-08-16 18:24:52 +07:00
commit 876886a39a
13244 changed files with 2353959 additions and 0 deletions
@@ -0,0 +1,42 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#pragma once
#include "../appinit.h"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
namespace Application {
//------------------------------------------------------------------------
/** %Application delegate adapter
*
* @ingroup standalone
*/
class DelegateAdapter : public IDelegate
{
public:
DelegateAdapter (Info&& info) : appInfo (std::move (info)) {}
void finishLaunching () override {}
void onQuit () override {}
bool canQuit () override { return true; }
void showAboutDialog () override {}
bool hasAboutDialog () override { return false; }
void showPreferenceDialog () override {}
bool hasPreferenceDialog () override { return false; }
const Info& getInfo () const override { return appInfo; }
UTF8StringPtr getSharedUIResourceFilename () const override { return nullptr; }
bool openFiles (const std::vector<UTF8String>& paths) override { return false; }
//------------------------------------------------------------------------
private:
Info appInfo;
};
//------------------------------------------------------------------------
} // Application
} // Standalone
} // VSTGUI
@@ -0,0 +1,100 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#pragma once
#include "../iasync.h"
#include <atomic>
#include <vector>
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
namespace Async {
//------------------------------------------------------------------------
/** Group of asynchronous tasks. */
struct Group final : std::enable_shared_from_this<Group>
{
/** Create a new group.
*
* Note that all calls to the group must be from one thread. If you want to call them from
* different threads, you have to lock the access of it with a mutex yourself.
*
* @param queue the queue where to schedule the groups tasks
* @return a shared pointer to the new group
*/
static GroupPtr make (QueuePtr queue) { return GroupPtr (new Group (queue)); }
/** Add a task to the group.
*
* If the group was started, new tasks cannot be added.
*
* @param task the task to add
* @return true on success
*/
template <typename T>
bool add (T&& task)
{
if (started == true)
return false;
unscheduledTasks.emplace_back (std::forward<T> (task));
return true;
}
/** Start the groups tasks
*
* A group can only be started once. The optional finishTask is performed after all tasks in
* this group have executed. The finish task will execute on the same queue as the tasks.
*
* @param finishTask an optional task to run after all group tasks were executed.
* @return true on success
*/
bool start (Task&& finishTask = nullptr)
{
if (started == true)
return false;
started = true;
finalizerTask = std::move (finishTask);
if (unscheduledTasks.empty ())
{
if (finalizerTask)
schedule (queue, std::move (finalizerTask));
return true;
}
taskCounter.store (unscheduledTasks.size ());
for (auto& t : unscheduledTasks)
{
schedule (queue, [task = std::move (t), g = shared_from_this ()] () {
task ();
g->taskDone ();
});
}
unscheduledTasks.clear ();
return true;
}
private:
Group (QueuePtr queue) : queue (queue) {}
void taskDone ()
{
if (--taskCounter == 0 && finalizerTask)
{
finalizerTask ();
finalizerTask = nullptr;
}
}
QueuePtr queue;
Task finalizerTask;
std::vector<Task> unscheduledTasks;
std::atomic<size_t> taskCounter {0};
bool started {false};
};
//------------------------------------------------------------------------
} // Async
} // Standalone
} // VSTGUI
@@ -0,0 +1,66 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#pragma once
#include "../imenubuilder.h"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
/** Menu builder adapter
*
* @ingroup standalone
*/
class MenuBuilderAdapter : public IMenuBuilder
{
public:
bool showCommandGroupInMenu (const Interface& context, const UTF8String& group) const override
{
return true;
}
bool showCommandInMenu (const Interface& context, const Command& cmd) const override
{
return true;
}
SortFunction getCommandGroupSortFunction (const Interface& context,
const UTF8String& group) const override
{
return {};
}
bool prependMenuSeparator (const Interface& context, const Command& cmd) const override
{
return false;
}
};
//------------------------------------------------------------------------
/** No menu builder adapter
*
* Use this to prevent a window to have a menu
*
* @ingroup standalone
*/
class NoMenuBuilder : public MenuBuilderAdapter
{
public:
bool showCommandGroupInMenu (const Interface& context, const UTF8String& group) const override
{
return false;
}
bool showCommandInMenu (const Interface& context, const Command& cmd) const override
{
return false;
}
};
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -0,0 +1,139 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#pragma once
#include "../ipreference.h"
#include "../iapplication.h"
#include <sstream>
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
static constexpr const char* DefaultPreferencesGroupSeparator = "::";
//------------------------------------------------------------------------
class Preferences
{
public:
Preferences (Preferences&&) = default;
Preferences& operator= (Preferences&&) = default;
Preferences (const std::initializer_list<const char*>& groups,
const char* groupSeparator = DefaultPreferencesGroupSeparator)
: groupSeparator (groupSeparator)
{
for (auto& g : groups)
groupKey += UTF8String (g) + groupSeparator;
}
Preferences (const UTF8String& inGroupKey = "",
const char* groupSeparator = DefaultPreferencesGroupSeparator)
: groupKey (inGroupKey), groupSeparator (groupSeparator)
{
if (!groupKey.empty ())
groupKey += groupSeparator;
}
inline Preferences subGroupPreferences (const UTF8String& subGroup) const
{
return Preferences (groupKey + subGroup, groupSeparator);
}
inline bool set (const UTF8String& key, const UTF8String& value) const
{
if (!groupKey.empty ())
return preferences->set (groupKey + key, value);
return preferences->set (key, value);
}
inline Optional<UTF8String> get (const UTF8String& key) const
{
if (!groupKey.empty ())
return preferences->get (groupKey + key);
return preferences->get (key);
}
template <typename T>
inline bool setNumber (const UTF8String& key, T value) const
{
return set (key, toString (value));
}
template <typename T>
inline bool setFloat (const UTF8String& key, T value, uint32_t precision = 8) const
{
std::ostringstream sstream;
sstream.imbue (std::locale::classic ());
sstream.precision (static_cast<std::streamsize> (precision));
sstream << value;
return set (key, UTF8String (sstream.str ()));
}
template <typename T>
inline Optional<T> getNumber (const UTF8String& key) const
{
if (auto p = get (key))
{
if constexpr (std::is_floating_point<T>::value)
return UTF8StringView (*p).toFloat ();
return UTF8StringView (*p).toNumber<T> ();
}
return {};
}
inline bool setPoint (const UTF8String& key, CPoint p, uint32_t precision = 8) const
{
std::ostringstream sstream;
sstream.imbue (std::locale::classic ());
sstream.precision (static_cast<std::streamsize> (precision));
sstream << '{';
sstream << p.x;
sstream << ';';
sstream << p.y;
sstream << '}';
return set (key, UTF8String (sstream.str ()));
}
inline Optional<CPoint> getPoint (const UTF8String& key) const
{
if (auto p = get (key))
{
std::istringstream sstream (p->getString ());
sstream.imbue (std::locale::classic ());
uint8_t c;
sstream >> c;
if (sstream.fail () || c != '{')
return {};
CCoord x;
sstream >> x;
sstream >> c;
if (sstream.fail () || c != ';')
return {};
CCoord y;
sstream >> y;
sstream >> c;
if (sstream.fail () || c != '}')
return {};
return {CPoint (x, y)};
}
return {};
}
inline const UTF8String& getGroupKey () const { return groupKey; }
inline const UTF8String& getGroupSeparator () const { return groupSeparator; }
private:
Preferences (const Preferences&) = default;
Preferences& operator= (const Preferences&) = default;
IPreference* preferences {&IApplication::instance ().getPreferences ()};
UTF8String groupKey;
UTF8String groupSeparator;
};
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -0,0 +1,100 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#pragma once
#include "../../iuidescwindow.h"
#include <string>
#include <unordered_map>
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
namespace UIDesc {
//------------------------------------------------------------------------
/** ICustomization adapter
* @ingroup standalone
*/
class CustomizationAdapter : public ICustomization
{
public:
IController* createController (const UTF8StringView& name, IController* parent,
const IUIDescription* uiDesc) override
{
return nullptr;
}
void onUIDescriptionParsed (const IUIDescription* uiDesc) override {}
};
//------------------------------------------------------------------------
/** Customization helper for an UIDesc window
*
* Use this class to create controllers for your views
*
* Example:
* @code{.cpp}
* using namespace VSTGUI::Standalone;
* auto customization = UIDesc::Customization::make ();
*
* customization->addCreateViewControllerFunc (
* "MyFirstViewController", [] (const auto& name, auto parent, const auto uiDesc) {
* return new MyFirstViewController (parent);
* });
* customization->addCreateViewControllerFunc (
* "MySecondViewController", [] (const auto& name, auto parent, const auto uiDesc) {
* return new MySecondViewController (parent);
* });
*
* UIDesc::Config config;
* config.uiDescFileName = "Window.uidesc";
* config.viewName = "Window";
* config.customization = customization;
* config.windowConfig.title = "MyWindow";
* config.windowConfig.style.border ().close ().size ().centered ();
* if (auto window = UIDesc::makeWindow (config))
* window->show ();
*
* @endcode
*
* The view controller MyFirstViewController will be created when the sub-controller attribute of a
* view is equal to "MyFirstController" and the same for "MySecondViewController".
*
* @ingroup standalone
*/
class Customization : public CustomizationAdapter
{
public:
static std::shared_ptr<Customization> make () { return std::make_shared<Customization> (); }
using CreateViewControllerFunc = std::function<IController*(
const UTF8StringView& name, IController* parent, const IUIDescription* uiDesc)>;
void addCreateViewControllerFunc (const UTF8String& name, CreateViewControllerFunc func)
{
createViewControllerMap.emplace (name.getString (), func);
}
IController* createController (const UTF8StringView& name, IController* parent,
const IUIDescription* uiDesc) override
{
auto it = createViewControllerMap.find (std::string (name));
if (it != createViewControllerMap.end ())
{
return it->second (name, parent, uiDesc);
}
return nullptr;
}
private:
using CreateViewControllerMap = std::unordered_map<std::string, CreateViewControllerFunc>;
CreateViewControllerMap createViewControllerMap;
};
//------------------------------------------------------------------------
} // UIDesc
} // Standalone
} // VSTGUI
@@ -0,0 +1,155 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#pragma once
#include "../../iuidescwindow.h"
#include "../valuelistener.h"
#include <functional>
#include <unordered_map>
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
namespace UIDesc {
//------------------------------------------------------------------------
struct ValueCalls
{
using Call = std::function<void (IValue&)>;
Call onBeginEditCall;
Call onPerformEditCall;
Call onEndEditCall;
Call onStateChangeCall;
static ValueCalls onPerformEdit (Call&& call)
{
ValueCalls c;
c.onPerformEditCall = std::move (call);
return c;
}
static ValueCalls onEndEdit (Call&& call)
{
ValueCalls c;
c.onEndEditCall = std::move (call);
return c;
}
static ValueCalls onAction (Call&& call)
{
ValueCalls c;
c.onEndEditCall = [call = std::move (call)] (IValue & v)
{
if (v.getValue () > 0.5)
call (v);
};
return c;
}
};
class ModelBindingCallbacks;
using ModelBindingCallbacksPtr = std::shared_ptr<ModelBindingCallbacks>;
//------------------------------------------------------------------------
class ModelBindingCallbacks : public ValueListenerAdapter, public IModelBinding
{
public:
static ModelBindingCallbacksPtr make () { return std::make_shared<ModelBindingCallbacks> (); }
ModelBindingCallbacks () = default;
~ModelBindingCallbacks () override;
ValuePtr addValue (ValuePtr value, const ValueCalls& callbacks = {});
ValuePtr addValue (ValuePtr value, ValueCalls&& callbacks);
ValuePtr getValue (UTF8StringView valueID) const;
const ValueList& getValues () const override { return valueList; }
private:
void onBeginEdit (IValue& value) override;
void onPerformEdit (IValue& value, IValue::Type newValue) override;
void onEndEdit (IValue& value) override;
void onStateChange (IValue& value) override;
using ValueMap = std::unordered_map<const IValue*, ValueCalls>;
ValueList valueList;
ValueMap values;
};
//------------------------------------------------------------------------
inline ModelBindingCallbacks::~ModelBindingCallbacks ()
{
for (auto& v : valueList)
v->unregisterListener (this);
values.clear ();
valueList.clear ();
}
//------------------------------------------------------------------------
inline ValuePtr ModelBindingCallbacks::addValue (ValuePtr value, const ValueCalls& callbacks)
{
values.emplace (value.get (), callbacks);
valueList.emplace_back (value);
value->registerListener (this);
return value;
}
//------------------------------------------------------------------------
inline ValuePtr ModelBindingCallbacks::addValue (ValuePtr value, ValueCalls&& callbacks)
{
values.emplace (value.get (), std::move (callbacks));
valueList.emplace_back (value);
value->registerListener (this);
return value;
}
//------------------------------------------------------------------------
inline ValuePtr ModelBindingCallbacks::getValue (UTF8StringView valueID) const
{
for (auto& v : valueList)
{
if (v->getID () == valueID)
return v;
}
return nullptr;
}
//------------------------------------------------------------------------
inline void ModelBindingCallbacks::onBeginEdit (IValue& value)
{
auto it = values.find (&value);
if (it != values.end () && it->second.onBeginEditCall)
it->second.onBeginEditCall (value);
}
//------------------------------------------------------------------------
inline void ModelBindingCallbacks::onPerformEdit (IValue& value, IValue::Type newValue)
{
auto it = values.find (&value);
if (it != values.end () && it->second.onPerformEditCall)
it->second.onPerformEditCall (value);
}
//------------------------------------------------------------------------
inline void ModelBindingCallbacks::onEndEdit (IValue& value)
{
auto it = values.find (&value);
if (it != values.end () && it->second.onEndEditCall)
it->second.onEndEditCall (value);
}
//------------------------------------------------------------------------
inline void ModelBindingCallbacks::onStateChange (IValue& value)
{
auto it = values.find (&value);
if (it != values.end () && it->second.onStateChangeCall)
it->second.onStateChangeCall (value);
}
//------------------------------------------------------------------------
} // UIDesc
} // Standalone
} // VSTGUI
@@ -0,0 +1,285 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#pragma once
#include "../ivalue.h"
#include <vector>
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
class IStringListValue : public Interface
{
public:
using StringType = UTF8String;
using StringList = std::vector<StringType>;
virtual bool updateStringList (const StringList& newStrings) = 0;
virtual bool updateString (size_t index, const StringType& string) = 0;
};
//------------------------------------------------------------------------
class IMutableStepValue : public Interface
{
public:
virtual bool setNumSteps (IStepValue::StepType numSteps) = 0;
};
//------------------------------------------------------------------------
class IRangeValueConverter : public Interface
{
public:
virtual void setRange (IValue::Type minValue, IValue::Type maxValue) = 0;
};
//------------------------------------------------------------------------
class IStringValue : public Interface
{
public:
virtual void setString (const UTF8String& str) = 0;
virtual const UTF8String& getString () const = 0;
};
//------------------------------------------------------------------------
/** %value create and helper functions
* @ingroup standalone
*/
namespace Value {
//------------------------------------------------------------------------
/** @name %Create values
* @{ */
//------------------------------------------------------------------------
/** make a value in the normalized range [0..1]
*
* @param id value ID
* @param initialValue initial value
* @param valueConverter value converter
* @return shared value pointer
*/
ValuePtr make (const UTF8String& id, IValue::Type initialValue = 0.,
const ValueConverterPtr& valueConverter = nullptr);
//------------------------------------------------------------------------
/** make a step value
*
* @param id value ID
* @param numSteps number of discrete steps, must be greater than zero
* @param initialValue initial value in the normalized range [0..1]
* @param valueConverter value converter
* @return shared value pointer
*/
ValuePtr makeStepValue (const UTF8String& id, IStepValue::StepType numSteps,
IValue::Type initialValue = 0.,
const ValueConverterPtr& valueConverter = nullptr);
//------------------------------------------------------------------------
/** make a string list value
*
* a string list value is a step value where each step has a string representation.
*
* to modify the string list you can cast the returned value object to IStringListValue
* and use the updateStringList method.
*
* @param id value ID
* @param strings string list
* @param initialValue initial value in the normalized range [0..1]
* @return shared value pointer
*/
ValuePtr makeStringListValue (const UTF8String& id,
const std::initializer_list<IStringListValue::StringType>& strings,
IValue::Type initialValue = 0.);
//------------------------------------------------------------------------
/** make a string list value
*
* the returned value object has the IStringListValue interface
*
* @param id value ID
* @param strings string list
* @return shared value pointer
*/
ValuePtr makeStringListValue (const UTF8String& id, const IStringListValue::StringList& strings);
//------------------------------------------------------------------------
/** make a static string value
*
* a static string value is an inactive unchangeable value
*
* @param id value ID
* @param value static string
* @return shared value pointer
*/
ValuePtr makeStaticStringValue (const UTF8String& id, const UTF8String& value);
//------------------------------------------------------------------------
/** make a static string value
*
* a static string value is an inactive unchangeable value
*
* @param id value ID
* @param value static string
* @return shared value pointer
*/
ValuePtr makeStaticStringValue (const UTF8String& id, UTF8String&& value);
//------------------------------------------------------------------------
/** make a string value
*
* a string value has always the same numerical but different string representations
*
* @param id value ID
* @param value initial string
* @return shared value pointer
*/
ValuePtr makeStringValue (const UTF8String& id, const UTF8String& initialString);
//------------------------------------------------------------------------
/** make a string value
*
* a string value has always the same numerical but different string representations
*
* @param id value ID
* @param value initial string
* @return shared value pointer
*/
ValuePtr makeStringValue (const UTF8String& id, UTF8String&& initialString);
/** @} */
/** @name %Create value converters
* @{ */
//------------------------------------------------------------------------
/** make a percent value converter
*
* converts normalized values to the range [0..100]
*/
ValueConverterPtr makePercentConverter ();
//------------------------------------------------------------------------
/** make a range value converter
*
* converts normalized values to the range [minValue..maxValue]
*/
ValueConverterPtr makeRangeConverter (IValue::Type minValue, IValue::Type maxValue,
uint32_t stringPrecision = 4);
/** @} */
//------------------------------------------------------------------------
/** @name %Value helper functions
* @{
*/
inline IValue::Type plainToNormalize (IValue& value, IValue::Type plainValue)
{
return value.getConverter ().plainToNormalized (plainValue);
}
//------------------------------------------------------------------------
inline IValue::Type normalizeToPlain (IValue& value, IValue::Type normalizeValue)
{
return value.getConverter ().normalizedToPlain (normalizeValue);
}
//------------------------------------------------------------------------
inline IValue::Type stepToNormalize (IValue& value, IStepValue::StepType stepValue)
{
if (auto sv = value.dynamicCast<IStepValue> ())
{
return sv->stepToValue (stepValue);
}
return IValue::InvalidValue;
}
//------------------------------------------------------------------------
inline IStepValue::StepType normalizeToStep (IValue& value, IValue::Type normalizeValue)
{
if (auto sv = value.dynamicCast<IStepValue> ())
{
return sv->valueToStep (normalizeValue);
}
return IStepValue::InvalidStep;
}
//------------------------------------------------------------------------
inline IValue::Type currentPlainValue (IValue& value)
{
return normalizeToPlain (value, value.getValue ());
}
//------------------------------------------------------------------------
inline IStepValue::StepType currentStepValue (IValue& value)
{
return normalizeToStep (value, value.getValue ());
}
//------------------------------------------------------------------------
inline UTF8String currentStringValue (IValue& value)
{
if (auto stringValue = value.dynamicCast<IStringValue> ())
{
return stringValue->getString ();
}
return value.getConverter ().valueAsString (value.getValue ());
}
//------------------------------------------------------------------------
inline void performSingleEdit (IValue& value, IValue::Type newValue)
{
value.beginEdit ();
value.performEdit (newValue);
value.endEdit ();
}
//------------------------------------------------------------------------
inline void performSinglePlainEdit (IValue& value, IValue::Type plainValue)
{
performSingleEdit (value, plainToNormalize (value, plainValue));
}
//------------------------------------------------------------------------
inline bool performSingleStepEdit (IValue& value, IStepValue::StepType step)
{
if (auto stepValue = value.dynamicCast<IStepValue> ())
{
performSingleEdit (value, stepValue->stepToValue (step));
return true;
}
return false;
}
//------------------------------------------------------------------------
inline bool performStringValueEdit (IValue& value, const UTF8String& str)
{
if (auto stringValue = value.dynamicCast<IStringValue> ())
{
value.beginEdit ();
stringValue->setString (str);
value.endEdit ();
return true;
}
return false;
}
//------------------------------------------------------------------------
inline bool performStringAppendValueEdit (IValue& value, const UTF8String& str)
{
if (auto stringValue = value.dynamicCast<IStringValue> ())
{
value.beginEdit ();
stringValue->setString (stringValue->getString () + str);
value.endEdit ();
return true;
}
return false;
}
/** @} */
//------------------------------------------------------------------------
} // Value
} // Standalone
} // VSTGUI
@@ -0,0 +1,142 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#pragma once
#include "../ivaluelistener.h"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
/** %Value listener adapter
*
* @ingroup standalone
*/
class ValueListenerAdapter : public IValueListener
{
public:
void onBeginEdit (IValue& value) override {}
void onPerformEdit (IValue& value, IValue::Type newValue) override {}
void onEndEdit (IValue& value) override {}
void onStateChange (IValue& value) override {}
};
//------------------------------------------------------------------------
namespace Value {
namespace Detail {
//------------------------------------------------------------------------
class ListenerBase : public IValueListener
{
public:
ListenerBase (IValue& value) : value (value)
{
value.registerListener (this);
}
~ListenerBase () noexcept override
{
value.unregisterListener (this);
}
IValue& getValueObject () const { return value; }
private:
IValue& value;
};
//------------------------------------------------------------------------
} // Detail
//------------------------------------------------------------------------
/** %Value listener
*
* @ingroup standalone
*/
template <typename Context>
class ListenerT : public Detail::ListenerBase
{
public:
ListenerT (IValue& value, Context context) : Detail::ListenerBase (value), context (context) {}
using OnBeginEditFunc = void(*) (IValue&, Context&);
using OnEndEditFunc = void(*) (IValue&, Context&);
using OnStateChangeFunc = void(*) (IValue&, Context&);
using OnPerformEditFunc = void(*) (IValue&, IValue::Type, Context&);
OnBeginEditFunc onBeginEditFunc {nullptr};
OnEndEditFunc onEndEditFunc {nullptr};
OnStateChangeFunc onStateChangeFunc {nullptr};
OnPerformEditFunc onPerformEditFunc {nullptr};
private:
void onBeginEdit (IValue& value) final
{
if (onBeginEditFunc)
onBeginEditFunc (value, context);
}
void onPerformEdit (IValue& value, IValue::Type newValue) final
{
if (onPerformEditFunc)
onPerformEditFunc (value, newValue, context);
}
void onEndEdit (IValue& value) final
{
if (onEndEditFunc)
onEndEditFunc (value, context);
}
void onStateChange (IValue& value) final
{
if (onStateChangeFunc)
onStateChangeFunc (value, context);
}
Context context;
};
//------------------------------------------------------------------------
/** %Value listener
*
* @ingroup standalone
*/
class Listener : public Detail::ListenerBase
{
public:
Listener (IValue& value) : Detail::ListenerBase (value) {}
using OnBeginEditFunc = void(*) (IValue&);
using OnEndEditFunc = void(*) (IValue&);
using OnStateChangeFunc = void(*) (IValue&);
using OnPerformEditFunc = void(*) (IValue&, IValue::Type);
OnBeginEditFunc onBeginEditFunc {nullptr};
OnEndEditFunc onEndEditFunc {nullptr};
OnStateChangeFunc onStateChangeFunc {nullptr};
OnPerformEditFunc onPerformEditFunc {nullptr};
private:
void onBeginEdit (IValue& value) final
{
if (onBeginEditFunc)
onBeginEditFunc (value);
}
void onPerformEdit (IValue& value, IValue::Type newValue) final
{
if (onPerformEditFunc)
onPerformEditFunc (value, newValue);
}
void onEndEdit (IValue& value) final
{
if (onEndEditFunc)
onEndEditFunc (value);
}
void onStateChange (IValue& value) final
{
if (onStateChangeFunc)
onStateChangeFunc (value);
}
};
//------------------------------------------------------------------------
} // Value
} // Standalone
} // VSTGUI
@@ -0,0 +1,44 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#pragma once
#include "../iwindowcontroller.h"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
/** %Window controller adapter
*
* @ingroup standalone
*/
class WindowControllerAdapter : public IWindowController
{
public:
void onSizeChanged (const IWindow& window, const CPoint& newSize) override {}
void onPositionChanged (const IWindow& window, const CPoint& newPosition) override {}
void onShow (const IWindow& window) override {}
void onHide (const IWindow& window) override {}
void onClosed (const IWindow& window) override {}
void onActivated (const IWindow& window) override {}
void onDeactivated (const IWindow& window) override {}
CPoint constraintSize (const IWindow& window, const CPoint& newSize) override
{
return newSize;
}
bool canClose (const IWindow& window) override { return true; }
void beforeShow (IWindow& window) override {}
PlatformFrameConfigPtr createPlatformFrameConfig (PlatformType platformType) override
{
return nullptr;
}
void onSetContentView (IWindow& window, const SharedPointer<CFrame>& contentView) override {}
const IMenuBuilder* getWindowMenuBuilder (const IWindow& window) const override { return nullptr; }
};
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -0,0 +1,64 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#pragma once
#include "../iwindowlistener.h"
#include <functional>
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
/** %Window listener adapter
*
* @ingroup standalone
*/
class WindowListenerAdapter : public IWindowListener
{
public:
void onSizeChanged (const IWindow& window, const CPoint& newSize) override {}
void onPositionChanged (const IWindow& window, const CPoint& newPosition) override {}
void onShow (const IWindow& window) override {}
void onHide (const IWindow& window) override {}
void onClosed (const IWindow& window) override {}
void onActivated (const IWindow& window) override {}
void onDeactivated (const IWindow& window) override {}
};
//------------------------------------------------------------------------
/** %Window closed listener
*
* @ingroup standalone
*/
class WindowClosedListener : public WindowListenerAdapter
{
public:
using Func = std::function<void (const IWindow&)>;
WindowClosedListener () {}
template <typename Func>
WindowClosedListener (Func func) : func (std::forward<Func> (func))
{
}
void onClosed (const IWindow& window) override
{
if (func)
{
func (window);
Func e {};
func.swap (e);
func = nullptr;
}
}
Func func;
};
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI