Initial release
This commit is contained in:
+42
@@ -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
|
||||
+66
@@ -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
|
||||
+139
@@ -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
|
||||
+100
@@ -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
|
||||
+155
@@ -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
|
||||
+142
@@ -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
|
||||
+44
@@ -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
|
||||
+64
@@ -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
|
||||
Reference in New Issue
Block a user