Files
2026-08-16 18:24:52 +07:00

1126 lines
31 KiB
C++

// 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
#include "../../lib/algorithm.h"
#include "../../lib/cfileselector.h"
#include "../../lib/cframe.h"
#include "../../lib/controls/coptionmenu.h"
#include "../../lib/controls/csegmentbutton.h"
#include "../../lib/controls/cstringlist.h"
#include "../../lib/controls/ctextedit.h"
#include "../../lib/crect.h"
#include "../../lib/cvstguitimer.h"
#include "../../lib/iviewlistener.h"
#include "../../uidescription/compresseduidescription.h"
#include "../../uidescription/cstream.h"
#include "../../uidescription/xmlparser.h"
#include "../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../uidescription/editing/uieditcontroller.h"
#include "../../uidescription/editing/uieditmenucontroller.h"
#include "../../uidescription/icontroller.h"
#include "../../uidescription/uiattributes.h"
#include "../../uidescription/uicontentprovider.h"
#include "../../uidescription/uidescription.h"
#include "../include/helpers/menubuilder.h"
#include "../include/helpers/valuelistener.h"
#include "../include/helpers/windowcontroller.h"
#include "../include/ialertbox.h"
#include "../include/iappdelegate.h"
#include "../include/iapplication.h"
#include "../include/iasync.h"
#include "../include/iuidescwindow.h"
#include "application.h"
#include "shareduiresources.h"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace Standalone {
namespace /* Anonymous */ {
using UIDesc::ModelBindingPtr;
using UIDesc::CustomizationPtr;
//------------------------------------------------------------------------
class WindowController : public IWindowController,
public ICommandHandler,
public IUIDescWindowController
{
public:
bool init (const UIDesc::Config& config, WindowPtr& window);
bool initStatic (const UIDesc::Config& config, WindowPtr& window);
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;
bool canClose (const IWindow& window) override;
void beforeShow (IWindow& window) override;
PlatformFrameConfigPtr createPlatformFrameConfig (PlatformType platformType) override;
void onSetContentView (IWindow& window, const SharedPointer<CFrame>& contentView) override;
bool canHandleCommand (const Command& command) override;
bool handleCommand (const Command& command) override;
const IMenuBuilder* getWindowMenuBuilder (const IWindow& window) const override;
ModelBindingPtr getModelBinding () const override;
CustomizationPtr getCustomization () const override;
private:
struct Impl;
struct EditImpl;
std::unique_ptr<Impl> impl;
};
//------------------------------------------------------------------------
class ValueWrapper : public ValueListenerAdapter,
public IControlListener,
public ViewListenerAdapter
{
public:
using ControlList = std::vector<CControl*>;
explicit ValueWrapper (const ValuePtr& value = nullptr) : value (value)
{
if (value)
value->registerListener (this);
}
~ValueWrapper () noexcept override
{
if (value)
value->unregisterListener (this);
for (auto& control : controls)
onRemoveControl (control);
}
const UTF8String& getID () const { return value->getID (); }
void onBeginEdit (IValue&) override
{
for (auto& c : controls)
{
if (auto listener = c->getListener ())
listener->controlBeginEdit (c);
}
}
void onEndEdit (IValue&) override
{
for (auto& c : controls)
{
if (auto listener = c->getListener ())
listener->controlEndEdit (c);
}
}
void onPerformEdit (IValue&, IValue::Type newValue) override
{
auto newControlValue = static_cast<float> (newValue);
for (auto& c : controls)
{
updateControl = c;
c->setValueNormalized (newControlValue);
c->valueChanged ();
c->invalid ();
updateControl = nullptr;
}
}
void updateControlOnStateChange (CControl* control) const
{
control->setMouseEnabled (value->isActive ());
auto listcontrol = dynamic_cast<CListControl*>(control);
auto stepValue = dynamicPtrCast<const IStepValue> (value);
if (listcontrol && stepValue)
{
control->setMin (0.f);
control->setMax (static_cast<float> (stepValue->getSteps () - 1));
return;
}
control->setMin (0.f);
control->setMax (1.f);
if (!stepValue)
return;
const auto& valueConverter = value->getConverter ();
if (auto menu = dynamic_cast<COptionMenu*> (control))
{
menu->removeAllEntry ();
for (IStepValue::StepType i = 0; i < stepValue->getSteps (); ++i)
{
auto title = valueConverter.valueAsString (stepValue->stepToValue (i));
menu->addEntry (title);
}
}
else if (auto segmentButton = dynamic_cast<CSegmentButton*> (control))
{
segmentButton->removeAllSegments ();
for (IStepValue::StepType i = 0; i < stepValue->getSteps (); ++i)
{
auto title = valueConverter.valueAsString (stepValue->stepToValue (i));
CSegmentButton::Segment segment;
segment.name = title;
segmentButton->addSegment (std::move (segment));
}
}
}
void onStateChange (IValue&) override
{
for (auto& c : controls)
{
updateControlOnStateChange (c);
c->valueChanged ();
}
}
void valueChanged (CControl* control) override
{
if (updateControl == control)
return;
auto newValue = static_cast<IValue::Type> (control->getValueNormalized ());
value->performEdit (newValue);
}
void controlBeginEdit (CControl* control) override { value->beginEdit (); }
void controlEndEdit (CControl* control) override { value->endEdit (); }
void addControl (CControl* control)
{
if (auto paramDisplay = dynamic_cast<CParamDisplay*> (control))
{
paramDisplay->setValueToStringFunction2 (
[this] (float val, std::string& utf8String, CParamDisplay* display) {
utf8String = this->value->getConverter ().valueAsString (val);
return true;
});
if (auto textEdit = dynamic_cast<CTextEdit*> (paramDisplay))
{
textEdit->setStringToValueFunction (
[&] (UTF8StringPtr txt, float& result, CTextEdit* textEdit) {
auto v = value->getConverter ().stringAsValue (txt);
if (v == IValue::InvalidValue)
v = value->getValue ();
result = static_cast<float> (v);
return true;
});
}
}
else if (auto listControl = dynamic_cast<CListControl*> (control))
{
if (auto stringListDrawer =
dynamic_cast<StringListControlDrawer*> (listControl->getDrawer ()))
{
stringListDrawer->setStringProvider ([this] (int32_t row) {
auto min = this->value->getConverter ().normalizedToPlain (0.);
auto norm = this->value->getConverter ().plainToNormalized (row + min);
auto string = this->value->getConverter ().valueAsString (norm);
return shared (string.getPlatformString ());
});
}
}
updateControlOnStateChange (control);
control->beginEdit ();
control->setValueNormalized (static_cast<float> (value->getValue ()));
control->valueChanged ();
control->endEdit ();
control->invalid ();
control->registerControlListener (this);
control->registerViewListener (this);
controls.emplace_back (control);
}
void removeControl (CControl* control)
{
auto it = std::find (controls.begin (), controls.end (), control);
if (it != controls.end ())
{
onRemoveControl (control);
controls.erase (it);
}
}
void viewWillDelete (CView* view) override { removeControl (dynamic_cast<CControl*> (view)); }
const ControlList& getControls () const { return controls; }
protected:
void onRemoveControl (CControl* control)
{
if (auto paramDisplay = dynamic_cast<CParamDisplay*> (control))
{
paramDisplay->setValueToStringFunction (nullptr);
if (auto textEdit = dynamic_cast<CTextEdit*> (paramDisplay))
textEdit->setStringToValueFunction (nullptr);
}
else if (auto listControl = dynamic_cast<CListControl*> (control))
{
if (auto stringListDrawer =
dynamic_cast<StringListControlDrawer*> (listControl->getDrawer ()))
{
stringListDrawer->setStringProvider (nullptr);
}
}
control->unregisterViewListener (this);
control->unregisterControlListener (this);
}
ValuePtr value;
ControlList controls;
CControl* updateControl {nullptr};
};
using ValueWrapperPtr = std::unique_ptr<ValueWrapper>;
//------------------------------------------------------------------------
struct WindowController::Impl : public IController, public ICommandHandler
{
using ValueWrapperList = std::vector<ValueWrapperPtr>;
Impl (WindowController& controller, const ModelBindingPtr& modelHandler,
const CustomizationPtr& customization)
: controller (controller), modelBinding (modelHandler), customization (customization)
{
initModelValues (modelHandler);
}
~Impl () override
{
if (uiDesc && uiDesc->getSharedResources ())
{
uiDesc->setSharedResources (nullptr);
}
for (auto& vw : valueWrappers)
{
for (auto control : vw->getControls ())
{
if (control->getListener () == this)
control->setListener (nullptr);
}
}
}
virtual bool init (WindowPtr& inWindow, const char* inFileName, const char* inTemplateName)
{
window = inWindow.get ();
if (!initUIDesc (inFileName))
return false;
frame = makeOwned<CFrame> (CRect (), nullptr);
frame->setTransparency (true);
templateName = inTemplateName;
showView ();
window->setContentView (frame);
return true;
}
bool initStatic (WindowPtr& inWindow, UTF8String inXml, const char* inTemplateName)
{
window = inWindow.get ();
MemoryContentProvider xmlContentProvider (inXml, static_cast<uint32_t> (inXml.length ()));
uiDesc = makeOwned<UIDescription> (&xmlContentProvider);
if (!uiDesc->parse ())
return false;
if (customization)
customization->onUIDescriptionParsed (uiDesc);
frame = makeOwned<CFrame> (CRect (), nullptr);
frame->setTransparency (true);
templateName = inTemplateName;
showView ();
window->setContentView (frame);
return true;
}
virtual CPoint constraintSize (const CPoint& newSize)
{
if (customization)
{
if (auto customController = dynamicPtrCast<IWindowController> (customization))
{
auto p = customController->constraintSize (*window, newSize);
if (p != newSize)
return p;
}
}
CPoint p (newSize);
if (minSize.x > 0 && minSize.y > 0)
{
p.x = std::max (p.x, minSize.x);
p.y = std::max (p.y, minSize.y);
}
if (maxSize.x > 0 && maxSize.y > 0)
{
p.x = std::min (p.x, maxSize.x);
p.y = std::min (p.y, maxSize.y);
}
return p;
}
virtual void beforeShow ()
{
if (customization)
{
if (auto customController = dynamicPtrCast<IWindowController> (customization))
customController->beforeShow (*window);
}
}
virtual bool canClose ()
{
if (customization)
{
if (auto customController = dynamicPtrCast<IWindowController> (customization))
return customController->canClose (*window);
}
return true;
}
PlatformFrameConfigPtr createPlatformFrameConfig (PlatformType platformType)
{
if (customization)
{
if (auto customController = dynamicPtrCast<IWindowController> (customization))
return customController->createPlatformFrameConfig (platformType);
}
return nullptr;
}
void onSetContentView (const SharedPointer<CFrame>& contentView)
{
if (customization)
{
if (auto customController = dynamicPtrCast<IWindowController> (customization))
customController->onSetContentView (*window, contentView);
}
}
virtual void onSizeChanged (const CPoint& newSize)
{
if (customization)
{
if (auto customController = dynamicPtrCast<IWindowController> (customization))
customController->onSizeChanged (*window, newSize);
}
}
void onPositionChanged (const CPoint& newPos)
{
if (customization)
{
if (auto customController = dynamicPtrCast<IWindowController> (customization))
customController->onPositionChanged (*window, newPos);
}
}
void onShow ()
{
if (customization)
{
if (auto customController = dynamicPtrCast<IWindowController> (customization))
customController->onShow (*window);
}
}
void onHide ()
{
if (customization)
{
if (auto customController = dynamicPtrCast<IWindowController> (customization))
customController->onHide (*window);
}
}
virtual void onClosed ()
{
if (customization)
{
if (auto customController = dynamicPtrCast<IWindowController> (customization))
customController->onClosed (*window);
}
}
void onActivated ()
{
if (customization)
{
if (auto customController = dynamicPtrCast<IWindowController> (customization))
customController->onActivated (*window);
}
}
void onDeactivated ()
{
if (customization)
{
if (auto customController = dynamicPtrCast<IWindowController> (customization))
customController->onDeactivated (*window);
}
}
bool initUIDesc (const char* fileName)
{
if (Detail::getApplicationPlatformAccess ()
->getConfiguration ()
.useCompressedUIDescriptionFiles)
uiDesc = makeOwned<CompressedUIDescription> (fileName);
else
uiDesc = makeOwned<UIDescription> (fileName);
uiDesc->setSharedResources (Detail::getSharedUIDescription ());
if (!uiDesc->parse ())
{
return false;
}
if (customization)
customization->onUIDescriptionParsed (uiDesc);
return true;
}
void updateMinMaxSizes ()
{
const UIAttributes* attr = uiDesc->getViewAttributes (templateName);
if (!attr)
return;
CPoint p;
if (attr->getPointAttribute (kTemplateAttributeMinSize, p))
minSize = p;
else
minSize = {};
if (attr->getPointAttribute (kTemplateAttributeMaxSize, p))
maxSize = p;
else
maxSize = {};
}
void showView ()
{
frame->removeAll ();
updateMinMaxSizes ();
auto view = uiDesc->createView (templateName, this);
if (!view)
{
return;
}
auto viewSize = view->getViewSize ().getSize ();
frame->getTransform ().transform (viewSize);
frame->setSize (viewSize.x, viewSize.y);
frame->addView (view);
auto focusDrawing = uiDesc->getFocusDrawingSettings ();
frame->setFocusDrawingEnabled (focusDrawing.enabled);
if (focusDrawing.enabled)
{
frame->setFocusWidth (focusDrawing.width);
CColor focusColor;
if (uiDesc->getColor (focusDrawing.colorName.data (), focusColor))
frame->setFocusColor (focusColor);
}
window->setSize (view->getViewSize ().getSize ());
}
CView* currentCommandHandlerCandidate ()
{
if (auto focusView = frame->getFocusView ())
return focusView;
return frame->getView (0);
}
bool canHandleCommand (const Command& command) override
{
bool canHandle = false;
if (modelBinding)
{
if (auto commandHandler = dynamicPtrCast<ICommandHandler> (modelBinding))
canHandle = commandHandler->canHandleCommand (command);
}
if (!canHandle && customization)
{
if (auto commandHandler = dynamicPtrCast<ICommandHandler> (customization))
canHandle = commandHandler->canHandleCommand (command);
}
if (!canHandle)
{
if (auto view = currentCommandHandlerCandidate ())
{
if (auto viewController = getViewController (view, true))
{
if (auto viewCommandHandler = dynamic_cast<ICommandHandler*> (viewController))
{
canHandle = viewCommandHandler->canHandleCommand (command);
}
}
}
}
return canHandle;
}
bool handleCommand (const Command& command) override
{
bool handled = false;
if (modelBinding)
{
if (auto commandHandler = dynamicPtrCast<ICommandHandler> (modelBinding))
handled = commandHandler->handleCommand (command);
}
if (!handled && customization)
{
if (auto commandHandler = dynamicPtrCast<ICommandHandler> (customization))
handled = commandHandler->handleCommand (command);
}
if (!handled)
{
if (auto view = currentCommandHandlerCandidate ())
{
if (auto viewController = getViewController (view, true))
{
if (auto viewCommandHandler = dynamic_cast<ICommandHandler*> (viewController))
{
handled = viewCommandHandler->handleCommand (command);
}
}
}
}
return handled;
}
void initModelValues (const ModelBindingPtr& modelHandler)
{
if (!modelHandler)
return;
valueWrappers.reserve (modelHandler->getValues ().size ());
for (auto& value : modelHandler->getValues ())
{
valueWrappers.emplace_back (std::make_unique<ValueWrapper> (value));
}
}
// IController
void valueChanged (CControl* control) override {}
int32_t controlModifierClicked (CControl* control, CButtonState button) override { return 0; }
void controlBeginEdit (CControl* control) override {}
void controlEndEdit (CControl* control) override {}
void controlTagWillChange (CControl* control) override
{
if (control->getTag () < 0)
return;
auto index = static_cast<ValueWrapperList::size_type> (control->getTag ());
if (index < valueWrappers.size ())
valueWrappers[index]->removeControl (control);
}
void controlTagDidChange (CControl* control) override
{
if (control->getTag () < 0)
return;
auto index = static_cast<ValueWrapperList::size_type> (control->getTag ());
if (index < valueWrappers.size ())
valueWrappers[index]->addControl (control);
}
int32_t getTagForName (UTF8StringPtr name, int32_t registeredTag) const override
{
if (auto index =
indexOfTest (valueWrappers.begin (), valueWrappers.end (),
[&] (const ValueWrapperPtr& v) { return v->getID () == name; }))
return *index;
return registeredTag;
}
IControlListener* getControlListener (UTF8StringPtr controlTagName) override { return this; }
CView* createView (const UIAttributes& attributes, const IUIDescription* description) override
{
return nullptr;
}
CView* verifyView (CView* view, const UIAttributes& attributes,
const IUIDescription* description) override
{
auto* control = dynamic_cast<CControl*> (view);
if (control)
{
if (control->getListener () == nullptr)
control->setListener (this);
auto index = static_cast<ValueWrapperList::size_type> (control->getTag ());
if (index < valueWrappers.size ())
{
valueWrappers[index]->updateControlOnStateChange (control);
}
}
return view;
}
IController* createSubController (UTF8StringPtr name,
const IUIDescription* description) override
{
if (customization)
return customization->createController (name, this, description);
return nullptr;
}
WindowController& controller;
IWindow* window {nullptr};
SharedPointer<VSTGUI::UIDescription> uiDesc;
SharedPointer<CFrame> frame;
UTF8String templateName;
CPoint minSize;
CPoint maxSize;
ModelBindingPtr modelBinding;
CustomizationPtr customization;
ValueWrapperList valueWrappers;
};
#if VSTGUI_LIVE_EDITING
//------------------------------------------------------------------------
struct WindowController::EditImpl : WindowController::Impl
{
EditImpl (WindowController& controller, const ModelBindingPtr& modelBinding,
const CustomizationPtr& customization)
: Impl (controller, modelBinding, customization)
{
IApplication::instance ().registerCommand (Commands::Debug::ToggleInlineUIEditor, 'E');
IApplication::instance ().registerCommand (Commands::Debug::RecreateView, 0);
if (IApplication::instance ().getDelegate ().getSharedUIResourceFilename ())
IApplication::instance ().registerCommand (Commands::Debug::ResaveSharedResources, 0);
}
bool init (WindowPtr& inWindow, const char* fileName, const char* templateName) override
{
this->filename = fileName;
if (auto absPath = Detail::getEditFileMap ().get (fileName))
fileName = *absPath;
window = inWindow.get ();
frame = makeOwned<CFrame> (CRect (), nullptr);
frame->setTransparency (true);
if (!initUIDesc (fileName))
{
auto attr = makeOwned<UIAttributes> ();
attr->setAttribute (UIViewCreator::kAttrClass, "CViewContainer");
attr->setAttribute (UIViewCreator::kAttrSize, "300, 300");
attr->setAttribute (UIViewCreator::kAttrAutosize, "left right top bottom");
uiDesc->addNewTemplate (templateName, attr);
initAsNew ();
}
else
{
auto settings = uiDesc->getCustomAttributes ("UIDescFilePath", true);
auto filePath = settings->getAttributeValue ("path");
if (filePath)
{
if (auto file = fopen (filePath->data (), "rb"))
{
uiDesc->setFilePath (filePath->data ());
fclose (file);
}
}
}
this->templateName = templateName;
syncTags ();
showView ();
window->setContentView (frame);
return true;
}
CPoint constraintSize (const CPoint& newSize) override
{
if (isEditing)
return newSize;
return Impl::constraintSize (newSize);
}
void onSizeChanged (const CPoint& newSize) override
{
if (isEditing)
return;
Impl::onSizeChanged (newSize);
}
void onClosed () override
{
enableEditing (false);
Impl::onClosed ();
}
bool canClose () override
{
if (frame->getModalView ())
return false;
return Impl::canClose ();
}
void initAsNew ()
{
Detail::PreventPopupClose ppc (*window);
if (Detail::initUIDescAsNew (*uiDesc, frame))
{
enableEditing (true, true);
save (true);
enableEditing (false);
}
else
{
Async::schedule (Async::mainQueue (), [this] () { window->close (); });
}
}
void checkFileExists ()
{
Detail::PreventPopupClose ppc (*window);
auto result = Detail::checkAndUpdateUIDescFilePath (*uiDesc, frame);
if (result == Detail::UIDescCheckFilePathResult::Exists)
return;
if (result == Detail::UIDescCheckFilePathResult::NewPathSet)
{
save (true);
return;
}
enableEditing (false);
}
void save (bool force = false)
{
if (!uiEditController)
return;
if (force || uiEditController->getUndoManager ()->isSavePosition () == false)
{
if (uiEditController->getUndoManager ()->isSavePosition () == false)
Detail::saveSharedUIDescription ();
int32_t flags = UIDescription::kWriteImagesIntoUIDescFile |
CompressedUIDescription::kForceWriteCompressedDesc;
// filter out attributes we will always override with the values from the parameters
auto filter = [] (CView* view, const std::string& name) -> bool {
if (auto control = dynamic_cast<CControl*> (view))
{
if (control->getTag () >= 0)
{
if (name == UIViewCreator::kAttrMinValue)
return false;
if (name == UIViewCreator::kAttrMaxValue)
return false;
if (name == UIViewCreator::kAttrDefaultValue)
return false;
if (name == UIViewCreator::kAttrMouseEnabled)
return false;
if (name == UIViewCreator::kAttrTitle &&
dynamic_cast<CTextLabel*> (control))
return false;
}
}
return true;
};
if (!uiDesc->save (uiDesc->getFilePath (), flags, filter))
{
AlertBoxConfig config;
config.headline = "Saving the uidesc file failed.";
IApplication::instance ().showAlertBox (config);
uiDesc->setFilePath ("");
checkFileExists ();
}
else
Detail::getEditFileMap ().set (filename, uiDesc->getFilePath ());
}
}
void syncTags ()
{
std::list<const std::string*> tagNames;
uiDesc->collectControlTagNames (tagNames);
int32_t index = 0;
for (auto& v : valueWrappers)
{
auto it = std::find_if (tagNames.begin (), tagNames.end (),
[&] (const std::string* name) { return v->getID () == *name; });
auto create = it == tagNames.end ();
uiDesc->changeControlTagString (v->getID (), std::to_string (index), create);
++index;
}
// now remove all old tags
for (auto& name : tagNames)
{
auto it = std::find_if (valueWrappers.begin (), valueWrappers.end (),
[&] (const ValueWrapperList::value_type& value) {
return value->getID () == *name;
});
if (it == valueWrappers.end ())
uiDesc->removeTag (name->data ());
}
}
void enableEditing (bool state, bool ignoreCheckFileExist = false)
{
if (isEditing == state && frame->getNbViews () != 0)
return;
isEditing = state;
if (!state)
{
save ();
uiEditController = nullptr;
}
frame->removeAll ();
if (state)
{
uiDesc->setController (this);
uiEditController = new UIEditController (uiDesc);
auto view = uiEditController->createEditView ();
auto viewSize = view->getViewSize ().getSize ();
frame->getTransform ().transform (viewSize);
frame->setSize (viewSize.x, viewSize.y);
frame->addView (view);
frame->enableTooltips (true);
CColor focusColor = kBlueCColor;
uiEditController->getEditorDescription ()->getColor ("focus", focusColor);
frame->setFocusColor (focusColor);
frame->setFocusDrawingEnabled (true);
frame->setFocusWidth (1);
window->setSize (view->getViewSize ().getSize ());
if (auto menuController = uiEditController->getMenuController ())
{
if (auto menu = menuController->getFileMenu ())
{
menu->removeAllEntry ();
menu->setMouseEnabled (false);
}
}
if (!ignoreCheckFileExist)
checkFileExists ();
}
else
{
showView ();
}
}
bool canHandleCommand (const Command& command) override
{
using namespace Commands;
if (command == Debug::ToggleInlineUIEditor || command == Debug::RecreateView)
return frame->getModalView () == nullptr;
if (command == Debug::ResaveSharedResources)
return true;
else if (uiEditController && uiEditController->getMenuController ()->canHandleCommand (
command.group, command.name))
return true;
return Impl::canHandleCommand (command);
}
bool handleCommand (const Command& command) override
{
using namespace Commands;
if (command == Debug::ToggleInlineUIEditor)
{
enableEditing (!isEditing);
return true;
}
else if (command == Debug::RecreateView)
{
showView ();
return true;
}
else if (command == Debug::ResaveSharedResources)
{
Detail::saveSharedUIDescription ();
return true;
}
else if (uiEditController && uiEditController->getMenuController ()->handleCommand (
command.group, command.name))
return true;
return Impl::handleCommand (command);
}
SharedPointer<UIEditController> uiEditController;
bool isEditing {false};
std::string filename;
};
#endif
//------------------------------------------------------------------------
bool WindowController::initStatic (const UIDesc::Config& config, WindowPtr& window)
{
impl = std::unique_ptr<Impl> (new Impl (*this, config.modelBinding, config.customization));
return impl->initStatic (window, config.uiDescFileName, config.viewName);
}
//------------------------------------------------------------------------
bool WindowController::init (const UIDesc::Config& config, WindowPtr& window)
{
#if VSTGUI_LIVE_EDITING
impl = std::unique_ptr<Impl> (new EditImpl (*this, config.modelBinding, config.customization));
#else
impl = std::unique_ptr<Impl> (new Impl (*this, config.modelBinding, config.customization));
#endif
return impl->init (window, config.uiDescFileName, config.viewName);
}
//------------------------------------------------------------------------
CPoint WindowController::constraintSize (const IWindow& window, const CPoint& newSize)
{
return impl ? impl->constraintSize (newSize) : newSize;
}
//------------------------------------------------------------------------
bool WindowController::canClose (const IWindow& window)
{
return impl ? impl->canClose () : true;
}
//------------------------------------------------------------------------
void WindowController::onClosed (const IWindow& window)
{
if (impl)
impl->onClosed ();
impl = nullptr;
}
//------------------------------------------------------------------------
void WindowController::beforeShow (IWindow& window)
{
if (impl)
impl->beforeShow ();
}
//------------------------------------------------------------------------
PlatformFrameConfigPtr WindowController::createPlatformFrameConfig (PlatformType platformType)
{
if (impl)
return impl->createPlatformFrameConfig (platformType);
return nullptr;
}
//------------------------------------------------------------------------
void WindowController::onSetContentView (IWindow& window, const SharedPointer<CFrame>& contentView)
{
if (impl)
impl->onSetContentView (contentView);
}
//------------------------------------------------------------------------
void WindowController::onSizeChanged (const IWindow& window, const CPoint& newSize)
{
if (impl)
impl->onSizeChanged (newSize);
}
//------------------------------------------------------------------------
void WindowController::onPositionChanged (const IWindow& window, const CPoint& newPosition)
{
if (impl)
impl->onPositionChanged (newPosition);
}
//------------------------------------------------------------------------
void WindowController::onShow (const IWindow& window)
{
if (impl)
impl->onShow ();
}
//------------------------------------------------------------------------
void WindowController::onHide (const IWindow& window)
{
if (impl)
impl->onHide ();
}
//------------------------------------------------------------------------
void WindowController::onActivated (const IWindow& window)
{
if (impl)
impl->onActivated ();
}
//------------------------------------------------------------------------
void WindowController::onDeactivated (const IWindow& window)
{
if (impl)
impl->onDeactivated ();
}
//------------------------------------------------------------------------
bool WindowController::canHandleCommand (const Command& command)
{
return impl->canHandleCommand (command);
}
//------------------------------------------------------------------------
bool WindowController::handleCommand (const Command& command)
{
return impl->handleCommand (command);
}
//------------------------------------------------------------------------
const IMenuBuilder* WindowController::getWindowMenuBuilder (const IWindow& window) const
{
if (auto menuBuilder = dynamicPtrCast<IMenuBuilder> (impl->customization))
return menuBuilder.get ();
return nullptr;
}
ModelBindingPtr WindowController::getModelBinding () const { return impl->modelBinding; }
CustomizationPtr WindowController::getCustomization () const { return impl->customization; }
//------------------------------------------------------------------------
} // Anonymous
//------------------------------------------------------------------------
namespace UIDesc {
static const UTF8StringView staticXmlIdentifier ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
//------------------------------------------------------------------------
WindowPtr makeWindow (const Config& config)
{
vstgui_assert (config.viewName.empty () == false);
vstgui_assert (config.uiDescFileName.empty () == false);
auto controller = std::make_shared<WindowController> ();
if (UTF8StringView (config.uiDescFileName).startsWith (staticXmlIdentifier))
{
auto window = IApplication::instance ().createWindow (config.windowConfig, controller);
if (!window)
return nullptr;
if (!controller->initStatic (config, window))
return nullptr;
return window;
}
#if VSTGUI_LIVE_EDITING
WindowConfiguration windowConfig = config.windowConfig;
windowConfig.style.size ();
#else
auto& windowConfig = config.windowConfig;
#endif
auto window = IApplication::instance ().createWindow (windowConfig, controller);
if (!window)
return nullptr;
if (!controller->init (config, window))
return nullptr;
return window;
}
//------------------------------------------------------------------------
} // UIDesc
} // Standalone
} // VSTGUI