// 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 "uidialogcontroller.h" #if VSTGUI_LIVE_EDITING #include "uieditcontroller.h" #include "../uiattributes.h" #include "../../lib/coffscreencontext.h" #include "../../lib/cbitmapfilter.h" #include "../../lib/clayeredviewcontainer.h" #include "../../lib/cshadowviewcontainer.h" #include "../../lib/events.h" #include "../../lib/controls/ctextlabel.h" #include "../../lib/controls/cbuttons.h" #include "../../lib/animation/animations.h" #include "../../lib/animation/animator.h" #include "../../lib/animation/timingfunctions.h" #include namespace VSTGUI { //---------------------------------------------------------------------------------------------------- UIDialogController::UIDialogController (IController* baseController, CFrame* frame) : DelegationController (baseController) , frame (frame) { } //---------------------------------------------------------------------------------------------------- void UIDialogController::run (UTF8StringPtr _templateName, UTF8StringPtr _dialogTitle, UTF8StringPtr _button1, UTF8StringPtr _button2, const SharedPointer& _dialogController, UIDescription* _description, bool _resizable) { collectOpenGLViews (frame); templateName = _templateName; dialogTitle = _dialogTitle; dialogButton1 = _button1; dialogButton2 = _button2 != nullptr ? _button2 : ""; dialogController = _dialogController; dialogDescription = _description; resizable = _resizable; CView* view = UIEditController::getEditorDescription ()->createView ("dialog", this); if (view) { auto* layeredView = dynamic_cast(view); if (layeredView) layeredView->setZIndex (std::numeric_limits::max () - 1); CRect size = view->getViewSize (); size.right += sizeDiff.x; size.bottom += sizeDiff.y; CRect frameSize = frame->getViewSize (); frame->getTransform ().inverse ().transform (frameSize); size.centerInside (frameSize); size.makeIntegral (); view->setViewSize (size); view->setMouseableArea (size); view->setAlphaValue (0.f); modalSession = frame->beginModalViewSession (view); frame->registerKeyboardHook (this); frame->registerViewListener (this); view->registerViewListener (this); if (button1) frame->setFocusView (button1); setOpenGLViewsVisible (false); if (dialogController) dialogController->onDialogShow (this); using namespace Animation; view->addAnimation ( "AlphaAnimation", new AlphaValueAnimation (1.f), new CubicBezierTimingFunction (CubicBezierTimingFunction::easyInOut (160))); if (resizable) { if (customViewEmbedder) customViewEmbedder->setAutosizeFlags (kAutosizeAll); view->setAutosizeFlags (kAutosizeAll); view->setViewSize (frameSize); } } else { forget (); } } //---------------------------------------------------------------------------------------------------- void UIDialogController::close () { frame->unregisterKeyboardHook (this); frame->unregisterViewListener (this); if (button1) button1->setListener (nullptr); if (button2) button2->setListener (nullptr); setOpenGLViewsVisible (true); if (modalSession) { if (auto dialog = frame->getModalView ()) dialog->unregisterViewListener (this); frame->endModalViewSession (*modalSession); modalSession = {}; } forget (); } //---------------------------------------------------------------------------------------------------- void UIDialogController::viewSizeChanged (CView* view, const CRect& oldSize) { if (view == frame && !resizable) { CView* dialog = frame->getModalView (); CRect viewSize = dialog->getViewSize (); CRect frameSize = frame->getViewSize (); frame->getTransform ().inverse ().transform (frameSize); viewSize.centerInside (frameSize); dialog->setViewSize (viewSize); dialog->setMouseableArea (viewSize); } } //---------------------------------------------------------------------------------------------------- void UIDialogController::viewRemoved (CView* view) { if (view != frame) { view->unregisterViewListener (this); close (); } } //---------------------------------------------------------------------------------------------------- void UIDialogController::valueChanged (CControl* control) { if (control->getValue () == control->getMax ()) { switch (control->getTag ()) { case kButton1Tag: { if (dialogController) dialogController->onDialogButton1Clicked (this); break; } case kButton2Tag: { if (dialogController) dialogController->onDialogButton2Clicked (this); break; } } CView* modalView = frame->getModalView (); using namespace Animation; modalView->addAnimation ( "AlphaAnimation", new AlphaValueAnimation (0.f), new CubicBezierTimingFunction (CubicBezierTimingFunction::easyInOut (160)), [this] (CView*, const IdStringPtr, IAnimationTarget*) { close (); }); } } //---------------------------------------------------------------------------------------------------- IControlListener* UIDialogController::getControlListener (UTF8StringPtr controlTagName) { return this; } //---------------------------------------------------------------------------------------------------- CView* UIDialogController::verifyView (CView* view, const UIAttributes& attributes, const IUIDescription* description) { if (auto control = dynamic_cast (view)) { if (control->getTag () == kButton1Tag) { auto* button = dynamic_cast(control); if (button) { button1 = button; button->setTitle (dialogButton1.c_str ()); layoutButtons (); } } else if (control->getTag () == kButton2Tag) { auto* button = dynamic_cast(control); if (button) { button2 = button; if (dialogButton2.empty ()) { button->setVisible (false); } else { button->setTitle (dialogButton2.c_str ()); } layoutButtons (); } } else if (control->getTag () == kTitleTag) { auto* label = dynamic_cast(control); if (label) { label->setText (dialogTitle.c_str ()); } } } else if (auto name = attributes.getAttributeValue (IUIDescription::kCustomViewName)) { if (*name == "view" && view) { auto controller = dialogController.cast (); if (auto subView = dialogDescription->createView (templateName.c_str (), controller)) { subView->setAttribute (kCViewControllerAttribute, controller); sizeDiff.x = subView->getWidth () - view->getWidth (); sizeDiff.y = subView->getHeight () - view->getHeight (); CRect size = view->getViewSize (); size.setWidth (subView->getWidth ()); size.setHeight (subView->getHeight ()); view->setViewSize (size); view->setMouseableArea (size); if (auto container = view->asViewContainer ()) container->addView (subView); if (controller) dialogController->remember (); customViewEmbedder = view; } } } else if (auto shadowViewContainer = dynamic_cast (view)) { if (resizable) { auto container = new CViewContainer (view->getViewSize ()); container->setAutosizeFlags (view->getAutosizeFlags ()); while (shadowViewContainer->hasChildren ()) { auto child = shared (shadowViewContainer->getView (0)); shadowViewContainer->removeView (child, false); container->addView (child); } view->forget (); view = container; } } return view; } //---------------------------------------------------------------------------------------------------- void UIDialogController::layoutButtons () { if (button1 && button2) { CRect b1r1 = button1->getViewSize (); CRect b2r1 = button2->getViewSize (); CCoord margin = b1r1.left - b2r1.right; button1->sizeToFit (); button2->sizeToFit (); CRect b1r2 = button1->getViewSize (); CRect b2r2 = button2->getViewSize (); b1r2.offset (b1r1.getWidth () - b1r2.getWidth (), b1r1.getHeight () - b1r2.getHeight ()); button1->setViewSize (b1r2); button1->setMouseableArea (b1r2); b2r2.offset (b2r1.getWidth () - b2r2.getWidth (), b2r1.getHeight () - b2r2.getHeight ()); b2r2.offset ((b1r2.left - margin) - b2r2.right, 0); button2->setViewSize (b2r2); button2->setMouseableArea (b2r2); } } //---------------------------------------------------------------------------------------------------- void UIDialogController::onKeyboardEvent (KeyboardEvent& event, CFrame* inFrame) { auto guard = shared (this); if (auto focusView = shared (inFrame->getFocusView ())) { focusView->dispatchEvent (event); if (event.consumed) return; } if (event.type != EventType::KeyUp) { if (event.virt == VirtualKey::Return && event.modifiers.empty ()) { button1->setValue (button1->getMax ()); button1->valueChanged (); event.consumed = true; } else if (event.virt == VirtualKey::Escape && event.modifiers.empty () && button2->isVisible ()) { button2->setValue (button2->getMax ()); button2->valueChanged (); event.consumed = true; } } } //---------------------------------------------------------------------------------------------------- void UIDialogController::collectOpenGLViews (CViewContainer* container) { #if VSTGUI_OPENGL_SUPPORT container->forEachChild ([this] (CView* view) { auto openGLView = dynamic_cast (view); if (openGLView && openGLView->isVisible ()) openglViews.emplace_back (openGLView); else if (auto childContainer = view->asViewContainer ()) collectOpenGLViews (childContainer); }); #endif } //---------------------------------------------------------------------------------------------------- void UIDialogController::setOpenGLViewsVisible (bool state) { #if VSTGUI_OPENGL_SUPPORT for (auto& v : openglViews) v->setVisible (state); #endif } } // VSTGUI #endif // VSTGUI_LIVE_EDITING