// 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 "cframe.h" #include "events.h" #include "finally.h" #include "coffscreencontext.h" #include "ctooltipsupport.h" #include "cinvalidrectlist.h" #include "itouchevent.h" #include "iscalefactorchangedlistener.h" #include "idatapackage.h" #include "iviewlayouter.h" #include "animation/animator.h" #include "controls/ctextedit.h" #include "platform/platformfactory.h" #include "platform/iplatformframe.h" #include #include #include #include #include namespace VSTGUI { IdStringPtr kMsgNewFocusView = "kMsgNewFocusView"; IdStringPtr kMsgOldFocusView = "kMsgOldFocusView"; #define DEBUG_MOUSE_VIEWS (DEBUG && 0) //------------------------------------------------------------------------ struct CFrame::CollectInvalidRects { explicit CollectInvalidRects (CFrame* frame); ~CollectInvalidRects () noexcept; void addRect (const CRect& rect); void flush (); private: using InvalidRects = std::vector; SharedPointer frame; CInvalidRectList invalidRects; uint64_t lastTicks; #if VSTGUI_LOG_COLLECT_INVALID_RECTS uint32_t numAddedRects; #endif }; //------------------------------------------------------------------------ struct ModalViewSession { ModalViewSessionID identifier {}; SharedPointer view; }; //------------------------------------------------------------------------ struct CFrame::Impl { using ViewList = std::list; using FunctionQueue = std::queue; using ModalViewSessionStack = std::stack; PlatformFramePtr platformFrame; VSTGUIEditorInterface* editor {nullptr}; IViewAddedRemovedObserver* viewAddedRemovedObserver {nullptr}; SharedPointer tooltips; SharedPointer animator; #if VSTGUI_ENABLE_DEPRECATED_METHODS Optional legacyModalViewSessionID; #endif CView* focusView {nullptr}; CView* activeFocusView {nullptr}; CollectInvalidRects* collectInvalidRects {nullptr}; ViewList mouseViews; ModalViewSessionStack modalViewSessionStack; DispatchList windowActiveStateChangeViews; DispatchList scaleFactorChangedListenerList; DispatchList mouseObservers; DispatchList focusViewObservers; DispatchList keyboardHooks; FunctionQueue postEventFunctionQueue; std::optional lastCheckSizeConstraintLayout; ModalViewSessionID modalViewSessionIDCounter {0}; double userScaleFactor {1.}; double platformScaleFactor {1.}; bool active {false}; bool windowActive {false}; bool inEventHandling {false}; BitmapInterpolationQuality bitmapQuality {BitmapInterpolationQuality::kDefault}; struct PostEventHandler { PostEventHandler (Impl& impl) : impl (impl) { wasInEventHandling = impl.inEventHandling; impl.inEventHandling = true; } ~PostEventHandler () noexcept { vstgui_assert (impl.inEventHandling == true); impl.inEventHandling = wasInEventHandling; FunctionQueue fl; impl.postEventFunctionQueue.swap (fl); while (!fl.empty ()) { fl.front () (); fl.pop (); } } private: Impl& impl; bool wasInEventHandling; }; }; //----------------------------------------------------------------------------- // CFrame Implementation //----------------------------------------------------------------------------- /*! @class CFrame It creates a platform dependend view object. On Mac OS X it is a HIView or NSView.\n On Windows it's a WS_CHILD Window. */ //----------------------------------------------------------------------------- CFrame::CFrame (const CRect& inSize, VSTGUIEditorInterface* inEditor) : CViewContainer (inSize) { pImpl = new Impl; pImpl->editor = inEditor; setParentFrame (this); } //----------------------------------------------------------------------------- void CFrame::beforeDelete () { clearMouseViews (CPoint (0, 0), Modifiers (), false); clearModalViewSessions (); setCursor (kCursorDefault); setParentFrame (nullptr); removeAll (); pImpl->tooltips = nullptr; pImpl->animator = nullptr; #if DEBUG if (!pImpl->scaleFactorChangedListenerList.empty ()) { DebugPrint ("Warning: Scale Factor Changed Listeners are not cleaned up correctly.\n If you register a change listener you must also unregister it !\n"); } if (!pImpl->mouseObservers.empty ()) { DebugPrint ("Warning: Mouse Observers are not cleaned up correctly.\n If you register a mouse oberver you must also unregister it !\n"); } if (!pImpl->keyboardHooks.empty ()) { DebugPrint ("Warning: Keyboard Hooks are not cleaned up correctly.\n If you register a keyboard hook you must also unregister it !\n"); } #endif if (pImpl->platformFrame) { pImpl->platformFrame->onFrameClosed (); pImpl->platformFrame = nullptr; } setViewFlag (kIsAttached, false); delete pImpl; pImpl = nullptr; CViewContainer::beforeDelete (); } //----------------------------------------------------------------------------- void CFrame::close () { clearMouseViews (CPoint (0, 0), Modifiers (), false); clearModalViewSessions (); setCursor (kCursorDefault); setParentFrame (nullptr); removeAll (); if (pImpl->platformFrame) { pImpl->platformFrame->onFrameClosed (); pImpl->platformFrame = nullptr; } forget (); } //----------------------------------------------------------------------------- bool CFrame::open (void* systemWin, PlatformType systemWindowType, IPlatformFrameConfig* config) { if (!systemWin || isAttached ()) return false; pImpl->platformFrame = getPlatformFactory ().createFrame (this, getViewSize (), systemWin, systemWindowType, config); if (!pImpl->platformFrame) { return false; } CollectInvalidRects cir (this); attached (this); setParentView (nullptr); invalid (); return true; } //----------------------------------------------------------------------------- bool CFrame::attached (CView* parent) { if (isAttached ()) return false; vstgui_assert (parent == this); if (CView::attached (parent)) { setParentView (nullptr); for (const auto& pV : getChildren ()) pV->attached (this); return true; } return false; } //----------------------------------------------------------------------------- bool CFrame::setZoom (double zoomFactor) { if (zoomFactor == 0.) return false; bool result = true; CGraphicsTransform currentTransform = getTransform (); CCoord origWidth = getWidth () / currentTransform.m11; CCoord origHeight = getHeight () / currentTransform.m22; CCoord newWidth = origWidth * zoomFactor; CCoord newHeight = origHeight * zoomFactor; setAutosizingEnabled (false); setTransform (CGraphicsTransform ().scale (zoomFactor, zoomFactor)); if (!setSize (newWidth, newHeight)) { setTransform (currentTransform); setSize (origWidth * currentTransform.m11, origHeight * currentTransform.m22); result = false; } invalid (); setAutosizingEnabled (true); if (result) { pImpl->userScaleFactor = zoomFactor; dispatchNewScaleFactor (getScaleFactor ()); } return result; } //----------------------------------------------------------------------------- double CFrame::getZoom () const { return pImpl->userScaleFactor; } //----------------------------------------------------------------------------- void CFrame::setBitmapInterpolationQuality (BitmapInterpolationQuality quality) { if (pImpl && pImpl->bitmapQuality != quality) { pImpl->bitmapQuality = quality; invalid (); } } //----------------------------------------------------------------------------- BitmapInterpolationQuality CFrame::getBitmapInterpolationQuality () const { if (pImpl) return pImpl->bitmapQuality; return BitmapInterpolationQuality::kDefault; } //----------------------------------------------------------------------------- double CFrame::getScaleFactor () const { return pImpl->platformScaleFactor * pImpl->userScaleFactor; } //----------------------------------------------------------------------------- void CFrame::enableTooltips (bool state, uint32_t delayTimeInMs) { if (state) { if (pImpl->tooltips == nullptr) pImpl->tooltips = makeOwned (this, delayTimeInMs); } else if (pImpl->tooltips) { pImpl->tooltips = nullptr; } } //----------------------------------------------------------------------------- void CFrame::draw (CDrawContext* pContext) { return CFrame::drawRect (pContext, getViewSize ()); } //----------------------------------------------------------------------------- void CFrame::drawRect (CDrawContext* pContext, const CRect& updateRect) { if (updateRect.getWidth () <= 0 || updateRect.getHeight () <= 0 || pContext == nullptr) return; auto lifeGuard = shared (pContext); if (pImpl) pContext->setBitmapInterpolationQuality (pImpl->bitmapQuality); drawClipped (pContext, updateRect, [&] () { // draw the background and the children CViewContainer::drawRect (pContext, updateRect); }); } //----------------------------------------------------------------------------- void CFrame::clearMouseViews (const CPoint& where, Modifiers modifiers, bool callMouseExit) { auto it = pImpl->mouseViews.rbegin (); while (it != pImpl->mouseViews.rend ()) { if (callMouseExit) { MouseExitEvent exitEvent; exitEvent.modifiers = modifiers; exitEvent.mousePosition = (*it)->translateToLocal (where, true); dispatchEvent ((*it), exitEvent); #if DEBUG_MOUSE_VIEWS DebugPrint ("mouseExited : %p[%d,%d]\n", (*it), (int)exitEvent.mousePosition.x, (int)exitEvent.mousePosition.y); #endif } if (pImpl->tooltips) pImpl->tooltips->onMouseExited ((*it)); callMouseObserverMouseExited ((*it)); (*it)->forget (); ++it; } pImpl->mouseViews.clear (); } //----------------------------------------------------------------------------- void CFrame::removeFromMouseViews (CView* view) { bool found = false; auto it = pImpl->mouseViews.begin (); while (it != pImpl->mouseViews.end ()) { if (found || (*it) == view) { if (pImpl->tooltips) pImpl->tooltips->onMouseExited ((*it)); callMouseObserverMouseExited ((*it)); (*it)->forget (); pImpl->mouseViews.erase (it++); found = true; } else ++it; } } //----------------------------------------------------------------------------- void CFrame::checkMouseViews (const MouseEvent& event) { if (getMouseDownView ()) return; CView* mouseView = getViewAt (event.mousePosition, GetViewOptions ().deep ().mouseEnabled ().includeViewContainer ()); CView* currentMouseView = pImpl->mouseViews.empty () == false ? pImpl->mouseViews.back () : nullptr; if (currentMouseView == mouseView) return; // no change if (pImpl->tooltips) { if (currentMouseView) pImpl->tooltips->onMouseExited (currentMouseView); if (mouseView && mouseView != this) pImpl->tooltips->onMouseEntered (mouseView); } if (mouseView == nullptr || mouseView == this) { clearMouseViews (event.mousePosition, event.modifiers); return; } auto callMouseExitForView = [this, &event] (CView* view) { MouseExitEvent exitEvent (event); exitEvent.mousePosition = view->translateToLocal (exitEvent.mousePosition, true); dispatchEvent (view, exitEvent); callMouseObserverMouseExited (view); #if DEBUG_MOUSE_VIEWS DebugPrint ("mouseExited : %p[%d,%d]\n", view, (int)exitEvent.mousePosition.x, (int)exitEvent.mousePosition.y); #endif }; auto callMouseEnterForView = [this, &event] (CView* view) { MouseEnterEvent enterEvent (event); enterEvent.mousePosition = view->translateToLocal (enterEvent.mousePosition, true); dispatchEvent (view, enterEvent); callMouseObserverMouseEntered (view); #if DEBUG_MOUSE_VIEWS DebugPrint ("mouseEntered : %p[%d,%d]\n", view, (int)enterEvent.mousePosition.x, (int)enterEvent.mousePosition.y); #endif }; CViewContainer* vc = currentMouseView ? currentMouseView->asViewContainer () : nullptr; // if the currentMouseView is not a view container, we know that the new mouseView won't be a child of it and that all other // views in the list are viewcontainers if (vc == nullptr && currentMouseView) { callMouseExitForView (currentMouseView); currentMouseView->forget (); pImpl->mouseViews.remove (currentMouseView); } auto it = pImpl->mouseViews.rbegin (); while (it != pImpl->mouseViews.rend ()) { vc = static_cast ((*it)); if (vc == mouseView) return; if (vc->isChild (mouseView, true) == false) { callMouseExitForView (vc); vc->forget (); pImpl->mouseViews.erase (--it.base ()); } else break; } vc = pImpl->mouseViews.empty () == false ? pImpl->mouseViews.back ()->asViewContainer () : nullptr; if (vc) { auto it2 = pImpl->mouseViews.end (); --it2; CView* container = mouseView; while ((vc = static_cast (container->getParentView ())) != *it2 && vc) { pImpl->mouseViews.emplace_back (vc); vc->remember (); container = vc; } pImpl->mouseViews.emplace_back (mouseView); mouseView->remember (); ++it2; while (it2 != pImpl->mouseViews.end ()) { callMouseEnterForView (*it2); ++it2; } } else { // must be pMouseViews.size () == 0 vstgui_assert (pImpl->mouseViews.empty ()); pImpl->mouseViews.emplace_back (mouseView); mouseView->remember (); while ((vc = static_cast (mouseView->getParentView ())) != this && vc) { pImpl->mouseViews.push_front (vc); vc->remember (); mouseView = vc; } auto it2 = pImpl->mouseViews.begin (); while (it2 != pImpl->mouseViews.end ()) { callMouseEnterForView (*it2); ++it2; } } } //------------------------------------------------------------------------ bool CFrame::hitTestSubViews (const CPoint& where, const Event& event) { if (auto modalView = getModalView ()) { CPoint where2 (where); getTransform ().inverse ().transform (where2); if (modalView->isVisible () && modalView->getMouseEnabled () && modalView->hitTest (where2, event)) { if (auto viewContainer = modalView->asViewContainer ()) { return viewContainer->hitTestSubViews (where2, event); } return true; } return false; } return CViewContainer::hitTestSubViews (where, event); } //----------------------------------------------------------------------------- void CFrame::dispatchEvent (CView* view, Event& event) { view->dispatchEvent (event); } //----------------------------------------------------------------------------- void CFrame::dispatchEventToChildren (Event& event) { CView::dispatchEvent (event); } //----------------------------------------------------------------------------- void CFrame::dispatchKeyboardEvent (KeyboardEvent& event) { if (static_cast (event.virt) > static_cast (VirtualKey::Equals)) event.virt = VirtualKey::None; dispatchKeyboardEventToHooks (event); if (event.consumed) return; if (pImpl->focusView) { CBaseObjectGuard og (pImpl->focusView); if (pImpl->focusView->getMouseEnabled ()) dispatchEvent (pImpl->focusView, event); if (event.consumed) return; CView* parent = pImpl->focusView->getParentView (); while (parent && parent != this) { if (parent->getMouseEnabled ()) { dispatchEvent (parent, event); if (event.consumed) return; } parent = parent->getParentView (); } } if (auto modalView = getModalView ()) { CBaseObjectGuard og (modalView); dispatchEvent (modalView, event); if (event.consumed) return; } if (event.type != EventType::KeyUp && event.virt == VirtualKey::Tab) { if (event.modifiers.empty () || event.modifiers.is (ModifierKey::Shift)) { if (advanceNextFocusView (pImpl->focusView, event.modifiers.is (ModifierKey::Shift))) event.consumed = true; } } } //------------------------------------------------------------------------ void CFrame::dispatchMouseDownEvent (MouseDownEvent& event) { auto originMousePosition = event.mousePosition; auto transformedMousePosition = event.mousePosition; getTransform ().inverse ().transform (transformedMousePosition); if (auto tooltips = pImpl->tooltips) tooltips->onMouseDown (transformedMousePosition); event.mousePosition = transformedMousePosition; callMouseObserverOtherMouseEvent (event); if (event.consumed) return; event.mousePosition = originMousePosition; setMouseDownView (nullptr); if (pImpl->focusView && dynamic_cast (pImpl->focusView)) setFocusView (nullptr); if (auto modalView = shared (getModalView ())) { if (modalView->isVisible () && modalView->getMouseEnabled ()) { event.mousePosition = transformedMousePosition; #if VSTGUI_ENABLE_DEPRECATED_METHODS auto buttonState = buttonStateFromMouseEvent (event); auto result = modalView->callMouseListener (MouseListenerCall::MouseDown, event.mousePosition, buttonState); if (result != kMouseEventNotHandled && result != kMouseEventNotImplemented) { event.consumed = true; return; } #endif dispatchEvent (modalView, event); if (event.consumed) setMouseDownView (modalView); } return; } dispatchEventToChildren (event); } //------------------------------------------------------------------------ void CFrame::dispatchMouseMoveEvent (MouseMoveEvent& event) { auto originMousePosition = event.mousePosition; auto transformedMousePosition = event.mousePosition; getTransform ().inverse ().transform (transformedMousePosition); if (auto tooltips = pImpl->tooltips) tooltips->onMouseMoved (transformedMousePosition); checkMouseViews (event); event.mousePosition = transformedMousePosition; callMouseObserverOtherMouseEvent (event); if (event.consumed) return; event.mousePosition = originMousePosition; if (auto modalView = shared (getModalView ())) { if (modalView->isVisible () && modalView->getMouseEnabled ()) { event.mousePosition = transformedMousePosition; #if VSTGUI_ENABLE_DEPRECATED_METHODS auto buttonState = buttonStateFromMouseEvent (event); auto result = modalView->callMouseListener (MouseListenerCall::MouseMoved, event.mousePosition, buttonState); if (result != kMouseEventNotHandled && result != kMouseEventNotImplemented) { event.consumed = true; return; } #endif dispatchEvent (modalView, event); } } else dispatchEventToChildren (event); if (event.consumed == false) { event.buttonState.clear (); auto it = pImpl->mouseViews.rbegin (); while (it != pImpl->mouseViews.rend ()) { CPoint p (transformedMousePosition); auto view = *it; if (view->asViewContainer ()) { if (auto parent = view->getParentView ()) { if (parent != this) { p.offsetInverse (parent->getViewSize ().getTopLeft ()); parent->translateToLocal (p, true); } } } else view->translateToLocal (p, true); event.mousePosition = p; dispatchEvent (view, event); if (event.consumed) break; ++it; } } } //------------------------------------------------------------------------ void CFrame::dispatchMouseUpEvent (MouseUpEvent& event) { auto transformedMousePosition = event.mousePosition; getTransform ().inverse ().transform (transformedMousePosition); auto f = finally ([this] () { setMouseDownView (nullptr); }); callMouseObserverOtherMouseEvent (event); if (event.consumed) return; if (auto modalView = shared (getModalView ())) { if (modalView->isVisible () && modalView->getMouseEnabled ()) { event.mousePosition = transformedMousePosition; #if VSTGUI_ENABLE_DEPRECATED_METHODS auto buttonState = buttonStateFromMouseEvent (event); auto result = modalView->callMouseListener (MouseListenerCall::MouseUp, event.mousePosition, buttonState); if (result != kMouseEventNotHandled && result != kMouseEventNotImplemented) { event.consumed = true; return; } #endif dispatchEvent (modalView, event); } return; } dispatchEventToChildren (event); } //------------------------------------------------------------------------ void CFrame::dispatchMouseEvent (MouseEvent& event) { if (event.type == EventType::MouseMove) dispatchMouseMoveEvent (castMouseMoveEvent (event)); else if (event.type == EventType::MouseDown) dispatchMouseDownEvent (castMouseDownEvent (event)); else if (event.type == EventType::MouseUp) dispatchMouseUpEvent (castMouseUpEvent (event)); else if (event.type == EventType::MouseEnter) {} else if (event.type == EventType::MouseExit) { if (getMouseDownView () == nullptr) { clearMouseViews (event.mousePosition, event.modifiers); if (pImpl->tooltips) pImpl->tooltips->hideTooltip (); } event.consumed = true; } else { vstgui_assert (false); } } //----------------------------------------------------------------------------- void CFrame::dispatchEvent (Event& event) { Impl::PostEventHandler peh (*pImpl); CollectInvalidRects cir (this); if (auto mouseEvent = asMouseEvent (event)) { dispatchMouseEvent (*mouseEvent); return; } if (auto keyEvent = asKeyboardEvent (event)) { dispatchKeyboardEvent (*keyEvent); return; } auto mousePosEvent = asMousePositionEvent (event); CPoint mousePosition; if (mousePosEvent) mousePosition = mousePosEvent->mousePosition; auto modalView = getModalView (); if (modalView && mousePosEvent) getTransform ().inverse ().transform (mousePosEvent->mousePosition); if (modalView) dispatchEvent (modalView, event); else dispatchEventToChildren (event); if (mousePosEvent) { MouseEvent mouseEvent; mouseEvent.mousePosition = mousePosEvent->mousePosition; mouseEvent.modifiers = mousePosEvent->modifiers; checkMouseViews (mouseEvent); } } //----------------------------------------------------------------------------- SharedPointer CFrame::getClipboard () { return getPlatformFactory ().getClipboard (); } //----------------------------------------------------------------------------- void CFrame::setClipboard (const SharedPointer& data) { getPlatformFactory ().setClipboard (data); } //----------------------------------------------------------------------------- void CFrame::idle () { if (CView::kDirtyCallAlwaysOnMainThread) return; invalidateDirtyViews (); } //----------------------------------------------------------------------------- Animation::Animator* CFrame::getAnimator () { if (pImpl->animator == nullptr) pImpl->animator = makeOwned (); return pImpl->animator; } //----------------------------------------------------------------------------- /** * @return tick count in milliseconds */ uint64_t CFrame::getTicks () const { return getPlatformFactory ().getTicks (); } //----------------------------------------------------------------------------- int32_t CFrame::kDefaultKnobMode = kCircularMode; //----------------------------------------------------------------------------- int32_t CFrame::getKnobMode () const { int32_t result = pImpl->editor ? pImpl->editor->getKnobMode () : -1; if (result == -1) result = kDefaultKnobMode; return result; } //----------------------------------------------------------------------------- /** * repositions the frame * @param x x coordinate * @param y y coordinate * @return true on success */ bool CFrame::setPosition (CCoord x, CCoord y) { if (pImpl->platformFrame) { CRect rect (getViewSize ()); rect.offset (x - getViewSize ().left, y - getViewSize ().top); if (pImpl->platformFrame->setSize (rect)) { setViewSize (rect, false); return true; } } return false; } //----------------------------------------------------------------------------- /** * get global position of frame * @param x x coordinate * @param y y coordinate * @return true on success */ bool CFrame::getPosition (CCoord &x, CCoord &y) const { if (pImpl->platformFrame) { CPoint p; if (pImpl->platformFrame->getGlobalPosition (p)) { x = p.x; y = p.y; return true; } } return false; } //----------------------------------------------------------------------------- void CFrame::setViewSize (const CRect& rect, bool invalid) { if (pImpl->lastCheckSizeConstraintLayout) { auto layout = std::move (*pImpl->lastCheckSizeConstraintLayout); pImpl->lastCheckSizeConstraintLayout = {}; if (layout.size == rect) { if (applyViewLayout (layout)) return; } } CViewContainer::setViewSize (rect, invalid); } //----------------------------------------------------------------------------- CPoint CFrame::checkSizeConstraint (const CPoint& newSize) const { pImpl->lastCheckSizeConstraintLayout = calculateViewLayout ({0., 0., newSize.x, newSize.y}); if (pImpl->lastCheckSizeConstraintLayout) return pImpl->lastCheckSizeConstraintLayout->size.getSize (); return getViewSize ().getSize (); } //----------------------------------------------------------------------------- /** * set size of frame (and the platform representation) * @param width new width * @param height new height * @return true on success */ bool CFrame::setSize (CCoord width, CCoord height) { if ((width == getViewSize ().getWidth ()) && (height == getViewSize ().getHeight ())) return true; CRect newSize (getViewSize ()); newSize.setWidth (width); newSize.setHeight (height); if (getEditor ()) { if (getEditor ()->beforeSizeChange (newSize, getViewSize ()) == false) return false; } if (pImpl->platformFrame) { if (pImpl->platformFrame->setSize (newSize)) { setViewSize (newSize); return true; } return false; } setViewSize (newSize); return true; } //----------------------------------------------------------------------------- /** * get size relative to parent * @param pRect size * @return true on success */ bool CFrame::getSize (CRect* pRect) const { if (pImpl->platformFrame && pRect) return pImpl->platformFrame->getSize (*pRect); return false; } //----------------------------------------------------------------------------- bool CFrame::getSize (CRect& outSize) const { return getSize (&outSize); } #if VSTGUI_ENABLE_DEPRECATED_METHODS //----------------------------------------------------------------------------- /** * @param pView the view which should be set to modal. * @return true if view could be set as the modal view. false if there is a already a modal view or the view to be set as modal is already attached. */ bool CFrame::setModalView (CView* pView) { if (pImpl->modalViewSessionStack.empty () && pView == nullptr) return true; if (pView && !pImpl->modalViewSessionStack.empty ()) return false; if (!pView) endLegacyModalViewSession (); else pImpl->legacyModalViewSessionID = beginModalViewSession (pView); return true; } //----------------------------------------------------------------------------- void CFrame::endLegacyModalViewSession () { vstgui_assert (pImpl->legacyModalViewSessionID); vstgui_assert (pImpl->modalViewSessionStack.top ().identifier == *pImpl->legacyModalViewSessionID); pImpl->modalViewSessionStack.top ().view->remember (); endModalViewSession (*pImpl->legacyModalViewSessionID); pImpl->legacyModalViewSessionID = {}; } #endif //----------------------------------------------------------------------------- CView* CFrame::getModalView () const { if (!pImpl->modalViewSessionStack.empty ()) return pImpl->modalViewSessionStack.top ().view; return nullptr; } //----------------------------------------------------------------------------- void CFrame::initModalViewSession (const ModalViewSession& session) { if (getMouseDownView ()) { onMouseCancel (); } clearMouseViews (CPoint (0, 0), Modifiers (), true); if (auto container = session.view->asViewContainer ()) container->advanceNextFocusView (nullptr, false); else setFocusView (session.view->wantsFocus () ? session.view : nullptr); if (isAttached ()) { CPoint where; getCurrentMouseLocation (where); MouseEvent mouseEvent; mouseEvent.mousePosition = where; // TODO: modifiers and mouse button state checkMouseViews (mouseEvent); } } //----------------------------------------------------------------------------- void CFrame::clearModalViewSessions () { #if VSTGUI_ENABLE_DEPRECATED_METHODS if (pImpl->legacyModalViewSessionID) endLegacyModalViewSession (); #endif while (!pImpl->modalViewSessionStack.empty ()) endModalViewSession (pImpl->modalViewSessionStack.top ().identifier); } //----------------------------------------------------------------------------- Optional CFrame::beginModalViewSession (CView* view) { if (view->isAttached ()) { #if DEBUG DebugPrint ("the view must not be attached when used for beginModalViewSession"); #endif return {}; } if (!addView (view)) { return {}; } ModalViewSession session; session.identifier = ++pImpl->modalViewSessionIDCounter; session.view = view; pImpl->modalViewSessionStack.push (session); initModalViewSession (session); return makeOptional (session.identifier); } //----------------------------------------------------------------------------- bool CFrame::endModalViewSession (ModalViewSessionID sessionID) { if (pImpl->modalViewSessionStack.empty ()) return false; if (pImpl->modalViewSessionStack.top ().identifier != sessionID) return false; auto view = pImpl->modalViewSessionStack.top ().view; pImpl->modalViewSessionStack.pop (); removeView (view); if (!pImpl->modalViewSessionStack.empty ()) initModalViewSession (pImpl->modalViewSessionStack.top ()); return true; } //----------------------------------------------------------------------------- void CFrame::beginEdit (int32_t index) { if (pImpl->editor) pImpl->editor->beginEdit (index); } //----------------------------------------------------------------------------- void CFrame::endEdit (int32_t index) { if (pImpl->editor) pImpl->editor->endEdit (index); } //----------------------------------------------------------------------------- /** * @param where location of mouse * @return true on success */ bool CFrame::getCurrentMouseLocation (CPoint &where) const { if (pImpl->platformFrame) { if (pImpl->platformFrame->getCurrentMousePosition (where)) { getTransform().transform (where); return true; } } return false; } //----------------------------------------------------------------------------- /** * @return mouse and modifier state */ CButtonState CFrame::getCurrentMouseButtons () const { CButtonState buttons = 0; if (pImpl->platformFrame) pImpl->platformFrame->getCurrentMouseButtons (buttons); return buttons; } //----------------------------------------------------------------------------- /** * @param type cursor type see #CCursorType */ void CFrame::setCursor (CCursorType type) { if (pImpl->platformFrame) pImpl->platformFrame->setMouseCursor (type); } //----------------------------------------------------------------------------- /** * @param pView view which was removed */ void CFrame::onViewRemoved (CView* pView) { removeFromMouseViews (pView); if (pImpl->activeFocusView == pView) pImpl->activeFocusView = nullptr; if (pImpl->focusView == pView) { if (pImpl->active) setFocusView (nullptr); else pImpl->focusView = nullptr; } if (auto container = pView->asViewContainer ()) { if (container->isChild (pImpl->focusView, true)) setFocusView (nullptr); } if (getViewAddedRemovedObserver ()) getViewAddedRemovedObserver ()->onViewRemoved (this, pView); if (pView->wantsWindowActiveStateChangeNotification ()) pImpl->windowActiveStateChangeViews.remove (pView); if (pImpl->animator) pImpl->animator->removeAnimations (pView); } //----------------------------------------------------------------------------- /** * @param pView view which was added */ void CFrame::onViewAdded (CView* pView) { if (getViewAddedRemovedObserver ()) getViewAddedRemovedObserver ()->onViewAdded (this, pView); if (pView->wantsWindowActiveStateChangeNotification ()) { pImpl->windowActiveStateChangeViews.add (pView); pView->onWindowActivate (pImpl->windowActive); } } //----------------------------------------------------------------------------- /** * @param pView new focus view */ void CFrame::setFocusView (CView *pView) { static bool recursion = false; if (pView == pImpl->focusView || (recursion && pImpl->focusView != nullptr)) return; if (pView && !pImpl->modalViewSessionStack.empty ()) { if (auto modalContainer = pImpl->modalViewSessionStack.top ().view->asViewContainer ()) { if (!modalContainer->isChild (pView, true)) { #if DEBUG DebugPrint ( "Could not set the focus view " \ "as it is not a child of the currently displayed modal view\n"); #endif return; } } } if (!pImpl->active) { pImpl->activeFocusView = pView; return; } recursion = true; CView *pOldFocusView = pImpl->focusView; if (pView == nullptr || (pView && pView->isAttached () == false)) pImpl->focusView = nullptr; else pImpl->focusView = pView; if (pImpl->focusView && pImpl->focusView->wantsFocus ()) { pImpl->focusView->invalid (); CView* receiver = pImpl->focusView->getParentView (); while (receiver != this && receiver != nullptr) { receiver->notify (pImpl->focusView, kMsgNewFocusView); receiver = receiver->getParentView (); } notify (pImpl->focusView, kMsgNewFocusView); } if (pOldFocusView) { if (pOldFocusView->wantsFocus ()) { pOldFocusView->invalid (); CView* receiver = pOldFocusView->getParentView (); while (receiver != this && receiver != nullptr) { receiver->notify (pOldFocusView, kMsgOldFocusView); receiver = receiver->getParentView (); } notify (pOldFocusView, kMsgOldFocusView); } pOldFocusView->looseFocus (); } if (pImpl->focusView && pImpl->focusView->wantsFocus ()) pImpl->focusView->takeFocus (); pImpl->focusViewObservers.forEach ([&] (IFocusViewObserver* observer) { observer->onFocusViewChanged (this, pImpl->focusView, pOldFocusView); }); recursion = false; } //----------------------------------------------------------------------------- CView* CFrame::getFocusView () const { return pImpl->focusView; } //----------------------------------------------------------------------------- bool CFrame::advanceNextFocusView (CView* oldFocus, bool reverse) { if (auto modalView = getModalView ()) { if (auto container = modalView->asViewContainer ()) { if (oldFocus == nullptr || container->isChild (oldFocus, true) == false) return container->advanceNextFocusView (nullptr, reverse); else { if (auto* parentView = static_cast (oldFocus->getParentView ())) { CView* tempOldFocus = oldFocus; while (parentView != container) { if (parentView->advanceNextFocusView (tempOldFocus, reverse)) return true; else { tempOldFocus = parentView; parentView = static_cast (parentView->getParentView ()); } } if (container->advanceNextFocusView (tempOldFocus, reverse)) return true; return container->advanceNextFocusView (nullptr, reverse); } } } else if (oldFocus != modalView) { setFocusView (modalView); return true; } return false; // currently not supported, but should be done sometime } if (oldFocus == nullptr) { if (pImpl->focusView == nullptr) return CViewContainer::advanceNextFocusView (nullptr, reverse); oldFocus = pImpl->focusView; } if (isChild (oldFocus)) { if (CViewContainer::advanceNextFocusView (oldFocus, reverse)) return true; else { setFocusView (nullptr); return false; } } if (auto* parentView = static_cast (oldFocus->getParentView ())) { CView* tempOldFocus = oldFocus; while (parentView) { if (parentView->advanceNextFocusView (tempOldFocus, reverse)) return true; else { tempOldFocus = parentView; parentView = static_cast (parentView->getParentView ()); } } } return CViewContainer::advanceNextFocusView (oldFocus, reverse); } //----------------------------------------------------------------------------- bool CFrame::removeView (CView* pView, bool withForget) { #if DEBUG vstgui_assert (getModalView () != pView); #endif return CViewContainer::removeView (pView, withForget); } //----------------------------------------------------------------------------- bool CFrame::removeAll (bool withForget) { clearModalViewSessions (); if (pImpl->focusView) { pImpl->focusView->looseFocus (); pImpl->focusView = nullptr; } pImpl->activeFocusView = nullptr; clearMouseViews (CPoint (0, 0), Modifiers (), false); return CViewContainer::removeAll (withForget); } //----------------------------------------------------------------------------- CView* CFrame::getViewAt (const CPoint& where, const GetViewOptions& options) const { if (auto modalView = getModalView ()) { CPoint where2 (where); getTransform ().inverse ().transform (where2); if (modalView->getViewSize ().pointInside (where2)) { if (options.getDeep ()) { if (auto container = modalView->asViewContainer ()) { return container->getViewAt (where2, options); } } return modalView; } return nullptr; } return CViewContainer::getViewAt (where, options); } //----------------------------------------------------------------------------- CViewContainer* CFrame::getContainerAt (const CPoint& where, const GetViewOptions& options) const { if (auto modalView = getModalView ()) { CPoint where2 (where); getTransform ().inverse ().transform (where2); if (modalView->getViewSize ().pointInside (where2)) { if (auto container = modalView->asViewContainer ()) { if (options.getDeep ()) return container->getContainerAt (where2, options); return container; } } return nullptr; } return CViewContainer::getContainerAt (where, options); } //------------------------------------------------------------------------ bool CFrame::getViewsAt (const CPoint& where, ViewList& views, const GetViewOptions& options) const { if (auto modalView = getModalView ()) { CPoint where2 (where); getTransform ().inverse ().transform (where2); if (modalView->getViewSize ().pointInside (where2)) { if (options.getDeep ()) { if (auto container = modalView->asViewContainer ()) { container->getViewsAt (where2, views, options); } } if (!options.getIncludeViewContainer () && modalView->asViewContainer ()) return true; if (options.getMouseEnabled () && modalView->getMouseEnabled () == false) return true; if (!options.getIncludeInvisible () && !modalView->isVisible ()) return true; views.emplace_back (modalView); return true; } return false; } return CViewContainer::getViewsAt (where, views, options); } //----------------------------------------------------------------------------- void CFrame::onActivate (bool state) { if (pImpl->active != state) { if (state) { pImpl->active = true; if (pImpl->activeFocusView) { setFocusView (pImpl->activeFocusView); pImpl->activeFocusView = nullptr; } else advanceNextFocusView (nullptr, false); } else { if (pImpl->tooltips) pImpl->tooltips->hideTooltip (); pImpl->activeFocusView = getFocusView (); setFocusView (nullptr); pImpl->active = false; } } } //----------------------------------------------------------------------------- bool CFrame::focusDrawingEnabled () const { uint32_t attrSize; if (getAttributeSize ('vfde', attrSize)) return true; return false; } //----------------------------------------------------------------------------- CColor CFrame::getFocusColor () const { CColor focusColor (kRedCColor); getAttribute ('vfco', focusColor); return focusColor; } //----------------------------------------------------------------------------- CCoord CFrame::getFocusWidth () const { CCoord focusWidth = 2; getAttribute ('vfwi', focusWidth); return focusWidth; } //----------------------------------------------------------------------------- void CFrame::setFocusDrawingEnabled (bool state) { if (state) setAttribute ('vfde', state); else removeAttribute ('vfde'); } //----------------------------------------------------------------------------- void CFrame::setFocusColor (const CColor& color) { setAttribute ('vfco', color); } //----------------------------------------------------------------------------- void CFrame::setFocusWidth (CCoord width) { setAttribute ('vfwi', width); } //----------------------------------------------------------------------------- /** * @param src rect which to scroll * @param distance point of distance */ void CFrame::scrollRect (const CRect& src, const CPoint& distance) { CRect rect (src); rect.offset (getViewSize ().left, getViewSize ().top); if (pImpl->platformFrame) { if (pImpl->platformFrame->scrollRect (src, distance)) return; } invalidRect (src); } //----------------------------------------------------------------------------- void CFrame::invalidate (const CRect &rect) { for (const auto& pV : getChildren ()) { CRect rectView = pV->getViewSize (); if (rect.rectOverlap (rectView)) pV->setDirty (true); } } //----------------------------------------------------------------------------- void CFrame::invalidRect (const CRect& rect) { if (!isVisible () || !pImpl->platformFrame) return; CRect _rect (rect); getTransform ().transform (_rect); _rect.makeIntegral (); if (pImpl->collectInvalidRects) pImpl->collectInvalidRects->addRect (_rect); else pImpl->platformFrame->invalidRect (_rect); } //----------------------------------------------------------------------------- IViewAddedRemovedObserver* CFrame::getViewAddedRemovedObserver () const { return pImpl->viewAddedRemovedObserver; } //----------------------------------------------------------------------------- void CFrame::setViewAddedRemovedObserver (IViewAddedRemovedObserver* observer) { pImpl->viewAddedRemovedObserver = observer; } //----------------------------------------------------------------------------- void CFrame::registerKeyboardHook (IKeyboardHook* hook) { pImpl->keyboardHooks.add (hook); } //----------------------------------------------------------------------------- void CFrame::unregisterKeyboardHook (IKeyboardHook* hook) { pImpl->keyboardHooks.remove (hook); } //----------------------------------------------------------------------------- void CFrame::dispatchKeyboardEventToHooks (KeyboardEvent& event) { pImpl->keyboardHooks.forEachReverse ( [&] (IKeyboardHook* hook) { hook->onKeyboardEvent (event, this); return event.consumed; }, [] (bool consumed) { return consumed; }); } //----------------------------------------------------------------------------- void CFrame::registerScaleFactorChangedListener (IScaleFactorChangedListener* listener) { pImpl->scaleFactorChangedListenerList.add (listener); } //----------------------------------------------------------------------------- void CFrame::unregisterScaleFactorChangedListener (IScaleFactorChangedListener* listener) { pImpl->scaleFactorChangedListenerList.remove (listener); } //----------------------------------------------------------------------------- void CFrame::registerMouseObserver (IMouseObserver* observer) { pImpl->mouseObservers.add (observer); } //----------------------------------------------------------------------------- void CFrame::registerFocusViewObserver (IFocusViewObserver* observer) { pImpl->focusViewObservers.add (observer); } //----------------------------------------------------------------------------- void CFrame::unregisterFocusViewObserver (IFocusViewObserver* observer) { pImpl->focusViewObservers.remove (observer); } //----------------------------------------------------------------------------- void CFrame::unregisterMouseObserver (IMouseObserver* observer) { pImpl->mouseObservers.remove (observer); } //----------------------------------------------------------------------------- void CFrame::callMouseObserverMouseEntered (CView* view) { #if VSTGUI_ENABLE_DEPRECATED_METHODS view->callMouseListenerEnteredExited (true); #endif pImpl->mouseObservers.forEach ([&] (IMouseObserver* observer) { observer->onMouseEntered (view, this); }); } //----------------------------------------------------------------------------- void CFrame::callMouseObserverMouseExited (CView* view) { pImpl->mouseObservers.forEach ([&] (IMouseObserver* observer) { observer->onMouseExited (view, this); }); #if VSTGUI_ENABLE_DEPRECATED_METHODS view->callMouseListenerEnteredExited (false); #endif } //----------------------------------------------------------------------------- void CFrame::callMouseObserverOtherMouseEvent (MouseEvent& event) { pImpl->mouseObservers.forEach ( [&] (IMouseObserver* observer) { observer->onMouseEvent (event, this); }); } //------------------------------------------------------------------------ bool CFrame::performDrag (const DragDescription& desc, const SharedPointer& callback) { if (auto platformFrame = getPlatformFrame ()) { if (platformFrame->doDrag (desc, callback)) { setMouseDownView (nullptr); return true; } } return false; } #if DEBUG //----------------------------------------------------------------------------- void CFrame::dumpHierarchy () { dumpInfo (); DebugPrint ("\n"); CViewContainer::dumpHierarchy (); } #endif //----------------------------------------------------------------------------- VSTGUIEditorInterface* CFrame::getEditor () const { return pImpl->editor; } //----------------------------------------------------------------------------- IPlatformFrame* CFrame::getPlatformFrame () const { return pImpl->platformFrame; } //----------------------------------------------------------------------------- void CFrame::platformDrawRects (const PlatformGraphicsDeviceContextPtr& context, double scaleFactor, const std::vector& rects) { CDrawContext drawContext (context, getViewSize (), scaleFactor); for (auto rect : rects) drawRect (&drawContext, rect); } //----------------------------------------------------------------------------- void CFrame::platformOnEvent (Event& event) { dispatchEvent (event); } //----------------------------------------------------------------------------- DragOperation CFrame::platformOnDragEnter (DragEventData data) { if (!getMouseEnabled ()) return DragOperation::None; Impl::PostEventHandler peh (*pImpl); CollectInvalidRects cir (this); return getDropTarget ()->onDragEnter (data); } //----------------------------------------------------------------------------- DragOperation CFrame::platformOnDragMove (DragEventData data) { if (!getMouseEnabled ()) return DragOperation::None; Impl::PostEventHandler peh (*pImpl); CollectInvalidRects cir (this); return getDropTarget ()->onDragMove (data); } //----------------------------------------------------------------------------- void CFrame::platformOnDragLeave (DragEventData data) { if (!getMouseEnabled ()) return; Impl::PostEventHandler peh (*pImpl); CollectInvalidRects cir (this); getDropTarget ()->onDragLeave (data); } //----------------------------------------------------------------------------- bool CFrame::platformOnDrop (DragEventData data) { if (!getMouseEnabled ()) return false; Impl::PostEventHandler peh (*pImpl); CollectInvalidRects cir (this); return getDropTarget ()->onDrop (data); } //----------------------------------------------------------------------------- void CFrame::platformOnActivate (bool state) { if (getFrame ()) { CollectInvalidRects cir (this); onActivate (state); } } //------------------------------------------------------------------------ void CFrame::platformOnWindowActivate (bool state) { if (pImpl->windowActive == state) return; pImpl->windowActive = state; CollectInvalidRects cir (this); pImpl->windowActiveStateChangeViews.forEach ([&] (CView* view) { view->onWindowActivate (state); }); } //----------------------------------------------------------------------------- void CFrame::platformScaleFactorChanged (double newScaleFactor) { if (pImpl->platformScaleFactor == newScaleFactor) return; pImpl->platformScaleFactor = newScaleFactor; dispatchNewScaleFactor (getScaleFactor ()); } //----------------------------------------------------------------------------- void CFrame::dispatchNewScaleFactor (double newScaleFactor) { pImpl->scaleFactorChangedListenerList.forEach ([&] (IScaleFactorChangedListener* listener) { listener->onScaleFactorChanged (this, newScaleFactor); }); } #if VSTGUI_TOUCH_EVENT_HANDLING //----------------------------------------------------------------------------- void CFrame::platformOnTouchEvent (ITouchEvent& event) { Impl::PostEventHandler peh (*pImpl); std::vector targetDispatched; bool hasBeganTouch = false; for (const auto& e : event) { CView* target = e.second.target; if (target) { if (e.second.targetIsSingleTouch) { CPoint where (e.second.location); target->frameToLocal (where); switch (e.second.state) { case ITouchEvent::kMoved: { MouseMoveEvent moveEvent (where, MouseButton::Left); dispatchEvent (target, moveEvent); if (moveEvent.ignoreFollowUpMoveAndUpEvents ()) { event.unsetTouchTarget (e.first, target); MouseMoveEvent mouseMoveEvent (where, MouseButton::Left); if (target->hitTest (where, mouseMoveEvent) == false) { // when the touch goes out of the target and it tells us to const_cast (e.second).state = ITouchEvent::kBegan; hasBeganTouch = true; } } break; } case ITouchEvent::kCanceled: { MouseCancelEvent cancelEvent; dispatchEvent (target, cancelEvent); if (cancelEvent.consumed == false) { MouseUpEvent upEvent (where, MouseButton::Left); dispatchEvent (target, upEvent); } event.unsetTouchTarget (e.first, target); break; } case ITouchEvent::kEnded: { MouseUpEvent upEvent (where, MouseButton::Left); dispatchEvent (target, upEvent); event.unsetTouchTarget (e.first, target); break; } default: { // do nothing break; } } } else { if (std::find (targetDispatched.begin (), targetDispatched.end (), target) == targetDispatched.end ()) { target->onTouchEvent (event); targetDispatched.emplace_back (target); } } } else if (e.second.state == ITouchEvent::kBegan) { hasBeganTouch = true; } } if (hasBeganTouch) { if (CView* focusView = getFocusView ()) { if (dynamic_cast (focusView)) setFocusView (nullptr); } for (const auto& e : event) { if (e.second.target == nullptr && e.second.state == ITouchEvent::kBegan) { findSingleTouchEventTarget (const_cast (e.second)); } } onTouchEvent (event); } } #endif //----------------------------------------------------------------------------- bool CFrame::doAfterEventProcessing (EventProcessingFunction&& func) { if (pImpl->inEventHandling) pImpl->postEventFunctionQueue.push (std::move (func)); return pImpl->inEventHandling; } //----------------------------------------------------------------------------- bool CFrame::doAfterEventProcessing (const EventProcessingFunction& func) { if (pImpl->inEventHandling) pImpl->postEventFunctionQueue.push (func); return pImpl->inEventHandling; } //----------------------------------------------------------------------------- bool CFrame::inEventProcessing () const { return pImpl->inEventHandling; } //----------------------------------------------------------------------------- void CFrame::onStartLocalEventLoop () { if (pImpl->collectInvalidRects) { pImpl->collectInvalidRects->flush (); pImpl->collectInvalidRects = nullptr; } } //----------------------------------------------------------------------------- void CFrame::setCollectInvalidRects (CollectInvalidRects* cir) { if (pImpl->collectInvalidRects) pImpl->collectInvalidRects->flush (); pImpl->collectInvalidRects = cir; } //----------------------------------------------------------------------------- CFrame::CollectInvalidRects::CollectInvalidRects (CFrame* frame) : frame (frame) , lastTicks (frame->getTicks ()) { #if VSTGUI_LOG_COLLECT_INVALID_RECTS numAddedRects = 0; #endif frame->setCollectInvalidRects (this); } //----------------------------------------------------------------------------- CFrame::CollectInvalidRects::~CollectInvalidRects () noexcept { frame->setCollectInvalidRects (nullptr); } //----------------------------------------------------------------------------- void CFrame::CollectInvalidRects::flush () { if (!invalidRects.data ().empty ()) { if (frame->isVisible () && frame->pImpl->platformFrame) { for (auto& rect : invalidRects) frame->pImpl->platformFrame->invalidRect (rect); #if VSTGUI_LOG_COLLECT_INVALID_RECTS DebugPrint ("%d -> %d\n", numAddedRects, invalidRects.size ()); numAddedRects = 0; #endif } invalidRects.clear (); } } //----------------------------------------------------------------------------- void CFrame::CollectInvalidRects::addRect (const CRect& rect) { #if VSTGUI_LOG_COLLECT_INVALID_RECTS numAddedRects++; #endif invalidRects.add (rect); auto now = frame->getTicks (); if (now - lastTicks > 16) { flush (); lastTicks = now; } } #if VSTGUI_ENABLE_DEPRECATED_METHODS //----------------------------------------------------------------------------- void OldMouseObserverAdapter::onMouseEvent (MouseEvent& event, CFrame* frame) { if (event.type == EventType::MouseDown) { auto res = onMouseDown (frame, event.mousePosition, buttonStateFromMouseEvent (event)); if (res == kMouseEventHandled) event.consumed = true; if (res == kMouseDownEventHandledButDontNeedMovedOrUpEvents) { event.consumed = true; castMouseDownEvent (event).ignoreFollowUpMoveAndUpEvents (true); } } else if (event.type == EventType::MouseMove) { auto res = onMouseMoved (frame, event.mousePosition, buttonStateFromMouseEvent (event)); if (res == kMouseEventHandled) event.consumed = true; if (res == kMouseMoveEventHandledButDontNeedMoreEvents) { event.consumed = true; castMouseMoveEvent (event).ignoreFollowUpMoveAndUpEvents (true); } } } //----------------------------------------------------------------------------- CMouseEventResult OldMouseObserverAdapter::onMouseMoved (CFrame* frame, const CPoint& where, const CButtonState& buttons) { return kMouseEventNotHandled; } //----------------------------------------------------------------------------- CMouseEventResult OldMouseObserverAdapter::onMouseDown (CFrame* frame, const CPoint& where, const CButtonState& buttons) { return kMouseEventNotHandled; } //----------------------------------------------------------------------------- void OldKeyboardHookAdapter::onKeyboardEvent (KeyboardEvent& event, CFrame* frame) { auto vstKeyCode = toVstKeyCode (event); if (event.type == EventType::KeyDown) { if (onKeyDown (vstKeyCode, frame) != -1) event.consumed = true; } else { if (onKeyUp (vstKeyCode, frame) != -1) event.consumed = true; } } #endif } // VSTGUI