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,97 @@
// 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 "iappdelegate.h"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
namespace Application {
enum class ConfigKey : uint64_t;
struct ConfigValue;
//------------------------------------------------------------------------
/** Startup configuration
*
* The standalone library can be configured with a list of key-value pairs.
* See ConfigKey for a list and description of available keys.
*
* @ingroup standalone
*/
using Configuration = std::vector<std::pair<ConfigKey, ConfigValue>>;
//------------------------------------------------------------------------
/** Configuration keys
*
* Enumeration of available configuration keys.
*
* @ingroup standalone
*/
enum class ConfigKey : uint64_t
{
/** Instead of plain text files, use compressed ui description files.
*
* This option expects an integer ConfigValue where 0 means that plain text files are used and
* any other value means that the ui description file is compressed. In this case for
* development purposes an uncompressed text file is also written.
*/
UseCompressedUIDescriptionFiles,
/** Show application commands in a window context menu
*
* This option expects an integer ConfigValue where 0 means that the commands are not shown in
* the context menu of a window which is shown on a right mouse click, on any other value the
* commands are shown. If this option is not specified the commands are not shown.
*/
ShowCommandsInContextMenu,
};
//------------------------------------------------------------------------
/** Configuration Value
*
* @ingroup standalone
*/
struct ConfigValue
{
ConfigValue () = delete;
#if defined(_MSC_VER) && _MSC_VER < 1910 // Can be removed when dropping VS 2015 Support
ConfigValue (int64_t v) : type (Type::Integer) { value.integer = v; }
ConfigValue (const char* s) : type (Type::String) { value.string = s; }
#else
constexpr ConfigValue (int64_t v) : type (Type::Integer) { value.integer = v; }
constexpr ConfigValue (const char* s) : type (Type::String) { value.string = s; }
#endif
enum class Type
{
Unknown,
Integer,
String
} type = Type::Unknown;
union
{
int64_t integer;
const char* string;
} value = {};
};
//------------------------------------------------------------------------
/** Init application
*
* @see IDelegate
*
* @ingroup standalone
*/
struct Init
{
explicit Init (DelegatePtr&& delegate, Configuration&& config = {});
};
//------------------------------------------------------------------------
} // Application
} // 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
/**
@defgroup standalone Standalone Library
List of classes for the standalone library.
See @ref standalone_library "this page" for an introduction.
@page standalone_library Standalone Library
@tableofcontents
@section standalone_about About
@note The Standalone Library is a preview. The API may change in the future !
The standalone library adds a minimal set of classes to write simple cross-platform UI applications.
See @ref standalone "this page" for a list of classes.
Here's a minimal sample just showing one window:
@code{.cpp}
#include "vstgui/standalone/include/iapplication.h"
#include "vstgui/standalone/include/iuidescwindow.h"
#include "vstgui/standalone/include/helpers/appdelegate.h"
#include "vstgui/standalone/include/helpers/windowlistener.h"
using namespace VSTGUI::Standalone;
using namespace VSTGUI::Standalone::Application;
class MyApplication : public DelegateAdapter, public WindowListenerAdapter
{
public:
MyApplication ()
: DelegateAdapter ({"simple_standalone", "1.0.0", "com.mycompany.simplestandalone"})
{}
void finishLaunching () override
{
UIDesc::Config config;
config.uiDescFileName = "Window.uidesc";
config.viewName = "Window";
config.windowConfig.title = "Sample App";
config.windowConfig.autoSaveFrameName = "SampleAppWindow";
config.windowConfig.style.border ().close ().size ().centered ();
if (auto window = UIDesc::makeWindow (config))
{
window->show ();
window->registerWindowListener (this);
}
else
{
IApplication::instance ().quit ();
}
}
void onClosed (const IWindow& window) override
{
IApplication::instance ().quit ();
}
};
static Init gAppDelegate (std::make_unique<MyApplication> ());
@endcode
Adding a real user interface to the window is done via a "What You See Is What You Get" editor
at runtime as known from the VST3 inline editor. Bindings are done via the
@link VSTGUI::Standalone::UIDesc::IModelBinding IModelBinding @endlink interface.
@section standalone_modelbinding Bindings
Binding the user interface with your code is done via @link VSTGUI::Standalone::IValue IValue @endlink objects. A list
of value objects are exposed via an object that implements the
@link VSTGUI::Standalone::UIDesc::IModelBinding IModelBinding @endlink interface.
As an example implementation there is the @link VSTGUI::Standalone::UIDesc::ModelBindingCallbacks ModelBindingCallbacks @endlink class in the helpers sub directory.
For example you want to have a button in the UI which triggers a function, you can implement it
like this :
@code{.cpp}
auto binding = UIDesc::ModelBindingCallbacks::make ();
binding->addValue (Value::make ("MyFunction"),
UIDesc::ValueCalls::onAction ([&] (IValue& v) {
executeMyFunction ();
}));
config.modelBinding = binding;
@endcode
After you have set the binding as the @link VSTGUI::Standalone::UIDesc::Config::modelBinding UIDesc::Config::modelBinding @endlink parameter
when you create the window, you can start your program, enable the inline editor, create a button
and bind that button to the "control-tag" of "MyFunction" as written in the above code. When the
button is clicked, the function 'executeMyFunction' is called.
@section standalone_window_customization Customization
If you need deeper control of the UI you can supply an object implementing the
@link VSTGUI::Standalone::UIDesc::ICustomization ICustomization @endlink interface as the
@link VSTGUI::Standalone::UIDesc::Config::customization UIDesc::Config::customization @endlink parameter.
In the UI editor you can set the 'sub-controller' attribute of a view container to create a new
@link VSTGUI::IController IController @endlink object out of your @link VSTGUI::Standalone::UIDesc::ICustomization ICustomization @endlink object. This controller can alter the UI in
many ways, it can even create custom views if you don't want to use the way described in
@link VSTGUI::IViewCreator IViewCreator @endlink to support the view inside the UI editor.
@section standalone_supported_os Supported operating systems
- Microsoft Windows 64bit
- minimum supported version : 7
- Apple macOS 64bit
- minimum supported version : 10.10
@section standalone_compiler_requirements Compiler requirements
To compile and use the library you need a compiler supporting most of c++14.
As of this writing the following compilers work (others not tested):
- Visual Studio 15
- Xcode 7.3
*/
//------------------------------------------------------------------------
namespace VSTGUI {
/** %Standalone Library
*
* See @ref standalone_library "this page"
* @ingroup new_in_4_5
*/
namespace Standalone {
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -0,0 +1,75 @@
// 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 <memory>
//------------------------------------------------------------------------
namespace VSTGUI {
class IPlatformFrameConfig;
namespace Standalone {
class IWindow;
class IWindowController;
class IWindowListener;
class IPreference;
class ICommandHandler;
class IMenuBuilder;
class IValue;
class IStepValue;
class IValueListener;
class IValueConverter;
class ISharedUIResources;
class ICommonDirectories;
using WindowPtr = std::shared_ptr<IWindow>;
using WindowControllerPtr = std::shared_ptr<IWindowController>;
using ValuePtr = std::shared_ptr<IValue>;
using ValueConverterPtr = std::shared_ptr<IValueConverter>;
using PlatformFrameConfigPtr = std::shared_ptr<IPlatformFrameConfig>;
struct Command;
struct AlertBoxConfig;
struct AlertBoxForWindowConfig;
enum class AlertResult;
//------------------------------------------------------------------------
namespace UIDesc {
class IModelBinding;
class ICustomization;
using ModelBindingPtr = std::shared_ptr<IModelBinding>;
using CustomizationPtr = std::shared_ptr<ICustomization>;
struct Config;
//------------------------------------------------------------------------
} // UIDesc
//------------------------------------------------------------------------
namespace Application {
class IDelegate;
using DelegatePtr = std::unique_ptr<IDelegate>;
//------------------------------------------------------------------------
} // Application
//------------------------------------------------------------------------
namespace Async {
struct Queue;
using QueuePtr = std::shared_ptr<Queue>;
struct Group;
using GroupPtr = std::shared_ptr<Group>;
//------------------------------------------------------------------------
} // Async
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -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
@@ -0,0 +1,58 @@
// 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 "fwd.h"
#include "../../lib/cstring.h"
#include "interface.h"
#include <functional>
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
/** Alert result
*
* @ingroup standalone
*/
enum class AlertResult
{
DefaultButton,
SecondButton,
ThirdButton,
Error,
};
//------------------------------------------------------------------------
/** Alertbox configuration
*
* @ingroup standalone
*/
struct AlertBoxConfig
{
UTF8String headline;
UTF8String description;
UTF8String defaultButton {"OK"};
UTF8String secondButton;
UTF8String thirdButton;
};
//------------------------------------------------------------------------
/** Alertbox for window configuration
*
* @ingroup standalone
*/
struct AlertBoxForWindowConfig : AlertBoxConfig
{
using Callback = std::function<void (AlertResult)>;
WindowPtr window;
Callback callback;
};
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -0,0 +1,80 @@
// 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 "fwd.h"
#include "../../lib/cstring.h"
#include "interface.h"
#include <memory>
#include <vector>
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
namespace Application {
//------------------------------------------------------------------------
/** %Application info.
*
* @ingroup standalone
*/
struct Info
{
/** Name of the application */
UTF8String name;
/** Version of the application */
UTF8String version;
/** Uniform resource identifier for the application */
UTF8String uri;
};
//------------------------------------------------------------------------
/** %Application delegate interface.
*
* Every VSTGUI application needs a delegate. It's a global instance which handles
* custom application behaviour.
*
* You define it via Application::Init (std::make_unique<YourDelegateClassType> ())
*
* @ingroup standalone
*/
class IDelegate : public Interface
{
public:
/** Called when the application has finished launching. */
virtual void finishLaunching () = 0;
/** Called when the application is terminating. */
virtual void onQuit () = 0;
/** Called to check if it is currently possible to quit. */
virtual bool canQuit () = 0;
/** The delegate should show the about dialog. */
virtual void showAboutDialog () = 0;
/** Is there an about dialog ? */
virtual bool hasAboutDialog () = 0;
/** The delegate should show the preference dialog. */
virtual void showPreferenceDialog () = 0;
/** Is there a preference dialog ? */
virtual bool hasPreferenceDialog () = 0;
/** Get the application info. */
virtual const Info& getInfo () const = 0;
/** Get the filename of the shared UI resources.
*
* If this returns a name than all the UI resources are shared between
* different uidesc files. If this returns a nullptr, every uidesc file
* has its own resources.
*/
virtual UTF8StringPtr getSharedUIResourceFilename () const = 0;
/** Called when the system wants the app to open files
*
* @param paths UTF-8 encoded paths to the files
* @return true on success
*/
virtual bool openFiles (const std::vector<UTF8String>& paths) = 0;
};
//------------------------------------------------------------------------
} // Application
} // Standalone
} // VSTGUI
@@ -0,0 +1,95 @@
// 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 "fwd.h"
#include "iwindow.h"
#include "interface.h"
#include <cstdint>
#include <vector>
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
/** %Application interface.
*
* @ingroup standalone
*/
class IApplication : public Interface
{
public:
using WindowList = std::vector<WindowPtr>;
using CommandLineArguments = std::vector<UTF8String>;
/** Get the global instance of the application */
static IApplication& instance ();
/** Get the application delegate */
virtual Application::IDelegate& getDelegate () const = 0;
/** Get the application preferences */
virtual IPreference& getPreferences () const = 0;
/** Get the command line arguments */
virtual const CommandLineArguments& getCommandLineArguments () const = 0;
/** Get the shared UI resources */
virtual const ISharedUIResources& getSharedUIResources () const = 0;
/** Get common directories */
virtual const ICommonDirectories& getCommonDirectories () const = 0;
/** Create a new window
*
* @param config window configuration
* @param controller window controller (can be nullptr)
* @return shared window pointer
*/
virtual WindowPtr createWindow (const WindowConfiguration& config,
const WindowControllerPtr& controller) = 0;
/** Get all application windows
*
* @note The active window will be the first in the list.
* @return a list of all windows
*/
virtual const WindowList& getWindows () const = 0;
/** Show an application wide modal alert box
*
* @param config alert box configuration
* @return alert result
*/
virtual AlertResult showAlertBox (const AlertBoxConfig& config) = 0;
/** Show an alert box modal to a window
*
* @param config alert box configuration
*/
virtual void showAlertBoxForWindow (const AlertBoxForWindowConfig& config) = 0;
/** Register a command
*
* The command will be added to the application menu. When the menu item is selected the
* command is first dispatched to the active window and then to the application delegate.
*
* @param command command name and group
* @param defaultCommandKey default command key
*/
virtual void registerCommand (const Command& command, char16_t defaultCommandKey) = 0;
/** Execute a command
*
* The command will be first dispatched to the active window (if there is one) and if the
* window did not handle the command the command is dispatched to the application delegate.
*
* @param command command name and group
* @return if the command was executed
*/
virtual bool executeCommand (const Command& command) = 0;
/** Enable or disable tooltips in all windows
*
* @param state true to enable tooltips, false for disabling them
*/
virtual void enableTooltips (bool state) = 0;
/** Quit the application */
virtual void quit () = 0;
};
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -0,0 +1,60 @@
// 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 "fwd.h"
#include <functional>
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
/** %asynchronous tasks
* @ingroup standalone
*/
namespace Async {
//------------------------------------------------------------------------
using Task = std::function<void ()>;
//------------------------------------------------------------------------
/** Get main/UI serial queue.
*
* Tasks scheduled on this queue are performed serially on the main/ui thread.
*/
const QueuePtr& mainQueue ();
//------------------------------------------------------------------------
/** Get background concurrent queue.
*
* Tasks scheduled on this queue are performed concurrently on background threads.
* The number of background threads are depending on the systems number of CPU cores.
*/
const QueuePtr& backgroundQueue ();
//------------------------------------------------------------------------
/** Make a new serial queue.
*
* Tasks scheduled on this queue are performed serially on a background thread.
*
* @param name the name of the serial queue (optional)
* @return a new serial queue
*/
QueuePtr makeSerialQueue (const char* name);
//------------------------------------------------------------------------
/** Schedule a task to be performed asynchronous on a queue.
*
* Can be called from any thread, but should not be called from realtime constraint threads as it
* may involves locks and memory allocations
*
* @param queue on which queue to perform the task
* @param task task to be performed
*/
void schedule (QueuePtr queue, Task&& task);
//------------------------------------------------------------------------
} // Async
} // Standalone
} // VSTGUI
@@ -0,0 +1,147 @@
// 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 "../../lib/cstring.h"
#include "interface.h"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
/** %Command definition
*
* Commands are automatically dispatched to the Application::IDelegate, the focus view controller
* or IWindowController instances if they implement the ICommandHandler interface.
*
* Commands are registered via IApplication::registerCommand.
*
*
* @ingroup standalone
*/
struct Command
{
UTF8String group;
UTF8String name;
};
//------------------------------------------------------------------------
inline bool operator== (const Command& c1, const Command& c2)
{
return c1.group == c2.group && c1.name == c2.name;
}
//------------------------------------------------------------------------
inline bool operator!= (const Command& c1, const Command& c2)
{
return c1.group != c2.group || c1.name != c2.name;
}
//------------------------------------------------------------------------
/** Handler for commands
*
* @ingroup standalone
*/
class ICommandHandler : public Interface
{
public:
/** Check if command can be handled. */
virtual bool canHandleCommand (const Command& command) = 0;
/** Handle command. */
virtual bool handleCommand (const Command& command) = 0;
};
//------------------------------------------------------------------------
/** predefined command groups
*
* @ingroup standalone
*/
namespace CommandGroup {
static constexpr IdStringPtr Application = "Application";
static constexpr IdStringPtr File = "File";
static constexpr IdStringPtr Edit = "Edit";
static constexpr IdStringPtr Window = "Window";
static constexpr IdStringPtr Debug = "Debug";
//------------------------------------------------------------------------
} // CommandGroup
//------------------------------------------------------------------------
namespace CommandName {
static constexpr IdStringPtr About = "About";
static constexpr IdStringPtr Preferences = "Preferences...";
static constexpr IdStringPtr Quit = "Quit";
static constexpr IdStringPtr Help = "Help";
static constexpr IdStringPtr New = "New";
static constexpr IdStringPtr Open = "Open...";
static constexpr IdStringPtr Save = "Save";
static constexpr IdStringPtr SaveAs = "Save As...";
static constexpr IdStringPtr Revert = "Revert";
static constexpr IdStringPtr CloseWindow = "Close Window";
static constexpr IdStringPtr Undo = "Undo";
static constexpr IdStringPtr Redo = "Redo";
static constexpr IdStringPtr Cut = "Cut";
static constexpr IdStringPtr Copy = "Copy";
static constexpr IdStringPtr Paste = "Paste";
static constexpr IdStringPtr Delete = "Delete";
static constexpr IdStringPtr SelectAll = "Select All";
static constexpr IdStringPtr FindNext = "Find Next";
static constexpr IdStringPtr FindPrevious = "Find Previous";
static constexpr IdStringPtr MenuSeparator = "~";
static constexpr IdStringPtr ToggleInlineUIEditor = "Toggle Inline UI-Editor";
static constexpr IdStringPtr RecreateView = "Recreate View";
static constexpr IdStringPtr ResaveSharedResources = "Resave Shared Resources";
} // CommandName
//------------------------------------------------------------------------
/** predefined commands
*
* @ingroup standalone
*/
namespace Commands {
static const Command About {CommandGroup::Application, CommandName::About};
static const Command Preferences {CommandGroup::Application, CommandName::Preferences};
static const Command Quit {CommandGroup::Application, CommandName::Quit};
static const Command Help {CommandGroup::Application, CommandName::Help};
static const Command NewDocument {CommandGroup::File, CommandName::New};
static const Command OpenDocument {CommandGroup::File, CommandName::Open};
static const Command SaveDocument {CommandGroup::File, CommandName::Save};
static const Command SaveDocumentAs {CommandGroup::File, CommandName::SaveAs};
static const Command RevertDocument {CommandGroup::File, CommandName::Revert};
static const Command CloseWindow {CommandGroup::File, CommandName::CloseWindow};
static const Command Undo {CommandGroup::Edit, CommandName::Undo};
static const Command Redo {CommandGroup::Edit, CommandName::Redo};
static const Command Cut {CommandGroup::Edit, CommandName::Cut};
static const Command Copy {CommandGroup::Edit, CommandName::Copy};
static const Command Paste {CommandGroup::Edit, CommandName::Paste};
static const Command Delete {CommandGroup::Edit, CommandName::Delete};
static const Command SelectAll {CommandGroup::Edit, CommandName::SelectAll};
static const Command FindNext {CommandGroup::Edit, CommandName::FindNext};
static const Command FindPrevious {CommandGroup::Edit, CommandName::FindPrevious};
//------------------------------------------------------------------------
namespace Debug {
static const Command ToggleInlineUIEditor {CommandGroup::Debug, CommandName::ToggleInlineUIEditor};
static const Command RecreateView {CommandGroup::Debug, CommandName::RecreateView};
static const Command ResaveSharedResources {CommandGroup::Debug,
CommandName::ResaveSharedResources};
//------------------------------------------------------------------------
} // Debug
} // Commands
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -0,0 +1,48 @@
// 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 "../../lib/cstring.h"
#include "../../lib/optional.h"
#include "interface.h"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
enum class CommonDirectoryLocation
{
/** Path to the application. */
AppPath,
/** Path to the resources of the application. */
AppResourcesPath,
/** Path to the folder where application preferences are stored. */
AppPreferencesPath,
/** Path to the folder for application specific cache files. */
AppCachesPath,
/** Path to the users documents folder. */
UserDocumentsPath,
};
//------------------------------------------------------------------------
class ICommonDirectories : public Interface
{
public:
/** Get a common directory.
*
* @param location the location of the directory
* @param subDir optional sub directory
* @param create create directory if it does not exist
* @return If location does exist the string is the path to the directory with the last
* character the path separator.
*/
virtual Optional<UTF8String> get (CommonDirectoryLocation location,
const UTF8String& subDir = "", bool create = false) const = 0;
};
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -0,0 +1,63 @@
// 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 "fwd.h"
#include "interface.h"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
/** Menu builder interface
*
* %Application delegates can implement this interface to customize the visibility and order of
* commands shown in the menu of the application or window. On platforms where the menu is sitting
* in the window, the window controllers menu builder is used if it has one.
* The context parameter of the methods is either an IApplication or IWindow.
*
* @ingroup standalone
*/
class IMenuBuilder : public Interface
{
public:
using SortFunction = std::function<bool (const UTF8String& lhs, const UTF8String& rhs)>;
/** should the command group be visible in the menu
*
* @param context either an IApplication or IWindow instance
* @param group group name
* @return true for visible or false for invisible
*/
virtual bool showCommandGroupInMenu (const Interface& context,
const UTF8String& group) const = 0;
/** should the command be visible in the menu
*
* @param context either an IApplication or IWindow instance
* @param cmd command
* @return true for visible or false for invisible
*/
virtual bool showCommandInMenu (const Interface& context, const Command& cmd) const = 0;
/** return command group sort function
*
* @param context either an IApplication or IWindow instance
* @param group group name
* @return if you want to sort the menu return a SortFunction otherwise return nullptr
*/
virtual SortFunction getCommandGroupSortFunction (const Interface& context,
const UTF8String& group) const = 0;
/** should a menu separator prepend a command
*
* @param context either an IApplication or IWindow instance
* @param cmd command
* @return true if a menu separator should be prepended before the command
*/
virtual bool prependMenuSeparator (const Interface& context, const Command& cmd) const = 0;
};
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -0,0 +1,76 @@
// 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 <memory>
//------------------------------------------------------------------------
namespace VSTGUI {
//------------------------------------------------------------------------
class Interface
{
public:
virtual ~Interface () noexcept {}
Interface () = default;
Interface (const Interface&) = delete;
Interface (Interface&&) = delete;
Interface& operator= (const Interface&) = delete;
Interface& operator= (Interface&&) = delete;
template <typename T>
const auto dynamicCast () const
{
return dynamic_cast<const T*> (this);
}
template <typename T>
auto dynamicCast ()
{
return dynamic_cast<T*> (this);
}
};
//------------------------------------------------------------------------
using InterfacePtr = std::shared_ptr<Interface>;
//------------------------------------------------------------------------
template <typename Iface, typename T>
inline auto dynamicPtrCast (std::shared_ptr<T>& obj)
{
return std::dynamic_pointer_cast<Iface> (obj);
}
//------------------------------------------------------------------------
template <typename Iface, typename T>
inline const auto dynamicPtrCast (const std::shared_ptr<T>& obj)
{
return std::dynamic_pointer_cast<Iface> (obj);
}
//------------------------------------------------------------------------
template <typename Iface, typename T>
inline auto staticPtrCast (std::shared_ptr<T>& obj)
{
return std::static_pointer_cast<Iface> (obj);
}
//------------------------------------------------------------------------
template <typename Iface, typename T>
inline const auto staticPtrCast (const std::shared_ptr<T>& obj)
{
return std::static_pointer_cast<Iface> (obj);
}
//------------------------------------------------------------------------
template <typename Iface, typename T>
inline const auto& asInterface (const T& obj)
{
return static_cast<const Iface&> (obj);
}
//------------------------------------------------------------------------
} // VSTGUI
@@ -0,0 +1,33 @@
// 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 "fwd.h"
#include "../../lib/cstring.h"
#include "../../lib/optional.h"
#include "interface.h"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
/** Preference interface
*
* You get the preferences via IApplication::instance ().getPreferences ().
* @ingroup standalone
*/
class IPreference : public Interface
{
public:
/** Set a preference value. */
virtual bool set (const UTF8String& key, const UTF8String& value) = 0;
/** Get a preference value */
virtual Optional<UTF8String> get (const UTF8String& key) = 0;
};
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -0,0 +1,35 @@
// 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 "../../lib/vstguifwd.h"
#include "../../lib/optional.h"
#include "interface.h"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
/** Shared UI resources interface
*
* @ingroup standalone
*/
class ISharedUIResources : public Interface
{
public:
/** get shared color. */
virtual Optional<CColor> getColor (const UTF8String& name) const = 0;
/** get shared bitmap. */
virtual Optional<CBitmap*> getBitmap (const UTF8String& name) const = 0;
/** get shared gradient. */
virtual Optional<CGradient*> getGradient (const UTF8String& name) const = 0;
/** get shared font. */
virtual Optional<CFontDesc*> getFont (const UTF8String& name) const = 0;
};
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -0,0 +1,127 @@
// 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 "../../uidescription/uidescriptionfwd.h"
#include "fwd.h"
#include "icommand.h"
#include "ivalue.h"
#include "iwindow.h"
#include <vector>
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
namespace UIDesc {
//------------------------------------------------------------------------
/** Model binding interface
*
* Make values available in the UIDescription window to be able to bind to controls.
*
* @ingroup standalone
*/
class IModelBinding : public Interface
{
public:
using ValueList = std::vector<ValuePtr>;
virtual const ValueList& getValues () const = 0;
};
//------------------------------------------------------------------------
/** UIDesc window customization interface
*
* @ingroup standalone
*/
class ICustomization : public Interface
{
public:
/** Create a sub controller
*
* A sub controller can be defined in the UI editor for a view and will be responsible
* as a controller for the view and its children.
*
* The controller will be automatically destroyed when the view is destroyed. You should
* always create a new controller instance here and do not cache it.
*
* @param name name of the sub controller
* @param parent the parent controller
* @param uiDesc the UIDescription instance
*/
virtual IController* createController (const UTF8StringView& name, IController* parent,
const IUIDescription* uiDesc) = 0;
/** Notification that the UIDescription was sucessfully parsed
*
* This can be used to get some resources from the UIDescription instance.
* @param uiDesc the UIDescription instance
*/
virtual void onUIDescriptionParsed (const IUIDescription* uiDesc) = 0;
};
//------------------------------------------------------------------------
/** Configuration for an UIDescription window
*
* @ingroup standalone
*/
struct Config
{
/** Filename of the UIDescription xml file */
UTF8String uiDescFileName;
/** Template name of the view in the uidesc file to show in the window */
UTF8String viewName;
/** Window configuration */
WindowConfiguration windowConfig;
/** Model binding
*
* Additioanlly to the IModelBinding features, if this object implements the ICommandHandler
* interface all commands send to the window will be dispatched to this object.
*
*/
ModelBindingPtr modelBinding;
/** %Optional UI customization
*
* Additionally to the ICustomization features, if this object implements the IWindowController
* interface, all window controller functions will be dispatched to this object.
*
*/
CustomizationPtr customization;
};
//------------------------------------------------------------------------
/** Create a window with an UIDescription
*
* @param config window configuration
* @see Config
*
* @ingroup standalone
*/
WindowPtr makeWindow (const Config& config);
//------------------------------------------------------------------------
} // UIDesc
//------------------------------------------------------------------------
/** Accessor interface for the window controller of an UIDescription window
*
* When creating a window using UIDesc::makeWindow, the window controller of the window conforms to
* this interface. You can utilize the dynamicPtrCast function to cast to this interface.
*/
class IUIDescWindowController : public Interface
{
public:
/** get the model binding object of the window controller */
virtual UIDesc::ModelBindingPtr getModelBinding () const = 0;
/** get the customization object of the window controller */
virtual UIDesc::CustomizationPtr getCustomization () const = 0;
};
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -0,0 +1,97 @@
// 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 "fwd.h"
#include "../../lib/cstring.h"
#include "interface.h"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
/** Value interface
*
* @ingroup standalone
*/
class IValue : public Interface
{
public:
/** floating point value in the range of 0 to 1 */
using Type = double;
/** indicates an invalid value */
static constexpr Type InvalidValue = std::numeric_limits<Type>::min ();
/** Begin editing the value. */
virtual void beginEdit () = 0;
/** Perform a value edit. */
virtual bool performEdit (Type newValue) = 0;
/** End editing the value. */
virtual void endEdit () = 0;
/** Set active state. */
virtual void setActive (bool state) = 0;
/** Is value active? */
virtual bool isActive () const = 0;
/** Get the normalized value. */
virtual Type getValue () const = 0;
/** Is value in edit mode. */
virtual bool isEditing () const = 0;
/** Get value identifier. */
virtual const UTF8String& getID () const = 0;
/** Get value converter. */
virtual const IValueConverter& getConverter () const = 0;
/** register a value listener. */
virtual void registerListener (IValueListener* listener) = 0;
/** unregister a value listener. */
virtual void unregisterListener (IValueListener* listener) = 0;
};
//------------------------------------------------------------------------
/** extension to IValue for a non continous value with discrete steps
*
* @ingroup standalone
*/
class IStepValue : public Interface
{
public:
using StepType = uint32_t;
static constexpr StepType InvalidStep = std::numeric_limits<uint32_t>::max ();
/** Get number of steps. */
virtual StepType getSteps () const = 0;
/** Convert step to normalized value. */
virtual IValue::Type stepToValue (StepType step) const = 0;
/** Convert normalized value to step. */
virtual StepType valueToStep (IValue::Type) const = 0;
};
//------------------------------------------------------------------------
/** %Value converter interface
*
* @ingroup standalone
*/
class IValueConverter : public Interface
{
public:
/** Convert value to string. */
virtual UTF8String valueAsString (IValue::Type value) const = 0;
/** Convert string to value. */
virtual IValue::Type stringAsValue (const UTF8String& string) const = 0;
/** Convert plain to normalized value. */
virtual IValue::Type plainToNormalized (IValue::Type plain) const = 0;
/** Convert normalized to plain value. */
virtual IValue::Type normalizedToPlain (IValue::Type normalized) const = 0;
};
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -0,0 +1,33 @@
// 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"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
/** %Value listener interface
*
* @ingroup standalone
*/
class IValueListener : public Interface
{
public:
/** %Value begins editing. */
virtual void onBeginEdit (IValue& value) = 0;
/** %Value performed an edit. */
virtual void onPerformEdit (IValue& value, IValue::Type newValue) = 0;
/** %Value ends editing. */
virtual void onEndEdit (IValue& value) = 0;
/** %Value changed some of its state. */
virtual void onStateChange (IValue& value) = 0;
};
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -0,0 +1,229 @@
// 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 "fwd.h"
#include "../../lib/crect.h"
#include "../../lib/cstring.h"
#include "interface.h"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
/** Window types
*
* About window types:
*
* There are two types of windows :
*
* - Document
*
* - Popup
*
* There can be as many document windows visible as you wish, but only one popup can be visible at
* a time.
* A popup window will automatically close if it is deactivated.
*
*
* @ingroup standalone
*/
enum class WindowType
{
Document,
Popup,
};
//------------------------------------------------------------------------
/** Window style
*
* Defines window style and behaviour.
*
* Border: Adds border and title bar. If transparent is set, this is ignored.
*
* Close: Adds a closebox if bordered and allows standard ways of closing the window.
*
* Size: Allows user resizing.
*
* Transparent: Window has no background and no operating system style window frame.
*
* MovableByWindowBackground: User can move the window by its background.
*
* Centered: Window will initially shown centered on screen.
*
* @ingroup standalone
*/
struct WindowStyle
{
private:
uint32_t flags {0};
enum Style
{
Border = 1 << 0,
Close = 1 << 1,
Size = 1 << 2,
Transparent = 1 << 3,
MovableByWindowBackground = 1 << 4,
Centered = 1 << 5,
};
public:
WindowStyle () = default;
WindowStyle& operator+= (WindowStyle toAdd)
{
flags |= toAdd.flags;
return *this;
}
WindowStyle& operator-= (WindowStyle toRemove)
{
flags &= ~(toRemove.flags);
return *this;
}
WindowStyle& border ()
{
flags |= Style::Border;
return *this;
}
WindowStyle& close ()
{
flags |= Style::Close;
return *this;
}
WindowStyle& size ()
{
flags |= Style::Size;
return *this;
}
WindowStyle& transparent ()
{
flags |= Style::Transparent;
return *this;
}
WindowStyle& movableByWindowBackground ()
{
flags |= Style::MovableByWindowBackground;
return *this;
}
WindowStyle& centered ()
{
flags |= Style::Centered;
return *this;
}
bool hasBorder () const { return (flags & Style::Border) != 0; }
bool canClose () const { return (flags & Style::Close) != 0; }
bool canSize () const { return (flags & Style::Size) != 0; }
bool isTransparent () const { return (flags & Style::Transparent) != 0; }
bool isMovableByWindowBackground () const
{
return (flags & Style::MovableByWindowBackground) != 0;
}
bool isCentered () const { return (flags & Style::Centered) != 0; }
};
//------------------------------------------------------------------------
/** Window configuration
*
* @ingroup standalone
*/
struct WindowConfiguration
{
/** Type of window */
WindowType type {WindowType::Document};
/** Window style */
WindowStyle style;
/** Initial window size */
CPoint size;
/** Window title */
UTF8String title;
/** Window save frame name */
UTF8String autoSaveFrameName;
/** Window group identifier [optional]
*
* Windows with the same group identifier can be grouped together on some platforms like on
* macOS to tabs in a single window
*/
UTF8String groupIdentifier;
};
//------------------------------------------------------------------------
/** Window interface
*
* Windows are created via IApplication::instance ().createWindow ()
*
* Windows are automatically destroyed when they are closed.
*
* @ingroup standalone
*/
class IWindow : public Interface
{
public:
/** Get the window controller. Can be nullptr. */
virtual const WindowControllerPtr& getController () const = 0;
/** Get the size of the client area. */
virtual CPoint getSize () const = 0;
/** Get the position in global coordinates. */
virtual CPoint getPosition () const = 0;
/** Get the content scale factor. */
virtual double getScaleFactor () const = 0;
/** Get the rect of the current focus view in frame relative coordinates. */
virtual CRect getFocusViewRect () const = 0;
/** Get the title of the window. */
virtual const UTF8String& getTitle () const = 0;
/** Get the type of the window. */
virtual WindowType getType () const = 0;
/** Get the style of the window. */
virtual WindowStyle getStyle () const = 0;
/** Get the auto save frame name of the window. */
virtual const UTF8String& getAutoSaveFrameName () const = 0;
/** Set the size of the client area. */
virtual void setSize (const CPoint& newSize) = 0;
/** Set the position in global coordinates. */
virtual void setPosition (const CPoint& newPosition) = 0;
/** Set the window title. */
virtual void setTitle (const UTF8String& newTitle) = 0;
/** Set content view. */
virtual void setContentView (const SharedPointer<CFrame>& frame) = 0;
/** Set the path the contents of this window represents. */
virtual void setRepresentedPath (const UTF8String& path) = 0;
/** Set the auto save frame name of the window. */
virtual void setAutoSaveFrameName (const UTF8String& name) = 0;
/** Change window style.
* May not change every style. Depends on the platform.
* Returns effective style.
*/
virtual WindowStyle changeStyle (WindowStyle stylesToAdd, WindowStyle stylesToRemove) = 0;
/** Show the window. */
virtual void show () = 0;
/** Hide the window. */
virtual void hide () = 0;
/** Close the window. */
virtual void close () = 0;
/** Activate the window. */
virtual void activate () = 0;
/** Register a window listener.
*
* There is no ownership involved here, so you have to make sure the listener is alive
* as long as the window lives.
* Listeners are automatically removed when the window is closed.
*/
virtual void registerWindowListener (IWindowListener* listener) = 0;
/** Unregister a window listener. */
virtual void unregisterWindowListener (IWindowListener* listener) = 0;
};
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -0,0 +1,38 @@
// 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 "../../lib/platform/iplatformframecallback.h"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
/** Window controller interface
*
* @ingroup standalone
*/
class IWindowController : public IWindowListener
{
public:
/** Constraint the size of the window. */
virtual CPoint constraintSize (const IWindow& window, const CPoint& newSize) = 0;
/** Can window close? */
virtual bool canClose (const IWindow& window) = 0;
/** Window will show. */
virtual void beforeShow (IWindow& window) = 0;
/** Create the platform frame configuration object. Can be nullptr. */
virtual PlatformFrameConfigPtr createPlatformFrameConfig (PlatformType platformType) = 0;
/** Content view of window is changed. */
virtual void onSetContentView (IWindow& window, const SharedPointer<CFrame>& contentView) = 0;
/** Get the menu builder for this window. */
virtual const IMenuBuilder* getWindowMenuBuilder (const IWindow& window) const = 0;
};
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI
@@ -0,0 +1,41 @@
// 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 "fwd.h"
#include "../../lib/cpoint.h"
#include "interface.h"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
//------------------------------------------------------------------------
/** Window listener interface
*
* @ingroup standalone
*/
class IWindowListener : public Interface
{
public:
/** Size of window is changed. */
virtual void onSizeChanged (const IWindow& window, const CPoint& newSize) = 0;
/** Position of window is changed. */
virtual void onPositionChanged (const IWindow& window, const CPoint& newPosition) = 0;
/** Window is shown. */
virtual void onShow (const IWindow& window) = 0;
/** Window is hidden. */
virtual void onHide (const IWindow& window) = 0;
/** Window is closed. */
virtual void onClosed (const IWindow& window) = 0;
/** Window is activated. */
virtual void onActivated (const IWindow& window) = 0;
/** Window is deactivated. */
virtual void onDeactivated (const IWindow& window) = 0;
};
//------------------------------------------------------------------------
} // Standalone
} // VSTGUI