// 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& 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; }; //------------------------------------------------------------------------ class ValueWrapper : public ValueListenerAdapter, public IControlListener, public ViewListenerAdapter { public: using ControlList = std::vector; 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 (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(control); auto stepValue = dynamicPtrCast (value); if (listcontrol && stepValue) { control->setMin (0.f); control->setMax (static_cast (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 (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 (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 (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 (control)) { paramDisplay->setValueToStringFunction2 ( [this] (float val, std::string& utf8String, CParamDisplay* display) { utf8String = this->value->getConverter ().valueAsString (val); return true; }); if (auto textEdit = dynamic_cast (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 (v); return true; }); } } else if (auto listControl = dynamic_cast (control)) { if (auto stringListDrawer = dynamic_cast (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 (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 (view)); } const ControlList& getControls () const { return controls; } protected: void onRemoveControl (CControl* control) { if (auto paramDisplay = dynamic_cast (control)) { paramDisplay->setValueToStringFunction (nullptr); if (auto textEdit = dynamic_cast (paramDisplay)) textEdit->setStringToValueFunction (nullptr); } else if (auto listControl = dynamic_cast (control)) { if (auto stringListDrawer = dynamic_cast (listControl->getDrawer ())) { stringListDrawer->setStringProvider (nullptr); } } control->unregisterViewListener (this); control->unregisterControlListener (this); } ValuePtr value; ControlList controls; CControl* updateControl {nullptr}; }; using ValueWrapperPtr = std::unique_ptr; //------------------------------------------------------------------------ struct WindowController::Impl : public IController, public ICommandHandler { using ValueWrapperList = std::vector; 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 (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 (inXml.length ())); uiDesc = makeOwned (&xmlContentProvider); if (!uiDesc->parse ()) return false; if (customization) customization->onUIDescriptionParsed (uiDesc); frame = makeOwned (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 (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 (customization)) customController->beforeShow (*window); } } virtual bool canClose () { if (customization) { if (auto customController = dynamicPtrCast (customization)) return customController->canClose (*window); } return true; } PlatformFrameConfigPtr createPlatformFrameConfig (PlatformType platformType) { if (customization) { if (auto customController = dynamicPtrCast (customization)) return customController->createPlatformFrameConfig (platformType); } return nullptr; } void onSetContentView (const SharedPointer& contentView) { if (customization) { if (auto customController = dynamicPtrCast (customization)) customController->onSetContentView (*window, contentView); } } virtual void onSizeChanged (const CPoint& newSize) { if (customization) { if (auto customController = dynamicPtrCast (customization)) customController->onSizeChanged (*window, newSize); } } void onPositionChanged (const CPoint& newPos) { if (customization) { if (auto customController = dynamicPtrCast (customization)) customController->onPositionChanged (*window, newPos); } } void onShow () { if (customization) { if (auto customController = dynamicPtrCast (customization)) customController->onShow (*window); } } void onHide () { if (customization) { if (auto customController = dynamicPtrCast (customization)) customController->onHide (*window); } } virtual void onClosed () { if (customization) { if (auto customController = dynamicPtrCast (customization)) customController->onClosed (*window); } } void onActivated () { if (customization) { if (auto customController = dynamicPtrCast (customization)) customController->onActivated (*window); } } void onDeactivated () { if (customization) { if (auto customController = dynamicPtrCast (customization)) customController->onDeactivated (*window); } } bool initUIDesc (const char* fileName) { if (Detail::getApplicationPlatformAccess () ->getConfiguration () .useCompressedUIDescriptionFiles) uiDesc = makeOwned (fileName); else uiDesc = makeOwned (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 (modelBinding)) canHandle = commandHandler->canHandleCommand (command); } if (!canHandle && customization) { if (auto commandHandler = dynamicPtrCast (customization)) canHandle = commandHandler->canHandleCommand (command); } if (!canHandle) { if (auto view = currentCommandHandlerCandidate ()) { if (auto viewController = getViewController (view, true)) { if (auto viewCommandHandler = dynamic_cast (viewController)) { canHandle = viewCommandHandler->canHandleCommand (command); } } } } return canHandle; } bool handleCommand (const Command& command) override { bool handled = false; if (modelBinding) { if (auto commandHandler = dynamicPtrCast (modelBinding)) handled = commandHandler->handleCommand (command); } if (!handled && customization) { if (auto commandHandler = dynamicPtrCast (customization)) handled = commandHandler->handleCommand (command); } if (!handled) { if (auto view = currentCommandHandlerCandidate ()) { if (auto viewController = getViewController (view, true)) { if (auto viewCommandHandler = dynamic_cast (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 (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 (control->getTag ()); if (index < valueWrappers.size ()) valueWrappers[index]->removeControl (control); } void controlTagDidChange (CControl* control) override { if (control->getTag () < 0) return; auto index = static_cast (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 (view); if (control) { if (control->getListener () == nullptr) control->setListener (this); auto index = static_cast (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 uiDesc; SharedPointer 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 (CRect (), nullptr); frame->setTransparency (true); if (!initUIDesc (fileName)) { auto attr = makeOwned (); 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 (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 (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 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; bool isEditing {false}; std::string filename; }; #endif //------------------------------------------------------------------------ bool WindowController::initStatic (const UIDesc::Config& config, WindowPtr& window) { impl = std::unique_ptr (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 (new EditImpl (*this, config.modelBinding, config.customization)); #else impl = std::unique_ptr (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& 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 (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 (""); //------------------------------------------------------------------------ WindowPtr makeWindow (const Config& config) { vstgui_assert (config.viewName.empty () == false); vstgui_assert (config.uiDescFileName.empty () == false); auto controller = std::make_shared (); 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