From 82f8d54acfc5aeec40ac6f3c4aa54863e97bcb86 Mon Sep 17 00:00:00 2001 From: scheffle Date: Mon, 30 May 2022 11:23:44 +0200 Subject: [PATCH 01/51] make "Open UI Editor" button optional and add "Save Screenshot" functionality. --- vstgui/plugin-bindings/vst3editor.cpp | 158 +++++++++++++++++++++++++- vstgui/plugin-bindings/vst3editor.h | 5 + 2 files changed, 158 insertions(+), 5 deletions(-) diff --git a/vstgui/plugin-bindings/vst3editor.cpp b/vstgui/plugin-bindings/vst3editor.cpp index 28899a2f9..dec1aa48e 100644 --- a/vstgui/plugin-bindings/vst3editor.cpp +++ b/vstgui/plugin-bindings/vst3editor.cpp @@ -8,6 +8,7 @@ #include "../lib/vstkeycode.h" #include "../lib/animation/timingfunctions.h" #include "../lib/animation/animations.h" +#include "../lib/platform/platformfactory.h" #include "../uidescription/detail/uiviewcreatorattributes.h" #include "../uidescription/editing/uieditcontroller.h" #include "../uidescription/editing/uieditmenucontroller.h" @@ -875,6 +876,12 @@ void VST3Editor::onMouseEvent (MouseEvent& event, CFrame* frame) CMenuItem* item = controllerMenu->addEntry (new CCommandMenuItem ( {"Open UIDescription Editor", this, "File", "Open UIDescription Editor"})); item->setKey ("e", kControl); + item = controllerMenu->addEntry (new CCommandMenuItem ( + {"Show 'Open UI Editor' Button", this, "File", "Show Editor Button"})); + if (enableShowEditButton ()) + item->setChecked (); + item = controllerMenu->addEntry (new CCommandMenuItem ( + {"Save Editor Screenshot", this, "File", "Save Editor Screenshot"})); } #endif CViewContainer::ViewList views; @@ -1276,6 +1283,7 @@ void PLUGIN_API VST3Editor::close () delete keyboardHook; } keyboardHook = nullptr; + openUIEditorController = nullptr; #endif getFrame ()->unregisterMouseObserver (this); getFrame ()->removeAll (true); @@ -1424,6 +1432,19 @@ bool VST3Editor::onCommandMenuItemSelected (CCommandMenuItem* item) item->setChecked (false); return true; } + else if (cmdName == "Save Editor Screenshot") + { + saveScreenshot (); + return true; + } + else if (cmdName == "Show Editor Button") + { + auto state = enableShowEditButton (); + enableShowEditButton (!state); + if (!editingEnabled) + showEditButton (!state); + return true; + } } else #endif @@ -1590,6 +1611,96 @@ void VST3Editor::syncParameterTags () #endif } +//------------------------------------------------------------------------ +void VST3Editor::saveScreenshot () +{ + if (auto fileSelector = + owned (CNewFileSelector::create (getFrame (), CNewFileSelector::kSelectDirectory))) + { + fileSelector->setTitle ("Select Directory where to save the screenshots"); + fileSelector->run ([this] (CNewFileSelector* fs) { + if (fs->getNumSelectedFiles () != 1) + return; + + auto makeScreenshot = [] (CFrame* frame) -> SharedPointer { + auto size = frame->getViewSize ().getSize (); + if (auto offscreen = COffscreenContext::create (size, 1.)) + { + offscreen->beginDraw (); + frame->draw (offscreen); + offscreen->endDraw (); + return shared (offscreen->getBitmap ()); + } + return nullptr; + }; + + showEditButton (false); + + auto origZoom = getFrame ()->getZoom (); + getFrame ()->setZoom (1.); + auto bitmap1 = makeScreenshot (getFrame ()); + getFrame ()->setZoom (2.); + auto bitmap2 = makeScreenshot (getFrame ()); + getFrame ()->setZoom (origZoom); + + auto folderPath = std::string (fs->getSelectedFile (0)); + auto uidStr = std::string ("XXXXXXXX"); + if (bitmap1) + { + auto data = getPlatformFactory ().createBitmapMemoryPNGRepresentation ( + bitmap1->getPlatformBitmap ()); + if (!data.empty ()) + { + auto filename = folderPath + "/" + uidStr + "_snapshot.png"; + CFileStream stream; + if (stream.open (filename.data (), CFileStream::kWriteMode | + CFileStream::kTruncateMode | + CFileStream::kBinaryMode)) + { + stream.writeRaw (data.data (), static_cast (data.size ())); + } + } + } + if (bitmap2) + { + auto filename = folderPath + "/" + uidStr + "_snapshot_2.0x.png"; + auto data = getPlatformFactory ().createBitmapMemoryPNGRepresentation ( + bitmap2->getPlatformBitmap ()); + if (!data.empty ()) + { + CFileStream stream; + if (stream.open (filename.data (), CFileStream::kWriteMode | + CFileStream::kTruncateMode | + CFileStream::kBinaryMode)) + { + stream.writeRaw (data.data (), static_cast (data.size ())); + } + } + } + if (enableShowEditButton ()) + showEditButton (true); + }); + } +} + +//------------------------------------------------------------------------ +bool VST3Editor::enableShowEditButton () const +{ + bool addShowEditorButton = true; + if (auto attributes = description->getCustomAttributes ("VST3Editor", true)) + { + attributes->getBooleanAttribute ("Show Editor Button", addShowEditorButton); + } + return addShowEditorButton; +} + +//------------------------------------------------------------------------ +void VST3Editor::enableShowEditButton (bool state) +{ + if (auto attributes = description->getCustomAttributes ("VST3Editor", true)) + attributes->setBooleanAttribute ("Show Editor Button", state); +} + #if VSTGUI_LIVE_EDITING //------------------------------------------------------------------------ class EnterEditModeController @@ -1615,6 +1726,22 @@ class EnterEditModeController button->registerControlListener (this); frame->addView (button); } + ~EnterEditModeController () noexcept override + { + if (button) + { + unregisterButtonListeners (); + if (auto parent = button->getParentView ()) + parent->asViewContainer ()->removeView (button); + } + } + + void unregisterButtonListeners () + { + button->unregisterViewEventListener (this); + button->unregisterViewListener (this); + button->unregisterControlListener (this); + } void valueChanged (CControl* c) override { @@ -1632,10 +1759,10 @@ class EnterEditModeController void viewWillDelete (CView* view) override { - vstgui_assert (view == button); - button->unregisterViewEventListener (this); - button->unregisterViewListener (this); - button->unregisterControlListener (this); + if (button == nullptr) + return; + unregisterButtonListeners (); + button = nullptr; delete this; } void viewOnEvent (CView* view, Event& event) override @@ -1681,6 +1808,25 @@ class EnterEditModeController #endif +//------------------------------------------------------------------------ +void VST3Editor::showEditButton (bool state) +{ +#if VSTGUI_LIVE_EDITING + if ((state && openUIEditorController) || (!state && openUIEditorController == nullptr)) + return; + if (state) + { + openUIEditorController = + new EnterEditModeController (getFrame (), [this] () { enableEditing (true); }); + } + else + { + delete openUIEditorController; + openUIEditorController = nullptr; + } +#endif +} + //------------------------------------------------------------------------ bool VST3Editor::enableEditing (bool state) { @@ -1689,6 +1835,7 @@ bool VST3Editor::enableEditing (bool state) getFrame ()->removeAll (); #if VSTGUI_LIVE_EDITING + openUIEditorController = nullptr; if (state) { // update uiDesc file path to absolute if possible @@ -1847,7 +1994,8 @@ bool VST3Editor::enableEditing (bool state) } } #if VSTGUI_LIVE_EDITING - new EnterEditModeController (getFrame (), [this] () { enableEditing (true); }); + if (enableShowEditButton ()) + showEditButton (true); #endif return true; } diff --git a/vstgui/plugin-bindings/vst3editor.h b/vstgui/plugin-bindings/vst3editor.h index 11cc098b7..b653a8aad 100644 --- a/vstgui/plugin-bindings/vst3editor.h +++ b/vstgui/plugin-bindings/vst3editor.h @@ -148,6 +148,10 @@ class VST3Editor : public Steinberg::Vst::VSTGUIEditor, void syncParameterTags (); void save (bool saveAs = false); bool enableEditing (bool state); + void saveScreenshot (); + bool enableShowEditButton () const; + void enableShowEditButton (bool state); + void showEditButton (bool state); bool PLUGIN_API open (void* parent, const PlatformType& type) override; void PLUGIN_API close () override; @@ -197,6 +201,7 @@ class VST3Editor : public Steinberg::Vst::VSTGUIEditor, UIDescription* description {nullptr}; IVST3EditorDelegate* delegate {nullptr}; IController* originalController {nullptr}; + IControlListener* openUIEditorController {nullptr}; using ParameterChangeListenerMap = std::map; ParameterChangeListenerMap paramChangeListeners; std::string viewName; From 3c2f6233f14004060078029a55cf20ff84202f55 Mon Sep 17 00:00:00 2001 From: scheffle Date: Thu, 2 Jun 2022 08:24:36 +0200 Subject: [PATCH 02/51] fix reading json data from resource stream --- vstgui/uidescription/detail/uijsonpersistence.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/vstgui/uidescription/detail/uijsonpersistence.cpp b/vstgui/uidescription/detail/uijsonpersistence.cpp index 859ff9837..01503535e 100644 --- a/vstgui/uidescription/detail/uijsonpersistence.cpp +++ b/vstgui/uidescription/detail/uijsonpersistence.cpp @@ -54,8 +54,10 @@ struct ContentProviderWrapper ContentProviderWrapper (IContentProvider& s) : stream (s) { - bufferLeft = bufferSize = - stream.readRawData (reinterpret_cast (buffer.data ()), static_cast (buffer.size ())); + bufferLeft = bufferSize = stream.readRawData (reinterpret_cast (buffer.data ()), + static_cast (buffer.size ())); + if (bufferLeft == kStreamIOError) + bufferSize = bufferLeft = 0; if (bufferSize == 0) { current = 0; @@ -72,8 +74,10 @@ struct ContentProviderWrapper ++pos; if (bufferLeft == 1) { - bufferLeft = bufferSize = - stream.readRawData (reinterpret_cast (buffer.data ()), static_cast (buffer.size ())); + bufferLeft = bufferSize = stream.readRawData ( + reinterpret_cast (buffer.data ()), static_cast (buffer.size ())); + if (bufferLeft == kStreamIOError) + bufferSize = bufferLeft = 0; if (bufferSize == 0) { current = 0; From ba1d080bf134570e257f98e99b4b265c9a28bda4 Mon Sep 17 00:00:00 2001 From: scheffle Date: Thu, 2 Jun 2022 08:29:14 +0200 Subject: [PATCH 03/51] fix reading json data from resource stream --- vstgui/uidescription/detail/uijsonpersistence.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vstgui/uidescription/detail/uijsonpersistence.cpp b/vstgui/uidescription/detail/uijsonpersistence.cpp index 01503535e..4a8b06cb2 100644 --- a/vstgui/uidescription/detail/uijsonpersistence.cpp +++ b/vstgui/uidescription/detail/uijsonpersistence.cpp @@ -55,7 +55,7 @@ struct ContentProviderWrapper ContentProviderWrapper (IContentProvider& s) : stream (s) { bufferLeft = bufferSize = stream.readRawData (reinterpret_cast (buffer.data ()), - static_cast (buffer.size ())); + static_cast (buffer.size ())); if (bufferLeft == kStreamIOError) bufferSize = bufferLeft = 0; if (bufferSize == 0) @@ -75,7 +75,7 @@ struct ContentProviderWrapper if (bufferLeft == 1) { bufferLeft = bufferSize = stream.readRawData ( - reinterpret_cast (buffer.data ()), static_cast (buffer.size ())); + reinterpret_cast (buffer.data ()), static_cast (buffer.size ())); if (bufferLeft == kStreamIOError) bufferSize = bufferLeft = 0; if (bufferSize == 0) From 550fe8e7c04b09bbcfcb67cb697a828d4b698bc5 Mon Sep 17 00:00:00 2001 From: scheffle Date: Thu, 2 Jun 2022 08:29:57 +0200 Subject: [PATCH 04/51] fix setting size constraints. Fixes #246 --- vstgui/plugin-bindings/vst3editor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vstgui/plugin-bindings/vst3editor.cpp b/vstgui/plugin-bindings/vst3editor.cpp index dec1aa48e..a681da573 100644 --- a/vstgui/plugin-bindings/vst3editor.cpp +++ b/vstgui/plugin-bindings/vst3editor.cpp @@ -542,13 +542,13 @@ bool VST3Editor::setEditorSizeConstrains (const CPoint& newMinimumSize, const CP CCoord height = currentSize.getHeight (); double scaleFactor = getAbsScaleFactor (); if (width > maxSize.x * scaleFactor) - currentSize.setWidth (maxSize.x * scaleFactor); + newSize.setWidth (maxSize.x * scaleFactor); else if (width < minSize.x * scaleFactor) - currentSize.setWidth (minSize.x * scaleFactor); + newSize.setWidth (minSize.x * scaleFactor); if (height > maxSize.y * scaleFactor) - currentSize.setHeight (maxSize.y * scaleFactor); + newSize.setHeight (maxSize.y * scaleFactor); else if (height < minSize.y * scaleFactor) - currentSize.setHeight (minSize.y * scaleFactor); + newSize.setHeight (minSize.y * scaleFactor); if (newSize != currentSize) requestResize (CPoint (newSize.getWidth (), newSize.getHeight ())); } From 63fb675bcd4ed7de982f1104045847a9c8115658 Mon Sep 17 00:00:00 2001 From: scheffle Date: Thu, 2 Jun 2022 08:36:12 +0200 Subject: [PATCH 05/51] correct the use of CMAKE_OSX_DEPLOYMENT_TARGET and update this value to 10.12 --- CMakeLists.txt | 5 ++--- README.md | 4 ++-- vstgui/CMakeLists.txt | 5 +---- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 518f62c09..d65a8710c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,11 +2,10 @@ cmake_minimum_required(VERSION 3.5) if(NOT PROJECT_NAME) + set(CMAKE_OSX_DEPLOYMENT_TARGET CACHE STRING 10.12) + project(vstgui) set(VSTGUI_MAIN_PROJECT_BUILD 1) - if(NOT CMAKE_OSX_DEPLOYMENT_TARGET) - set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9) - endif() if(CMAKE_CONFIGURATION_TYPES) set(CMAKE_CONFIGURATION_TYPES Debug Release ReleaseLTO) endif() diff --git a/README.md b/README.md index 014ec6b72..8b0e6c196 100644 --- a/README.md +++ b/README.md @@ -16,12 +16,12 @@ VSTGUI is a user interface toolkit mainly for audio plug-ins (VST, AAX, AudioUni Supported OS: - Microsoft Windows 10/11 -- Apple macOS 10.9-12 +- Apple macOS 10.12-12 - Apple iOS 9-15 - Linux (Preview) Supported IDE: -- Visual Studio 2015/2017/2019/2022 +- Visual Studio 2017/2019/2022 - minimum Xcode 10.1 - Qt Creator - Visual Studio Code diff --git a/vstgui/CMakeLists.txt b/vstgui/CMakeLists.txt index 96f598dca..1a0680266 100644 --- a/vstgui/CMakeLists.txt +++ b/vstgui/CMakeLists.txt @@ -2,14 +2,11 @@ cmake_minimum_required(VERSION 3.5) if(NOT PROJECT_NAME) + set(CMAKE_OSX_DEPLOYMENT_TARGET CACHE STRING 10.12) project(vstgui) set(VSTGUI_MAIN_PROJECT_BUILD 1) endif() -if(NOT CMAKE_OSX_DEPLOYMENT_TARGET) - set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9) -endif() - list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/modules/") include(vstgui_init) From c32531444cb81d702993debe7fdc967a83282445 Mon Sep 17 00:00:00 2001 From: Kai Wolf Date: Sat, 4 Jun 2022 21:54:09 +0200 Subject: [PATCH 06/51] Update macfactory.h createFileSelector() overrides a member function but is missing the override keyword which leads to a compiler error on macOS Monterey on ARM64 --- vstgui/lib/platform/mac/macfactory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vstgui/lib/platform/mac/macfactory.h b/vstgui/lib/platform/mac/macfactory.h index 50bd0ff4d..45300e41c 100644 --- a/vstgui/lib/platform/mac/macfactory.h +++ b/vstgui/lib/platform/mac/macfactory.h @@ -134,7 +134,7 @@ class MacFactory final : public IPlatformFactory * @return platform file selector or nullptr on failure */ PlatformFileSelectorPtr createFileSelector (PlatformFileSelectorStyle style, - IPlatformFrame* frame) const noexcept; + IPlatformFrame* frame) const noexcept override; const LinuxFactory* asLinuxFactory () const noexcept final; const MacFactory* asMacFactory () const noexcept final; From 590b7323b044decfc1c95faf8c9065b48c9fe3d4 Mon Sep 17 00:00:00 2001 From: Andreas Persson Date: Mon, 6 Jun 2022 10:54:16 +0200 Subject: [PATCH 07/51] fix close/reopen crash on linux. Fixes #249. cairo_device_finish must be called before closing the xcb connection, otherwise the invalid connection will not be removed from an internal cairo cache. When reopening the editor there's then a risk that the new connection has the same pointer value as the old one and that will cause a crash. The call to cairo_device_finish should not be made until the last instance of the editor has been closed. If it's done earlier, the remaining editors will stop working. --- vstgui/lib/platform/linux/x11frame.cpp | 1 + vstgui/lib/platform/linux/x11platform.cpp | 15 +++++++++++++++ vstgui/lib/platform/linux/x11platform.h | 2 ++ 3 files changed, 18 insertions(+) diff --git a/vstgui/lib/platform/linux/x11frame.cpp b/vstgui/lib/platform/linux/x11frame.cpp index 99393735c..b9c8284bb 100644 --- a/vstgui/lib/platform/linux/x11frame.cpp +++ b/vstgui/lib/platform/linux/x11frame.cpp @@ -177,6 +177,7 @@ struct DrawHandler ~DrawHandler () { + RunLoop::instance ().setDevice (device); cairo_device_destroy (device); } diff --git a/vstgui/lib/platform/linux/x11platform.cpp b/vstgui/lib/platform/linux/x11platform.cpp index 8f714505d..d429e4bea 100644 --- a/vstgui/lib/platform/linux/x11platform.cpp +++ b/vstgui/lib/platform/linux/x11platform.cpp @@ -122,6 +122,7 @@ struct RunLoop::Impl : IEventHandler std::array cursors {{XCB_CURSOR_NONE}}; KeyboardEvent lastUnprocessedKeyEvent; uint32_t lastUtf32KeyEventChar {0}; + cairo_device_t* device {nullptr}; void init (const SharedPointer& inRunLoop) { @@ -166,6 +167,11 @@ struct RunLoop::Impl : IEventHandler { if (--useCount != 0) return; + + cairo_device_finish (device); + cairo_device_destroy (device); + device = nullptr; + if (xcbConnection) { if (xkbUnprocessedState) @@ -550,6 +556,15 @@ Optional RunLoop::convertCurrentKeyEventToText () const return {}; } +void RunLoop::setDevice (cairo_device_t* device) +{ + if (impl->device != device) + { + cairo_device_destroy (impl->device); + impl->device = cairo_device_reference (device); + } +} + //------------------------------------------------------------------------ } // X11 } // VSTGUI diff --git a/vstgui/lib/platform/linux/x11platform.h b/vstgui/lib/platform/linux/x11platform.h index 690f69fc7..feace90ad 100644 --- a/vstgui/lib/platform/linux/x11platform.h +++ b/vstgui/lib/platform/linux/x11platform.h @@ -8,6 +8,7 @@ #include "x11frame.h" #include #include +#include struct xcb_connection_t; // forward declaration struct xcb_key_press_event_t; // forward declaration @@ -62,6 +63,7 @@ struct RunLoop KeyboardEvent&& getCurrentKeyEvent () const; Optional convertCurrentKeyEventToText () const; + void setDevice (cairo_device_t* device); static RunLoop& instance (); private: From 7dd14f417306aceef6de2063b82e48f9171ca5ec Mon Sep 17 00:00:00 2001 From: scheffle Date: Mon, 6 Jun 2022 22:17:32 +0200 Subject: [PATCH 08/51] fix: implicit conversion loses integer precision --- vstgui/lib/platform/mac/cocoa/nsviewframe.mm | 6 +++--- vstgui/lib/platform/mac/macclipboard.mm | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/vstgui/lib/platform/mac/cocoa/nsviewframe.mm b/vstgui/lib/platform/mac/cocoa/nsviewframe.mm index 079d93d98..aeccac660 100644 --- a/vstgui/lib/platform/mac/cocoa/nsviewframe.mm +++ b/vstgui/lib/platform/mac/cocoa/nsviewframe.mm @@ -1152,7 +1152,7 @@ static MouseEventButtonState buttonStateFromNSEvent (NSEvent* theEvent) event.timestamp = static_cast (theEvent.timestamp * 1000.); event.buttonState = buttonStateFromNSEvent (theEvent); event.modifiers = modifiersFromModifierFlags (theEvent.modifierFlags); - event.clickCount = theEvent.clickCount; + event.clickCount = static_cast (theEvent.clickCount); NSPoint nsPoint = [theEvent locationInWindow]; nsPoint = [nsView convertPoint:nsPoint fromView:nil]; event.mousePosition = pointFromNSPoint (nsPoint); @@ -1167,7 +1167,7 @@ static MouseEventButtonState buttonStateFromNSEvent (NSEvent* theEvent) event.timestamp = static_cast (theEvent.timestamp * 1000.); event.buttonState = buttonStateFromNSEvent (theEvent); event.modifiers = modifiersFromModifierFlags (theEvent.modifierFlags); - event.clickCount = theEvent.clickCount; + event.clickCount = static_cast (theEvent.clickCount); NSPoint nsPoint = [theEvent locationInWindow]; nsPoint = [nsView convertPoint:nsPoint fromView:nil]; event.mousePosition = pointFromNSPoint (nsPoint); @@ -1182,7 +1182,7 @@ static MouseEventButtonState buttonStateFromNSEvent (NSEvent* theEvent) event.timestamp = static_cast (theEvent.timestamp * 1000.); event.buttonState = buttonStateFromNSEvent (theEvent); event.modifiers = modifiersFromModifierFlags (theEvent.modifierFlags); - event.clickCount = theEvent.clickCount; + event.clickCount = static_cast (theEvent.clickCount); NSPoint nsPoint = [theEvent locationInWindow]; nsPoint = [nsView convertPoint:nsPoint fromView:nil]; event.mousePosition = pointFromNSPoint (nsPoint); diff --git a/vstgui/lib/platform/mac/macclipboard.mm b/vstgui/lib/platform/mac/macclipboard.mm index 008c3ea34..b7c29063b 100644 --- a/vstgui/lib/platform/mac/macclipboard.mm +++ b/vstgui/lib/platform/mac/macclipboard.mm @@ -23,13 +23,13 @@ public: Pasteboard (NSPasteboard* pb) : pb (pb) { entries.resize ([pb pasteboardItems].count); } - uint32_t getCount () const override { return entries.size (); } + uint32_t getCount () const override { return static_cast (entries.size ()); } uint32_t getDataSize (uint32_t index) const override { if (index >= getCount ()) return 0; prepareEntryAtIndex (index); - return entries[index].data.size (); + return static_cast (entries[index].data.size ()); } Type getDataType (uint32_t index) const override { @@ -45,7 +45,7 @@ uint32_t getData (uint32_t index, const void*& buffer, Type& type) const overrid prepareEntryAtIndex (index); buffer = entries[index].data.data (); type = entries[index].type; - return entries[index].data.size (); + return static_cast (entries[index].data.size ()); } private: From 120121eb9c7c5f158b76a5a25ed4f1488ef67ee9 Mon Sep 17 00:00:00 2001 From: scheffle Date: Sun, 24 Apr 2022 16:25:44 +0200 Subject: [PATCH 09/51] add PUBLIC keyword to allow to link to other libraries --- .../standalone/cmake/modules/vstgui_add_executable.cmake | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/vstgui/standalone/cmake/modules/vstgui_add_executable.cmake b/vstgui/standalone/cmake/modules/vstgui_add_executable.cmake index 233a5ebdb..75a6a653c 100644 --- a/vstgui/standalone/cmake/modules/vstgui_add_executable.cmake +++ b/vstgui/standalone/cmake/modules/vstgui_add_executable.cmake @@ -41,10 +41,11 @@ function(vstgui_add_executable target sources) endif(CMAKE_HOST_APPLE) target_link_libraries(${target} - vstgui - vstgui_uidescription - vstgui_standalone - ${PLATFORM_LIBRARIES} + PUBLIC + vstgui + vstgui_uidescription + vstgui_standalone + ${PLATFORM_LIBRARIES} ) target_compile_definitions(${target} ${VSTGUI_COMPILE_DEFINITIONS}) From 44e7c0c9103bc06103b7cc3db5ecdec818a0b897 Mon Sep 17 00:00:00 2001 From: scheffle Date: Mon, 6 Jun 2022 22:37:24 +0200 Subject: [PATCH 10/51] fix memory leak --- vstgui/lib/platform/mac/cocoa/nsviewframe.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vstgui/lib/platform/mac/cocoa/nsviewframe.mm b/vstgui/lib/platform/mac/cocoa/nsviewframe.mm index aeccac660..6316515e0 100644 --- a/vstgui/lib/platform/mac/cocoa/nsviewframe.mm +++ b/vstgui/lib/platform/mac/cocoa/nsviewframe.mm @@ -1056,9 +1056,10 @@ static void draggedImageEndedAtOperation (id self, SEL _cmd, NSImage* image, NSP return; } } + auto color = CGColorCreateGenericRGB (isClipBoundingBox ? 0. : 1., 1., 0., 1.); auto layer = [[CALayer new] autorelease]; layer.name = @"DebugLayer"; - layer.backgroundColor = CGColorCreateGenericRGB (isClipBoundingBox ? 0. : 1., 1., 0., 1.); + layer.backgroundColor = color; layer.opacity = 0.f; layer.zPosition = isClipBoundingBox ? 10 : 11; layer.frame = nsRectFromCRect (r); @@ -1066,6 +1067,7 @@ static void draggedImageEndedAtOperation (id self, SEL _cmd, NSImage* image, NSP [delegate setLayer:layer]; [layer addAnimation:anim forKey:@"opacity"]; + CFRelease (color); } #endif } From 1112940389553523cf136c2120ffa4993fb7070e Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 8 Jun 2022 11:18:33 +0200 Subject: [PATCH 11/51] replace sprintf with snprintf --- vstgui/lib/controls/ccolorchooser.cpp | 6 +++--- vstgui/lib/controls/cfontchooser.cpp | 2 +- vstgui/lib/controls/cparamdisplay.cpp | 4 ++-- vstgui/lib/controls/ctextedit.cpp | 4 ++-- vstgui/lib/platform/linux/cairobitmap.cpp | 4 ++-- vstgui/lib/platform/mac/cgbitmap.cpp | 2 +- vstgui/lib/platform/mac/macclipboard.mm | 4 ++-- vstgui/lib/platform/win32/win32optionmenu.cpp | 12 ++++++++---- .../uidescription/editing/uieditmenucontroller.cpp | 2 +- vstgui/uidescription/uiviewcreator.cpp | 2 +- 10 files changed, 23 insertions(+), 19 deletions(-) diff --git a/vstgui/lib/controls/ccolorchooser.cpp b/vstgui/lib/controls/ccolorchooser.cpp index 2e2d4539e..34965881e 100644 --- a/vstgui/lib/controls/ccolorchooser.cpp +++ b/vstgui/lib/controls/ccolorchooser.cpp @@ -240,21 +240,21 @@ static void setupParamDisplay (CParamDisplay* display, const CColorChooserUISett //----------------------------------------------------------------------------- bool CColorChooser::convertNormalizedToString (float value, char string[256], CParamDisplay::ValueToStringUserData* userData) { - sprintf (string, "%.3f", value); + snprintf (string, 255, "%.3f", value); return true; } //----------------------------------------------------------------------------- bool CColorChooser::convertColorValueToString (float value, char string[256], CParamDisplay::ValueToStringUserData* userData) { - sprintf (string, "%d", (int32_t)(value*255.f)); + snprintf (string, 255, "%d", (int32_t)(value * 255.f)); return true; } //----------------------------------------------------------------------------- bool CColorChooser::convertAngleToString (float value, char string[256], CParamDisplay::ValueToStringUserData* userData) { - sprintf (string, "%d%s", (int32_t)(value*359.f), kDegreeSymbol); + snprintf (string, 255, "%d%s", (int32_t)(value * 359.f), kDegreeSymbol); return true; } diff --git a/vstgui/lib/controls/cfontchooser.cpp b/vstgui/lib/controls/cfontchooser.cpp index 6587c6822..988f7dba8 100644 --- a/vstgui/lib/controls/cfontchooser.cpp +++ b/vstgui/lib/controls/cfontchooser.cpp @@ -48,7 +48,7 @@ class FontPreviewView : public CView { while (glyphRect.right < getViewSize ().right && i < 126) { - sprintf (string, "%c", i++); + snprintf (string, 2, "%c", i++); text += string; glyphRect.setWidth (context->getStringWidth (text.c_str ())); } diff --git a/vstgui/lib/controls/cparamdisplay.cpp b/vstgui/lib/controls/cparamdisplay.cpp index 47058dc6e..dcfe28941 100644 --- a/vstgui/lib/controls/cparamdisplay.cpp +++ b/vstgui/lib/controls/cparamdisplay.cpp @@ -186,8 +186,8 @@ void CParamDisplay::draw (CDrawContext *pContext) { char tmp[255]; char precisionStr[10]; - sprintf (precisionStr, "%%.%hhuf", valuePrecision); - sprintf (tmp, precisionStr, value); + snprintf (precisionStr, 10, "%%.%hhuf", valuePrecision); + snprintf (tmp, 255, precisionStr, value); string = tmp; } diff --git a/vstgui/lib/controls/ctextedit.cpp b/vstgui/lib/controls/ctextedit.cpp index e884bd99d..082dae08e 100644 --- a/vstgui/lib/controls/ctextedit.cpp +++ b/vstgui/lib/controls/ctextedit.cpp @@ -121,8 +121,8 @@ void CTextEdit::setValue (float val) { char tmp[255]; char precisionStr[10]; - sprintf (precisionStr, "%%.%hhuf", valuePrecision); - sprintf (tmp, precisionStr, getValue ()); + snprintf (precisionStr, 10, "%%.%hhuf", valuePrecision); + snprintf (tmp, 255, precisionStr, getValue ()); string = tmp; } diff --git a/vstgui/lib/platform/linux/cairobitmap.cpp b/vstgui/lib/platform/linux/cairobitmap.cpp index 727ddca17..e350ad2cb 100644 --- a/vstgui/lib/platform/linux/cairobitmap.cpp +++ b/vstgui/lib/platform/linux/cairobitmap.cpp @@ -1,4 +1,4 @@ -// This file is part of VSTGUI. It is subject to the license terms +// 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 @@ -186,7 +186,7 @@ bool Bitmap::load (const CResourceDescription& desc) if (desc.type == CResourceDescription::kIntegerType) { char filename[PATH_MAX]; - sprintf (filename, "bmp%05d.png", (int32_t)desc.u.id); + snprintf (filename, PATH_MAX, "bmp%05d.png", (int32_t)desc.u.id); path += filename; } else diff --git a/vstgui/lib/platform/mac/cgbitmap.cpp b/vstgui/lib/platform/mac/cgbitmap.cpp index bb470f4d2..678e4b198 100644 --- a/vstgui/lib/platform/mac/cgbitmap.cpp +++ b/vstgui/lib/platform/mac/cgbitmap.cpp @@ -158,7 +158,7 @@ bool CGBitmap::load (const CResourceDescription& desc) // else it just uses the name char filename [PATH_MAX]; if (desc.type == CResourceDescription::kIntegerType) - sprintf (filename, "bmp%05d", (int32_t)desc.u.id); + snprintf (filename, PATH_MAX, "bmp%05d", (int32_t)desc.u.id); else std::strcpy (filename, desc.u.name); CFStringRef cfStr = CFStringCreateWithCString (nullptr, filename, kCFStringEncodingUTF8); diff --git a/vstgui/lib/platform/mac/macclipboard.mm b/vstgui/lib/platform/mac/macclipboard.mm index b7c29063b..0e97b565f 100644 --- a/vstgui/lib/platform/mac/macclipboard.mm +++ b/vstgui/lib/platform/mac/macclipboard.mm @@ -96,7 +96,7 @@ static Entry makeEntry (NSPasteboardItem* item) int32_t blue = static_cast ([nsColor blueComponent] * 255.); int32_t alpha = static_cast ([nsColor alphaComponent] * 255.); char str[10]; - sprintf (str, "#%02x%02x%02x%02x", red, green, blue, alpha); + snprintf (str, 10, "#%02x%02x%02x%02x", red, green, blue, alpha); result.data.resize (10); memcpy (result.data.data (), str, 10); } @@ -193,7 +193,7 @@ static Entry makeEntry (NSPasteboardItem* item) int32_t blue = static_cast ([nsColor blueComponent] * 255.); int32_t alpha = static_cast ([nsColor alphaComponent] * 255.); char str[10]; - sprintf (str, "#%02x%02x%02x%02x", red, green, blue, alpha); + snprintf (str, 10, "#%02x%02x%02x%02x", red, green, blue, alpha); strings.emplace_back (str); } } diff --git a/vstgui/lib/platform/win32/win32optionmenu.cpp b/vstgui/lib/platform/win32/win32optionmenu.cpp index fb5bf6de3..505848f40 100644 --- a/vstgui/lib/platform/win32/win32optionmenu.cpp +++ b/vstgui/lib/platform/win32/win32optionmenu.cpp @@ -141,22 +141,26 @@ HMENU Win32OptionMenu::createMenu (COptionMenu* _menu, int32_t& offsetIdx) char* titleWithPrefixNumbers = nullptr; if (_menu->getPrefixNumbers ()) { - titleWithPrefixNumbers = (char*)std::malloc (strlen (item->getTitle ()) + 50); + auto bufferSize = strlen (item->getTitle ()) + 50; + titleWithPrefixNumbers = (char*)std::malloc (bufferSize); switch (_menu->getPrefixNumbers ()) { case 2: { - sprintf (titleWithPrefixNumbers, "%1d %s", inc+1, item->getTitle ().data ()); + snprintf (titleWithPrefixNumbers, bufferSize, "%1d %s", inc + 1, + item->getTitle ().data ()); break; } case 3: { - sprintf (titleWithPrefixNumbers, "%02d %s", inc+1, item->getTitle ().data ()); + snprintf (titleWithPrefixNumbers, bufferSize, "%02d %s", inc + 1, + item->getTitle ().data ()); break; } case 4: { - sprintf (titleWithPrefixNumbers, "%03d %s", inc+1, item->getTitle ().data ()); + snprintf (titleWithPrefixNumbers, bufferSize, "%03d %s", inc + 1, + item->getTitle ().data ()); break; } } diff --git a/vstgui/uidescription/editing/uieditmenucontroller.cpp b/vstgui/uidescription/editing/uieditmenucontroller.cpp index a91317ae6..d8dbadc18 100644 --- a/vstgui/uidescription/editing/uieditmenucontroller.cpp +++ b/vstgui/uidescription/editing/uieditmenucontroller.cpp @@ -109,7 +109,7 @@ bool UIEditMenuController::createUniqueTemplateName (std::list Date: Wed, 8 Jun 2022 11:28:21 +0200 Subject: [PATCH 12/51] Update macfactory.h --- vstgui/lib/platform/mac/macfactory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vstgui/lib/platform/mac/macfactory.h b/vstgui/lib/platform/mac/macfactory.h index 45300e41c..3ed621fa2 100644 --- a/vstgui/lib/platform/mac/macfactory.h +++ b/vstgui/lib/platform/mac/macfactory.h @@ -134,7 +134,7 @@ class MacFactory final : public IPlatformFactory * @return platform file selector or nullptr on failure */ PlatformFileSelectorPtr createFileSelector (PlatformFileSelectorStyle style, - IPlatformFrame* frame) const noexcept override; + IPlatformFrame* frame) const noexcept final; const LinuxFactory* asLinuxFactory () const noexcept final; const MacFactory* asMacFactory () const noexcept final; From 5792f9dc10e0b28ec9949c9ee01365608d4bb4e0 Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 8 Jun 2022 11:53:05 +0200 Subject: [PATCH 13/51] add Modifiers (in)equality operators. #253 --- vstgui/lib/events.h | 4 ++++ vstgui/tests/unittest/lib/event_test.cpp | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/vstgui/lib/events.h b/vstgui/lib/events.h index d7b3dcd04..396372f1b 100644 --- a/vstgui/lib/events.h +++ b/vstgui/lib/events.h @@ -128,6 +128,10 @@ struct Modifiers data = cast (modifier); return *this; } + /** check if equal to other modifiers */ + bool operator== (const Modifiers& other) const { return data == other.data; } + /** check if different to other modifiers */ + bool operator!= (const Modifiers& other) const { return data != other.data; } private: static uint32_t cast (ModifierKey mod) { return static_cast (mod); } diff --git a/vstgui/tests/unittest/lib/event_test.cpp b/vstgui/tests/unittest/lib/event_test.cpp index 9785920bf..2b28d987d 100644 --- a/vstgui/tests/unittest/lib/event_test.cpp +++ b/vstgui/tests/unittest/lib/event_test.cpp @@ -200,5 +200,14 @@ TEST_CASE (EventTest, IgnoreFollowUpEvent) EXPECT_TRUE (e.ignoreFollowUpMoveAndUpEvents ()); EXPECT_TRUE (e.consumed); } + +TEST_CASE (EventTest, ModifiersEquality) +{ + Modifiers altMod (ModifierKey::Alt); + Modifiers ctrlMod (ModifierKey::Control); + EXPECT_FALSE ((altMod == ctrlMod)); + EXPECT_TRUE ((altMod != ctrlMod)); +} + //------------------------------------------------------------------------ } // VSTGUI From e96ce733c527eb58849ab25ea94f6cea04ac0cc0 Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 8 Jun 2022 12:04:08 +0200 Subject: [PATCH 14/51] add [[nodiscard]] to methods in events.h. #254 --- vstgui/lib/events.h | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/vstgui/lib/events.h b/vstgui/lib/events.h index 396372f1b..9e5cfd098 100644 --- a/vstgui/lib/events.h +++ b/vstgui/lib/events.h @@ -51,7 +51,7 @@ struct EventConsumeState else data &= ~Handled; } - operator bool () { return data & Handled; } + [[nodiscard]] operator bool () { return data & Handled; } void reset () { data = NotHandled; } @@ -98,13 +98,13 @@ struct Modifiers explicit Modifiers (ModifierKey modifier) : data (cast (modifier)) {} /** test if no modifier key is set */ - bool empty () const { return data == 0; } + [[nodiscard]] bool empty () const { return data == 0; } /** test if modifier key is set */ - bool has (ModifierKey modifier) const { return data & cast (modifier); } + [[nodiscard]] bool has (ModifierKey modifier) const { return data & cast (modifier); } /** test if modifier key is set exclusively */ - bool is (ModifierKey modifier) const { return data == cast (modifier); } + [[nodiscard]] bool is (ModifierKey modifier) const { return data == cast (modifier); } /** test if the modifier keys are set exclusively */ - bool is (const std::initializer_list& modifiers) const + [[nodiscard]] bool is (const std::initializer_list& modifiers) const { uint32_t d = 0; for (auto& mod : modifiers) @@ -112,9 +112,9 @@ struct Modifiers return data == d; } /** test if modifier key is set */ - bool operator| (ModifierKey modifier) const { return has (modifier); } + [[nodiscard]] bool operator| (ModifierKey modifier) const { return has (modifier); } /** test if modifier key is set exclusively */ - bool operator== (ModifierKey modifier) const { return is (modifier); } + [[nodiscard]] bool operator== (ModifierKey modifier) const { return is (modifier); } /** add a modifier key */ void add (ModifierKey modifier) { data |= cast (modifier); } @@ -123,15 +123,15 @@ struct Modifiers /** clear all modifiers */ void clear () { data = 0; } /** set to one modifier key */ - Modifiers& operator= (ModifierKey modifier) + [[nodiscard]] Modifiers& operator= (ModifierKey modifier) { data = cast (modifier); return *this; } /** check if equal to other modifiers */ - bool operator== (const Modifiers& other) const { return data == other.data; } + [[nodiscard]] bool operator== (const Modifiers& other) const { return data == other.data; } /** check if different to other modifiers */ - bool operator!= (const Modifiers& other) const { return data != other.data; } + [[nodiscard]] bool operator!= (const Modifiers& other) const { return data != other.data; } private: static uint32_t cast (ModifierKey mod) { return static_cast (mod); } @@ -177,16 +177,16 @@ enum class MouseButton : uint32_t */ struct MouseEventButtonState { - bool isLeft () const { return data == MouseButton::Left; } - bool isMiddle () const { return data == MouseButton::Middle; } - bool isRight () const { return data == MouseButton::Right; } - bool is (MouseButton pos) const { return data == pos; } - bool isOther (uint32_t index) const { return data == static_cast (1 << index); } - bool has (MouseButton pos) const + [[nodiscard]] bool isLeft () const { return data == MouseButton::Left; } + [[nodiscard]] bool isMiddle () const { return data == MouseButton::Middle; } + [[nodiscard]] bool isRight () const { return data == MouseButton::Right; } + [[nodiscard]] bool is (MouseButton pos) const { return data == pos; } + [[nodiscard]] bool isOther (uint32_t index) const { return data == static_cast (1 << index); } + [[nodiscard]] bool has (MouseButton pos) const { return static_cast (static_cast (data) & static_cast (pos)); } - bool empty () const { return data == MouseButton::None; } + [[nodiscard]] bool empty () const { return data == MouseButton::None; } void add (MouseButton pos) { @@ -200,8 +200,8 @@ struct MouseEventButtonState MouseEventButtonState (const MouseEventButtonState&) = default; MouseEventButtonState (MouseButton pos) { set (pos); } - bool operator== (const MouseEventButtonState& other) const { return data == other.data; } - bool operator!= (const MouseEventButtonState& other) const { return data != other.data; } + [[nodiscard]] bool operator== (const MouseEventButtonState& other) const { return data == other.data; } + [[nodiscard]] bool operator!= (const MouseEventButtonState& other) const { return data != other.data; } private: MouseButton data {MouseButton::None}; @@ -272,7 +272,7 @@ struct MouseDownUpMoveEvent : MouseEvent consumed.data &= ~IgnoreFollowUpEventsMask; } - bool ignoreFollowUpMoveAndUpEvents () + [[nodiscard]] bool ignoreFollowUpMoveAndUpEvents () { return consumed.data & IgnoreFollowUpEventsMask; } From b26513e257c8060418f0e29b424a2f5299e918d7 Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 8 Jun 2022 12:11:23 +0200 Subject: [PATCH 15/51] run clang-format on events.h --- vstgui/lib/events.h | 143 ++++++++++++++++++++++++++++---------------- 1 file changed, 90 insertions(+), 53 deletions(-) diff --git a/vstgui/lib/events.h b/vstgui/lib/events.h index 9e5cfd098..69ef4d39f 100644 --- a/vstgui/lib/events.h +++ b/vstgui/lib/events.h @@ -181,7 +181,10 @@ struct MouseEventButtonState [[nodiscard]] bool isMiddle () const { return data == MouseButton::Middle; } [[nodiscard]] bool isRight () const { return data == MouseButton::Right; } [[nodiscard]] bool is (MouseButton pos) const { return data == pos; } - [[nodiscard]] bool isOther (uint32_t index) const { return data == static_cast (1 << index); } + [[nodiscard]] bool isOther (uint32_t index) const + { + return data == static_cast (1 << index); + } [[nodiscard]] bool has (MouseButton pos) const { return static_cast (static_cast (data) & static_cast (pos)); @@ -200,8 +203,14 @@ struct MouseEventButtonState MouseEventButtonState (const MouseEventButtonState&) = default; MouseEventButtonState (MouseButton pos) { set (pos); } - [[nodiscard]] bool operator== (const MouseEventButtonState& other) const { return data == other.data; } - [[nodiscard]] bool operator!= (const MouseEventButtonState& other) const { return data != other.data; } + [[nodiscard]] bool operator== (const MouseEventButtonState& other) const + { + return data == other.data; + } + [[nodiscard]] bool operator!= (const MouseEventButtonState& other) const + { + return data != other.data; + } private: MouseButton data {MouseButton::None}; @@ -223,8 +232,7 @@ struct MouseEvent : MousePositionEvent struct MouseEnterEvent : MouseEvent { MouseEnterEvent () { type = EventType::MouseEnter; } - MouseEnterEvent (CPoint pos, MouseEventButtonState buttons, Modifiers mods) - : MouseEnterEvent () + MouseEnterEvent (CPoint pos, MouseEventButtonState buttons, Modifiers mods) : MouseEnterEvent () { mousePosition = pos; buttonState = buttons; @@ -243,8 +251,7 @@ struct MouseEnterEvent : MouseEvent struct MouseExitEvent : MouseEvent { MouseExitEvent () { type = EventType::MouseExit; } - MouseExitEvent (CPoint pos, MouseEventButtonState buttons, Modifiers mods) - : MouseExitEvent () + MouseExitEvent (CPoint pos, MouseEventButtonState buttons, Modifiers mods) : MouseExitEvent () { mousePosition = pos; buttonState = buttons; @@ -489,7 +496,7 @@ enum class ModifierKey : uint32_t /** the super key (Control key on macOS, Windows key on Windows and Super key on other platforms)*/ Super = 1 << 3, - + None = 0 }; @@ -513,21 +520,29 @@ struct KeyboardEvent : ModifierEvent /** event as mouse position event or nullpointer if not a mouse position event * @ingroup new_in_4_11 */ -template , typename std::add_const_t, OutputT>::type> +template, typename std::add_const_t, OutputT>::type> inline MousePositionEventT* asMousePositionEvent (EventT& event) { switch (event.type) { - case EventType::ZoomGesture: [[fallthrough]]; - case EventType::MouseWheel: [[fallthrough]]; - case EventType::MouseDown: [[fallthrough]]; - case EventType::MouseMove: [[fallthrough]]; - case EventType::MouseUp: [[fallthrough]]; - case EventType::MouseEnter: [[fallthrough]]; - case EventType::MouseExit: return static_cast (&event); - default: break; + case EventType::ZoomGesture: + [[fallthrough]]; + case EventType::MouseWheel: + [[fallthrough]]; + case EventType::MouseDown: + [[fallthrough]]; + case EventType::MouseMove: + [[fallthrough]]; + case EventType::MouseUp: + [[fallthrough]]; + case EventType::MouseEnter: + [[fallthrough]]; + case EventType::MouseExit: + return static_cast (&event); + default: + break; } return nullptr; } @@ -536,19 +551,25 @@ inline MousePositionEventT* asMousePositionEvent (EventT& event) /** event as mouse position event or nullpointer if not a mouse position event * @ingroup new_in_4_11 */ -template , typename std::add_const_t, OutputT>::type> +template, typename std::add_const_t, OutputT>::type> inline MouseEventT* asMouseEvent (EventT& event) { switch (event.type) { - case EventType::MouseDown: [[fallthrough]]; - case EventType::MouseMove: [[fallthrough]]; - case EventType::MouseUp: [[fallthrough]]; - case EventType::MouseEnter: [[fallthrough]]; - case EventType::MouseExit: return static_cast (&event); - default: break; + case EventType::MouseDown: + [[fallthrough]]; + case EventType::MouseMove: + [[fallthrough]]; + case EventType::MouseUp: + [[fallthrough]]; + case EventType::MouseEnter: + [[fallthrough]]; + case EventType::MouseExit: + return static_cast (&event); + default: + break; } return nullptr; } @@ -557,17 +578,21 @@ inline MouseEventT* asMouseEvent (EventT& event) /** event as mouse down event or nullpointer if not a mouse down event * @ingroup new_in_4_11 */ -template , typename std::add_const_t, OutputT>::type> +template, typename std::add_const_t, OutputT>::type> inline MouseDownEventT* asMouseDownEvent (EventT& event) { switch (event.type) { - case EventType::MouseDown: [[fallthrough]]; - case EventType::MouseMove: [[fallthrough]]; - case EventType::MouseUp: return static_cast (&event); - default: break; + case EventType::MouseDown: + [[fallthrough]]; + case EventType::MouseMove: + [[fallthrough]]; + case EventType::MouseUp: + return static_cast (&event); + default: + break; } return nullptr; } @@ -576,22 +601,31 @@ inline MouseDownEventT* asMouseDownEvent (EventT& event) /** event as modifier event or nullpointer if not a modifier event * @ingroup new_in_4_11 */ -template , typename std::add_const_t, OutputT>::type> +template, typename std::add_const_t, OutputT>::type> inline ModifierEventT* asModifierEvent (EventT& event) { switch (event.type) { - case EventType::KeyDown: [[fallthrough]]; - case EventType::KeyUp: [[fallthrough]]; - case EventType::MouseEnter: [[fallthrough]]; - case EventType::MouseExit: [[fallthrough]]; - case EventType::MouseWheel: [[fallthrough]]; - case EventType::MouseDown: [[fallthrough]]; - case EventType::MouseMove: [[fallthrough]]; - case EventType::MouseUp: return static_cast (&event); - default: break; + case EventType::KeyDown: + [[fallthrough]]; + case EventType::KeyUp: + [[fallthrough]]; + case EventType::MouseEnter: + [[fallthrough]]; + case EventType::MouseExit: + [[fallthrough]]; + case EventType::MouseWheel: + [[fallthrough]]; + case EventType::MouseDown: + [[fallthrough]]; + case EventType::MouseMove: + [[fallthrough]]; + case EventType::MouseUp: + return static_cast (&event); + default: + break; } return nullptr; } @@ -600,16 +634,19 @@ inline ModifierEventT* asModifierEvent (EventT& event) /** event as keyboard event or nullpointer if not a keyboard event * @ingroup new_in_4_11 */ -template , typename std::add_const_t, OutputT>::type> +template, typename std::add_const_t, OutputT>::type> inline KeyboardEventT* asKeyboardEvent (EventT& event) { switch (event.type) { - case EventType::KeyDown: [[fallthrough]]; - case EventType::KeyUp: return static_cast (&event); - default: break; + case EventType::KeyDown: + [[fallthrough]]; + case EventType::KeyUp: + return static_cast (&event); + default: + break; } return nullptr; } From 2fdcdefdbb9a6c7798b866b4f92f02a75448fb81 Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 8 Jun 2022 12:12:31 +0200 Subject: [PATCH 16/51] remove unused member and mark class as deprecated. fix #252 --- vstgui/plugin-bindings/plugguieditor.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/vstgui/plugin-bindings/plugguieditor.h b/vstgui/plugin-bindings/plugguieditor.h index b9d4bf25f..66d5a113b 100644 --- a/vstgui/plugin-bindings/plugguieditor.h +++ b/vstgui/plugin-bindings/plugguieditor.h @@ -21,7 +21,8 @@ struct ERect //----------------------------------------------------------------------------- // AEffGUIEditor Declaration //----------------------------------------------------------------------------- -class PluginGUIEditor : public VSTGUIEditorInterface +class [[deprecated ("Please use your own VSTGUIEditorInterface subclass")]] PluginGUIEditor +: public VSTGUIEditorInterface { public : @@ -58,8 +59,6 @@ public : void* systemWindow; private: - uint32_t lLastTicks; - static int32_t knobMode; }; From cc231d5d5a541a728b23ae87b1f770f9281db66c Mon Sep 17 00:00:00 2001 From: Andreas Persson Date: Wed, 8 Jun 2022 19:46:44 +0200 Subject: [PATCH 17/51] simplify the cairo device cleanup a bit --- vstgui/lib/platform/linux/x11frame.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/vstgui/lib/platform/linux/x11frame.cpp b/vstgui/lib/platform/linux/x11frame.cpp index b9c8284bb..9975194d0 100644 --- a/vstgui/lib/platform/linux/x11frame.cpp +++ b/vstgui/lib/platform/linux/x11frame.cpp @@ -172,13 +172,7 @@ struct DrawHandler window.getSize ().x, window.getSize ().y); windowSurface.assign (s); onSizeChanged (window.getSize ()); - device = cairo_device_reference (cairo_surface_get_device (s)); - } - - ~DrawHandler () - { - RunLoop::instance ().setDevice (device); - cairo_device_destroy (device); + RunLoop::instance ().setDevice (cairo_surface_get_device (s)); } void onSizeChanged (const CPoint& size) @@ -213,7 +207,6 @@ struct DrawHandler } private: - cairo_device_t* device = nullptr; Cairo::SurfaceHandle windowSurface; Cairo::SurfaceHandle backBuffer; SharedPointer drawContext; From c7927f760e00e609bee05b96ee8dbaca97a51ec4 Mon Sep 17 00:00:00 2001 From: scheffle Date: Sun, 12 Jun 2022 10:20:00 +0200 Subject: [PATCH 18/51] fix regression of #146. Fixes #256 --- vstgui/lib/platform/mac/cocoa/nsviewframe.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vstgui/lib/platform/mac/cocoa/nsviewframe.mm b/vstgui/lib/platform/mac/cocoa/nsviewframe.mm index 6316515e0..5b927842f 100644 --- a/vstgui/lib/platform/mac/cocoa/nsviewframe.mm +++ b/vstgui/lib/platform/mac/cocoa/nsviewframe.mm @@ -1125,7 +1125,7 @@ static MouseEventButtonState buttonStateFromNSEvent (NSEvent* theEvent) { case 0: { - if (theEvent.modifierFlags & MacEventModifier::ControlKeyMask) + if (theEvent.type == MacEventType::LeftMouseDown && theEvent.modifierFlags & MacEventModifier::ControlKeyMask) state.add (MouseButton::Right); else state.add (MouseButton::Left); From 14d6fc5b74f709f0531191e8d6f77b0e42de2541 Mon Sep 17 00:00:00 2001 From: scheffle Date: Sun, 1 May 2022 12:25:35 +0200 Subject: [PATCH 19/51] fix method name typo --- vstgui/lib/cframe.cpp | 4 ++-- vstgui/lib/cframe.h | 15 +++++++++++++-- vstgui/lib/clayeredviewcontainer.cpp | 4 ++-- vstgui/lib/cshadowviewcontainer.cpp | 4 ++-- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/vstgui/lib/cframe.cpp b/vstgui/lib/cframe.cpp index 0061fb990..e874cb9a4 100644 --- a/vstgui/lib/cframe.cpp +++ b/vstgui/lib/cframe.cpp @@ -1554,13 +1554,13 @@ void CFrame::dispatchKeyboardEventToHooks (KeyboardEvent& event) } //----------------------------------------------------------------------------- -void CFrame::registerScaleFactorChangedListeneer (IScaleFactorChangedListener* listener) +void CFrame::registerScaleFactorChangedListener (IScaleFactorChangedListener* listener) { pImpl->scaleFactorChangedListenerList.add (listener); } //----------------------------------------------------------------------------- -void CFrame::unregisterScaleFactorChangedListeneer (IScaleFactorChangedListener* listener) +void CFrame::unregisterScaleFactorChangedListener (IScaleFactorChangedListener* listener) { pImpl->scaleFactorChangedListenerList.remove (listener); } diff --git a/vstgui/lib/cframe.h b/vstgui/lib/cframe.h index 3869352a4..f5804721a 100644 --- a/vstgui/lib/cframe.h +++ b/vstgui/lib/cframe.h @@ -143,8 +143,19 @@ class CFrame final : public CViewContainer, public IPlatformFrameCallback /** unregister a mouse observer */ void unregisterMouseObserver (IMouseObserver* observer); - void registerScaleFactorChangedListeneer (IScaleFactorChangedListener* listener); - void unregisterScaleFactorChangedListeneer (IScaleFactorChangedListener* listener); + VSTGUI_DEPRECATED_MSG ( + void registerScaleFactorChangedListeneer (IScaleFactorChangedListener* listener) { + registerScaleFactorChangedListener (listener); + }, + "use registerScaleFactorChangedListener") + VSTGUI_DEPRECATED_MSG ( + void unregisterScaleFactorChangedListeneer (IScaleFactorChangedListener* listener) { + unregisterScaleFactorChangedListener (listener); + }, + "use unregisterScaleFactorChangedListener") + + void registerScaleFactorChangedListener (IScaleFactorChangedListener* listener); + void unregisterScaleFactorChangedListener (IScaleFactorChangedListener* listener); void registerFocusViewObserver (IFocusViewObserver* observer); void unregisterFocusViewObserver (IFocusViewObserver* observer); diff --git a/vstgui/lib/clayeredviewcontainer.cpp b/vstgui/lib/clayeredviewcontainer.cpp index 628d7ff92..cf4f43267 100644 --- a/vstgui/lib/clayeredviewcontainer.cpp +++ b/vstgui/lib/clayeredviewcontainer.cpp @@ -69,7 +69,7 @@ bool CLayeredViewContainer::removed (CView* parent) { layer = nullptr; parentLayerView = nullptr; - getFrame ()->unregisterScaleFactorChangedListeneer (this); + getFrame ()->unregisterScaleFactorChangedListener (this); } return CViewContainer::removed (parent); } @@ -99,7 +99,7 @@ bool CLayeredViewContainer::attached (CView* parent) layer->setZIndex (zIndex); layer->setAlpha (getAlphaValue ()); updateLayerSize (); - frame->registerScaleFactorChangedListeneer (this); + frame->registerScaleFactorChangedListener (this); } } parent = getParentView (); diff --git a/vstgui/lib/cshadowviewcontainer.cpp b/vstgui/lib/cshadowviewcontainer.cpp index 45d8747d9..a8c9adbbf 100644 --- a/vstgui/lib/cshadowviewcontainer.cpp +++ b/vstgui/lib/cshadowviewcontainer.cpp @@ -47,7 +47,7 @@ void CShadowViewContainer::beforeDelete () //----------------------------------------------------------------------------- bool CShadowViewContainer::removed (CView* parent) { - getFrame ()->unregisterScaleFactorChangedListeneer (this); + getFrame ()->unregisterScaleFactorChangedListener (this); setBackground (nullptr); return CViewContainer::removed (parent); } @@ -58,7 +58,7 @@ bool CShadowViewContainer::attached (CView* parent) if (CViewContainer::attached (parent)) { invalidateShadow (); - getFrame ()->registerScaleFactorChangedListeneer (this); + getFrame ()->registerScaleFactorChangedListener (this); return true; } return false; From 5b5374b077ffde3d5f454e4fba99d14a7d33527b Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 20 Apr 2022 13:08:24 +0200 Subject: [PATCH 20/51] support ARC with the classbuilder --- .../lib/platform/mac/cocoa/objcclassbuilder.h | 55 ++++++++++++------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h b/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h index f2b540d73..b01fd6a1f 100644 --- a/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h +++ b/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h @@ -4,11 +4,13 @@ #pragma once -#import -#import -#import -#import -#import +#include +#include +#include +#include +#include +#include +#include //------------------------------------------------------------------------------------ namespace VSTGUI { @@ -17,26 +19,36 @@ namespace VSTGUI { template struct ObjCVariable { - ObjCVariable (id obj, Ivar ivar) : obj (obj), ivar (ivar) {} + ObjCVariable (__unsafe_unretained id obj, Ivar ivar) : obj (obj), ivar (ivar) {} + ObjCVariable (ObjCVariable&& o) { *this = std::move (o); } - T get () const { return static_cast (object_getIvar (obj, ivar)); } + ObjCVariable& operator= (ObjCVariable&& o) + { + obj = o.obj; + ivar = o.ivar; + o.obj = nullptr; + o.ivar = nullptr; + return *this; + } + + T get () const { return (__bridge T) (object_getIvar (obj, ivar)); } - void set (const T& value) { object_setIvar (obj, ivar, static_cast (value)); } + void set (const T& value) { object_setIvar (obj, ivar, (__bridge id) (value)); } private: - id obj; + __unsafe_unretained id obj; Ivar ivar {nullptr}; }; //------------------------------------------------------------------------------------ struct ObjCInstance { - ObjCInstance (id obj) : obj (obj) {} + ObjCInstance (__unsafe_unretained id obj) : obj (obj) {} template std::optional> getVariable (const char* name) const { - if (auto ivar = class_getInstanceVariable ([obj class], name)) + if (__strong auto ivar = class_getInstanceVariable (object_getClass (obj), name)) { return {ObjCVariable (obj, ivar)}; } @@ -46,14 +58,17 @@ struct ObjCInstance template void callSuper (SEL selector, T... args) const { - void (*f) (id, SEL, T...) = (void (*) (id, SEL, T...))objc_msgSendSuper; + void (*f) (__unsafe_unretained id, SEL, T...) = + (void (*) (__unsafe_unretained id, SEL, T...))objc_msgSendSuper; f (getSuper (), selector, args...); } template R callSuper (SEL selector, T... args) const { - R (*f) (id, SEL, T...) = (R (*) (id, SEL, T...))objc_msgSendSuper; + R (*f) + (__unsafe_unretained id, SEL, T...) = + (R (*) (__unsafe_unretained id, SEL, T...))objc_msgSendSuper; return f (getSuper (), selector, args...); } @@ -63,12 +78,12 @@ struct ObjCInstance if (os.receiver == nullptr) { os.receiver = obj; - os.super_class = class_getSuperclass ([obj class]); + os.super_class = class_getSuperclass (object_getClass (obj)); } - return static_cast (&os); + return (__bridge id) (&os); } - id obj; + __unsafe_unretained id obj; mutable objc_super os {}; }; @@ -171,7 +186,7 @@ template inline ObjCClassBuilder& ObjCClassBuilder::addMethod (SEL selector, Func imp, const char* types) { auto res = class_addMethod (cl, selector, IMP (imp), types); - vstgui_assert (res == true); + assert (res == true); return *this; } @@ -186,7 +201,7 @@ ObjCClassBuilder& ObjCClassBuilder::addMethod (SEL selector, Func imp) template inline ObjCClassBuilder& ObjCClassBuilder::addIvar (const char* name) { - return addIvar (name, sizeof (T), static_cast (log2 (sizeof (T))), @encode (T)); + return addIvar (name, sizeof (T), static_cast (std::log2 (sizeof (T))), @encode (T)); } //----------------------------------------------------------------------------- @@ -194,7 +209,7 @@ inline ObjCClassBuilder& ObjCClassBuilder::addIvar (const char* name, size_t siz uint8_t alignment, const char* types) { auto res = class_addIvar (cl, name, size, alignment, types); - vstgui_assert (res == true); + assert (res == true); return *this; } @@ -210,7 +225,7 @@ inline ObjCClassBuilder& ObjCClassBuilder::addProtocol (const char* name) inline ObjCClassBuilder& ObjCClassBuilder::addProtocol (Protocol* proto) { auto res = class_addProtocol (cl, proto); - vstgui_assert (res == true); + assert (res == true); return *this; } From ddcd81bd210dd5dced3d381f8bc72706ed38945e Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 15 Jun 2022 17:58:04 +0200 Subject: [PATCH 21/51] fix warning in release builds --- vstgui/lib/platform/mac/cocoa/objcclassbuilder.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h b/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h index b01fd6a1f..ae5bc24fd 100644 --- a/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h +++ b/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h @@ -187,6 +187,7 @@ inline ObjCClassBuilder& ObjCClassBuilder::addMethod (SEL selector, Func imp, co { auto res = class_addMethod (cl, selector, IMP (imp), types); assert (res == true); + (void)res; return *this; } @@ -210,6 +211,7 @@ inline ObjCClassBuilder& ObjCClassBuilder::addIvar (const char* name, size_t siz { auto res = class_addIvar (cl, name, size, alignment, types); assert (res == true); + (void)res; return *this; } @@ -226,6 +228,7 @@ inline ObjCClassBuilder& ObjCClassBuilder::addProtocol (Protocol* proto) { auto res = class_addProtocol (cl, proto); assert (res == true); + (void)res; return *this; } From e3eb412f28621c5bae302108f4a2d5f4de5c9e6f Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 15 Jun 2022 22:01:08 +0200 Subject: [PATCH 22/51] fix typo --- vstgui/lib/copenglview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vstgui/lib/copenglview.cpp b/vstgui/lib/copenglview.cpp index aa1199916..ca796d40a 100644 --- a/vstgui/lib/copenglview.cpp +++ b/vstgui/lib/copenglview.cpp @@ -56,7 +56,7 @@ bool COpenGLView::createPlatformOpenGLView () updatePlatformOpenGLViewSize (); platformOpenGLViewCreated (); platformOpenGLViewSizeChanged (); - getFrame ()->registerScaleFactorChangedListeneer (this); + getFrame ()->registerScaleFactorChangedListener (this); return true; } platformOpenGLView = nullptr; @@ -69,7 +69,7 @@ bool COpenGLView::destroyPlatformOpenGLView () { if (platformOpenGLView) { - getFrame ()->unregisterScaleFactorChangedListeneer (this); + getFrame ()->unregisterScaleFactorChangedListener (this); platformOpenGLViewWillDestroy (); platformOpenGLView->remove (); platformOpenGLView = nullptr; From eb22dde24c89c70b611d7f5e4dcf625089a51002 Mon Sep 17 00:00:00 2001 From: Yvan Grabit Date: Fri, 17 Jun 2022 09:13:05 +0200 Subject: [PATCH 23/51] [fix] compilation for app on ARM64EC https://developercommunity.visualstudio.com/t/LINK-:-error-LNK2001:-unresolved-externa/1699333#T-ND10073508 --- .../cmake/modules/vstgui_add_executable.cmake | 2 ++ .../source/platform/win32/win32application.cpp | 16 ---------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/vstgui/standalone/cmake/modules/vstgui_add_executable.cmake b/vstgui/standalone/cmake/modules/vstgui_add_executable.cmake index 75a6a653c..cb4734b48 100644 --- a/vstgui/standalone/cmake/modules/vstgui_add_executable.cmake +++ b/vstgui/standalone/cmake/modules/vstgui_add_executable.cmake @@ -13,6 +13,8 @@ function(vstgui_add_executable target sources) add_executable(${target} WIN32 ${sources}) if(MSVC_CXX_ARCHITECTURE_ID MATCHES "^(x86|X86)$") set_target_properties(${target} PROPERTIES LINK_FLAGS "/INCLUDE:_wWinMain@16") + elseif(MSVC_CXX_ARCHITECTURE_ID MATCHES "ARM64EC") + set_target_properties(${target} PROPERTIES LINK_FLAGS "/INCLUDE:#wWinMain") else() set_target_properties(${target} PROPERTIES LINK_FLAGS "/INCLUDE:wWinMain") endif() diff --git a/vstgui/standalone/source/platform/win32/win32application.cpp b/vstgui/standalone/source/platform/win32/win32application.cpp index 01815c11a..a12a91ef1 100644 --- a/vstgui/standalone/source/platform/win32/win32application.cpp +++ b/vstgui/standalone/source/platform/win32/win32application.cpp @@ -315,22 +315,6 @@ void Application::run () } // Standalone } // VSTGUI -//---Workaround for Visual with ARM64EC platform -// Reported to Microsoft (29.03.2022): -// https://developercommunity.visualstudio.com/t/LINK-:-error-LNK2001:-unresolved-externa/1699333 -#if defined(_M_ARM64EC) -#include -//------------------------------------------------------------------------ -int APIENTRY WinMain (_In_ HINSTANCE instance, _In_opt_ HINSTANCE prevInstance, - _In_ LPSTR _lpCmdLine, _In_ int nCmdShow) -{ - USES_CONVERSION; - auto cmdLine = A2W (_lpCmdLine); - return wWinMain (instance, prevInstance, cmdLine, nCmdShow); -} -#endif -//---Workaround end - //------------------------------------------------------------------------ int APIENTRY wWinMain (_In_ HINSTANCE instance, _In_opt_ HINSTANCE prevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) From 423dc2a17de7d295d3857f985026e439e2f42c02 Mon Sep 17 00:00:00 2001 From: scheffle Date: Fri, 8 Jul 2022 15:29:53 +0200 Subject: [PATCH 24/51] fix wrong mouse location in onMouseMoveEvent and add a unit test for this bug fixes #259 --- vstgui/lib/cframe.cpp | 3 +-- vstgui/tests/unittest/lib/cframe_test.cpp | 28 +++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/vstgui/lib/cframe.cpp b/vstgui/lib/cframe.cpp index e874cb9a4..f67335651 100644 --- a/vstgui/lib/cframe.cpp +++ b/vstgui/lib/cframe.cpp @@ -663,8 +663,7 @@ void CFrame::dispatchMouseMoveEvent (MouseMoveEvent& event) { CPoint p (transformedMousePosition); auto view = *it; - if (auto parent = view->getParentView ()) - parent->translateToLocal (p, true); + view->translateToLocal (p); event.mousePosition = p; dispatchEvent (view, event); if (event.consumed) diff --git a/vstgui/tests/unittest/lib/cframe_test.cpp b/vstgui/tests/unittest/lib/cframe_test.cpp index 7d9d1fdb4..7cb654efb 100644 --- a/vstgui/tests/unittest/lib/cframe_test.cpp +++ b/vstgui/tests/unittest/lib/cframe_test.cpp @@ -291,6 +291,34 @@ TEST_CASE (CFrameTest, MouseEnterExitInContainer) frame->unregisterMouseObserver (&observer); } +TEST_CASE (CFrameTest, MouseMoveInContainer) +{ + struct TestView : CView + { + using CView::CView; + + CPoint mouseMoveEventPos {}; + CMouseEventResult onMouseMoved (CPoint& where, const CButtonState& buttons) override + { + mouseMoveEventPos = where; + return kMouseEventHandled; + } + }; + + auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr)); + auto container = new CViewContainer (CRect (10, 10, 80, 80)); + frame->addView (container); + + auto testView = new TestView ({10, 10, 60, 60}); + container->addView (testView); + + frame->attached (frame); + + EXPECT_EQ (dispatchMouseEvent (frame, {30., 30.}, MouseButton::None), + EventConsumeState::Handled); + EXPECT_EQ (testView->mouseMoveEventPos, CPoint (20., 20.)); +} + TEST_CASE (CFrameTest, RemoveViewWhileMouseInside) { MouseObserver observer; From f204ec4f7d6f373bdf413dea0563fe29ec00224b Mon Sep 17 00:00:00 2001 From: scheffle Date: Fri, 8 Jul 2022 15:36:18 +0200 Subject: [PATCH 25/51] fix detection of endianness with gcc fixes #260 --- vstgui/lib/vstguibase.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vstgui/lib/vstguibase.h b/vstgui/lib/vstguibase.h index b0183187a..e17448f65 100644 --- a/vstgui/lib/vstguibase.h +++ b/vstgui/lib/vstguibase.h @@ -220,10 +220,11 @@ using UTF8StringBuffer = char*; //----------------------------------------------------------------------------- // @brief Byte Order //----------------------------------------------------------------------------- -enum ByteOrder { +enum ByteOrder +{ kBigEndianByteOrder = 0, kLittleEndianByteOrder, -#if WINDOWS || defined (__LITTLE_ENDIAN__) +#if WINDOWS || defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) kNativeByteOrder = kLittleEndianByteOrder #else kNativeByteOrder = kBigEndianByteOrder From 12389f5ae64ec70494b5d6d83950b8990c254562 Mon Sep 17 00:00:00 2001 From: scheffle Date: Fri, 8 Jul 2022 15:38:31 +0200 Subject: [PATCH 26/51] add missing GraphicsPath::addEllipse to cairo path --- vstgui/lib/platform/linux/cairopath.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/vstgui/lib/platform/linux/cairopath.cpp b/vstgui/lib/platform/linux/cairopath.cpp index bf54b6c59..e7a3d6535 100644 --- a/vstgui/lib/platform/linux/cairopath.cpp +++ b/vstgui/lib/platform/linux/cairopath.cpp @@ -81,10 +81,7 @@ void GraphicsPath::addArc (const CRect& rect, double startAngle, double endAngle } //------------------------------------------------------------------------ -void GraphicsPath::addEllipse (const CRect& rect) -{ -#warning TODO: GraphicsPath::addEllipse -} +void GraphicsPath::addEllipse (const CRect& rect) { addArc (rect, 0, 360, true); } //------------------------------------------------------------------------ void GraphicsPath::addRect (const CRect& rect) From 42aff2cedd8a4f8cbb640ce3ff1b23896d6a05f5 Mon Sep 17 00:00:00 2001 From: scheffle Date: Fri, 8 Jul 2022 15:54:26 +0200 Subject: [PATCH 27/51] fix wrong matrix multiplication fixes #261 --- vstgui/lib/platform/linux/cairocontext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vstgui/lib/platform/linux/cairocontext.cpp b/vstgui/lib/platform/linux/cairocontext.cpp index c2d07eb37..578ded239 100644 --- a/vstgui/lib/platform/linux/cairocontext.cpp +++ b/vstgui/lib/platform/linux/cairocontext.cpp @@ -478,7 +478,7 @@ void Context::drawGraphicsPath (CGraphicsPath* path, CDrawContext::PathDrawMode cairo_matrix_t resultMatrix; auto matrix = convert (*transformation); cairo_get_matrix (cr, ¤tMatrix); - cairo_matrix_multiply (&resultMatrix, ¤tMatrix, &matrix); + cairo_matrix_multiply (&resultMatrix, &matrix, ¤tMatrix); cairo_set_matrix (cr, &resultMatrix); } cairo_append_path (cr, p); From b3953cd1f99f1c9935b807718431209dc1ab1d68 Mon Sep 17 00:00:00 2001 From: scheffle Date: Fri, 8 Jul 2022 16:29:51 +0200 Subject: [PATCH 28/51] fix wrong mouse location on mouse move (Part II) additional fix for #259 --- vstgui/lib/cframe.cpp | 8 ++++++- vstgui/tests/unittest/lib/cframe_test.cpp | 29 ++++++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/vstgui/lib/cframe.cpp b/vstgui/lib/cframe.cpp index f67335651..fb09421cf 100644 --- a/vstgui/lib/cframe.cpp +++ b/vstgui/lib/cframe.cpp @@ -663,7 +663,13 @@ void CFrame::dispatchMouseMoveEvent (MouseMoveEvent& event) { CPoint p (transformedMousePosition); auto view = *it; - view->translateToLocal (p); + if (view->asViewContainer ()) + { + if (auto parent = view->getParentView ()) + parent->translateToLocal (p, true); + } + else + view->translateToLocal (p, true); event.mousePosition = p; dispatchEvent (view, event); if (event.consumed) diff --git a/vstgui/tests/unittest/lib/cframe_test.cpp b/vstgui/tests/unittest/lib/cframe_test.cpp index 7cb654efb..665e96037 100644 --- a/vstgui/tests/unittest/lib/cframe_test.cpp +++ b/vstgui/tests/unittest/lib/cframe_test.cpp @@ -293,6 +293,16 @@ TEST_CASE (CFrameTest, MouseEnterExitInContainer) TEST_CASE (CFrameTest, MouseMoveInContainer) { + struct TestViewContainer : CViewContainer + { + using CViewContainer::CViewContainer; + CPoint mouseMoveEventPos {}; + CMouseEventResult onMouseMoved (CPoint& where, const CButtonState& buttons) override + { + mouseMoveEventPos = where; + return CViewContainer::onMouseMoved (where, buttons); + } + }; struct TestView : CView { using CView::CView; @@ -301,12 +311,12 @@ TEST_CASE (CFrameTest, MouseMoveInContainer) CMouseEventResult onMouseMoved (CPoint& where, const CButtonState& buttons) override { mouseMoveEventPos = where; - return kMouseEventHandled; + return kMouseEventNotHandled; } }; auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr)); - auto container = new CViewContainer (CRect (10, 10, 80, 80)); + auto container = new TestViewContainer (CRect (10, 10, 80, 80)); frame->addView (container); auto testView = new TestView ({10, 10, 60, 60}); @@ -315,8 +325,21 @@ TEST_CASE (CFrameTest, MouseMoveInContainer) frame->attached (frame); EXPECT_EQ (dispatchMouseEvent (frame, {30., 30.}, MouseButton::None), - EventConsumeState::Handled); + EventConsumeState::NotHandled); + EXPECT_EQ (container->mouseMoveEventPos, CPoint (30., 30.)); EXPECT_EQ (testView->mouseMoveEventPos, CPoint (20., 20.)); + + container->mouseMoveEventPos = {}; + testView->mouseMoveEventPos = {}; + + CGraphicsTransform tm; + tm.scale (2., 2.); + container->setTransform (tm); + + EXPECT_EQ (dispatchMouseEvent (frame, {30., 30.}, MouseButton::None), + EventConsumeState::NotHandled); + EXPECT_EQ (container->mouseMoveEventPos, CPoint (30., 30.)); + EXPECT_EQ (testView->mouseMoveEventPos, CPoint (10., 10.)); } TEST_CASE (CFrameTest, RemoveViewWhileMouseInside) From 2853a80505564e1215f52750654c1d4a4ccd2e65 Mon Sep 17 00:00:00 2001 From: scheffle Date: Sat, 9 Jul 2022 12:56:17 +0200 Subject: [PATCH 29/51] make D2DBitmap cache thread safe allowing to render to a bitmap on a background thread --- .../win32/direct2d/d2dbitmapcache.cpp | 55 ++++++++++++++----- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/vstgui/lib/platform/win32/direct2d/d2dbitmapcache.cpp b/vstgui/lib/platform/win32/direct2d/d2dbitmapcache.cpp index 5c1021ec7..8b8ed4b00 100644 --- a/vstgui/lib/platform/win32/direct2d/d2dbitmapcache.cpp +++ b/vstgui/lib/platform/win32/direct2d/d2dbitmapcache.cpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace VSTGUI { namespace D2DBitmapCache { @@ -29,6 +30,9 @@ struct Cache void removeDevice (ID2D1Device* device); private: + using Mutex = std::mutex; + using LockGuard = std::lock_guard; + COM::Ptr createBitmap (D2DBitmap* bitmap, ID2D1RenderTarget* renderTarget) const; struct ResourceLocation @@ -45,45 +49,66 @@ struct Cache using ResourceLocationList = std::vector>>; using BitmapMap = std::map; BitmapMap bitmaps; + + Mutex mutex; }; //----------------------------------------------------------------------------- ID2D1Bitmap* Cache::getBitmap (D2DBitmap* bitmap, ID2D1RenderTarget* renderTarget, ID2D1Device* device) { + ID2D1Bitmap* result = nullptr; + ResourceLocation resLoc {device, device ? nullptr : renderTarget}; + mutex.lock (); auto bitmapIt = bitmaps.find (bitmap); if (bitmapIt != bitmaps.end ()) { - auto resLocIt = std::find_if (bitmapIt->second.begin (), bitmapIt->second.end (), [&] (const auto& loc) { return loc.first == resLoc; }); if (resLocIt != bitmapIt->second.end ()) { - return resLocIt->second.get (); + result = resLocIt->second.get (); + mutex.unlock (); + } + else + { + mutex.unlock (); + auto b = createBitmap (bitmap, renderTarget); + if (b) + { + mutex.lock (); + bitmapIt->second.emplace_back (std::make_pair (resLoc, b)); + mutex.unlock (); + result = b.get (); + } } - auto b = createBitmap (bitmap, renderTarget); - if (b) - bitmapIt->second.emplace_back (std::make_pair (resLoc, b)); - return b.get (); } - auto insertSuccess = bitmaps.emplace (bitmap, ResourceLocationList ()); - if (insertSuccess.second == true) + else { - auto b = createBitmap (bitmap, renderTarget); - if (b) + auto insertSuccess = bitmaps.emplace (bitmap, ResourceLocationList ()); + mutex.unlock (); + if (insertSuccess.second == true) { - insertSuccess.first->second.emplace_back (std::make_pair (resLoc, b)); - return b.get (); + auto b = createBitmap (bitmap, renderTarget); + if (b) + { + mutex.lock (); + insertSuccess.first->second.emplace_back (std::make_pair (resLoc, b)); + mutex.unlock (); + result = b.get (); + } } } - return nullptr; + return result; } //----------------------------------------------------------------------------- void Cache::removeBitmap (D2DBitmap* bitmap) { + LockGuard g (mutex); + auto bitmapIt = bitmaps.find (bitmap); if (bitmapIt != bitmaps.end ()) bitmaps.erase (bitmapIt); @@ -92,6 +117,8 @@ void Cache::removeBitmap (D2DBitmap* bitmap) //----------------------------------------------------------------------------- void Cache::removeRenderTarget (ID2D1RenderTarget* renderTarget) { + LockGuard g (mutex); + auto bitmapIt = bitmaps.begin (); while (bitmapIt != bitmaps.end ()) { @@ -108,6 +135,8 @@ void Cache::removeRenderTarget (ID2D1RenderTarget* renderTarget) //----------------------------------------------------------------------------- void Cache::removeDevice (ID2D1Device* device) { + LockGuard g (mutex); + auto bitmapIt = bitmaps.begin (); while (bitmapIt != bitmaps.end ()) { From 9ffef9aa845c63438f9e46640eb30fa2d1e0f3b9 Mon Sep 17 00:00:00 2001 From: scheffle Date: Sun, 10 Jul 2022 09:41:01 +0200 Subject: [PATCH 30/51] make getCGColor thread safe --- vstgui/lib/platform/mac/macglobals.cpp | 76 +++++++++++++------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/vstgui/lib/platform/mac/macglobals.cpp b/vstgui/lib/platform/mac/macglobals.cpp index f3675d44b..3f4136bab 100644 --- a/vstgui/lib/platform/mac/macglobals.cpp +++ b/vstgui/lib/platform/mac/macglobals.cpp @@ -10,58 +10,60 @@ #include "macfactory.h" #include "../iplatformframe.h" #include "../common/fileresourceinputstream.h" -#include "../std_unorderedmap.h" +#include +#include namespace VSTGUI { //----------------------------------------------------------------------------- -struct ColorHash +class CGColorMap { - size_t operator () (const CColor& c) const +public: + struct ColorHash { - size_t v1 = static_cast (c.red | (c.green << 8) | (c.blue << 16) | (c.alpha << 24)); - return v1; - } -}; + size_t operator() (const CColor& c) const + { + return static_cast (c.red | (c.green << 8) | (c.blue << 16) | (c.alpha << 24)); + } + }; -using CGColorMap = std::unordered_map; + using Map = std::unordered_map; -//----------------------------------------------------------------------------- -class CGColorMapImpl -{ -public: - ~CGColorMapImpl () + static CGColorMap& instance () { - for (auto& it : map) - CFRelease (it.second); + static CGColorMap gInstance; + return gInstance; } - - CGColorMap map; -}; -//----------------------------------------------------------------------------- -static CGColorMap& getColorMap () -{ - static CGColorMapImpl colorMap; - return colorMap.map; -} + ~CGColorMap () noexcept + { + std::for_each (map.begin (), map.end (), [] (auto& el) { CFRelease (el.second); }); + } -//----------------------------------------------------------------------------- -CGColorRef getCGColor (const CColor& color) -{ - auto& colorMap = getColorMap (); - auto it = colorMap.find (color); - if (it != colorMap.end ()) + CGColorRef getColor (const CColor& color) { - CGColorRef result = it->second; + mutex.lock (); + auto it = map.find (color); + if (it != map.end ()) + { + auto result = it->second; + mutex.unlock (); + return result; + } + const CGFloat components[] = {color.normRed (), color.normGreen (), + color.normBlue (), color.normAlpha ()}; + auto result = CGColorCreate (GetCGColorSpace (), components); + map.emplace (color, result); + mutex.unlock (); return result; } - const CGFloat components[] = {color.normRed (), color.normGreen (), - color.normBlue (), color.normAlpha ()}; - CGColorRef result = CGColorCreate (GetCGColorSpace (), components); - colorMap.emplace (color, result); - return result; -} + + Map map; + std::mutex mutex; +}; + +//----------------------------------------------------------------------------- +CGColorRef getCGColor (const CColor& color) { return CGColorMap::instance ().getColor (color); } //----------------------------------------------------------------------------- class GenericMacColorSpace From 553e409c4a9d41297099d262d54c28a3f0982ee4 Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 13 Jul 2022 10:44:25 +0200 Subject: [PATCH 31/51] correctly return true from CFrame::setSize if the size is the same as already set --- vstgui/lib/cframe.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vstgui/lib/cframe.cpp b/vstgui/lib/cframe.cpp index fb09421cf..5e5e7f4b1 100644 --- a/vstgui/lib/cframe.cpp +++ b/vstgui/lib/cframe.cpp @@ -888,7 +888,7 @@ void CFrame::setViewSize (const CRect& rect, bool invalid) bool CFrame::setSize (CCoord width, CCoord height) { if ((width == getViewSize ().getWidth ()) && (height == getViewSize ().getHeight ())) - return false; + return true; CRect newSize (getViewSize ()); newSize.setWidth (width); From 85988732859bd28782f6b9c8186267282361fcc4 Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 13 Jul 2022 22:01:17 +0200 Subject: [PATCH 32/51] support setting arbitrary variables by using ivar_getOffset --- vstgui/lib/platform/mac/cocoa/objcclassbuilder.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h b/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h index ae5bc24fd..b52335454 100644 --- a/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h +++ b/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h @@ -31,9 +31,18 @@ struct ObjCVariable return *this; } - T get () const { return (__bridge T) (object_getIvar (obj, ivar)); } + T get () const + { + auto offset = ivar_getOffset (ivar); + return *reinterpret_cast (((__bridge uintptr_t)obj) + offset); + } - void set (const T& value) { object_setIvar (obj, ivar, (__bridge id) (value)); } + void set (const T& value) + { + auto offset = ivar_getOffset (ivar); + auto storage = reinterpret_cast (((__bridge uintptr_t)obj) + offset); + *storage = value; + } private: __unsafe_unretained id obj; From b413cd94288a0878ec5546879e91f986867306e7 Mon Sep 17 00:00:00 2001 From: scheffle Date: Thu, 14 Jul 2022 08:13:34 +0200 Subject: [PATCH 33/51] add RunTimeObjCClass template --- .../lib/platform/mac/cocoa/objcclassbuilder.h | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h b/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h index b52335454..2de8c3421 100644 --- a/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h +++ b/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h @@ -96,6 +96,30 @@ struct ObjCInstance mutable objc_super os {}; }; +//------------------------------------------------------------------------ +template +struct RuntimeObjCClass +{ + using Base = RuntimeObjCClass; + + static id alloc () + { + static T gInstance; + return class_createInstance (gInstance.cl, 0); + } + + RuntimeObjCClass () { cl = T::CreateClass (); } + + ~RuntimeObjCClass () noexcept + { + if (cl) + objc_disposeClassPair (cl); + } + +private: + Class cl {nullptr}; +}; + //------------------------------------------------------------------------------------ struct ObjCClassBuilder { From 20918ce88f5cae5468f4f634283cdff916448901 Mon Sep 17 00:00:00 2001 From: scheffle Date: Tue, 19 Jul 2022 09:09:32 +0200 Subject: [PATCH 34/51] fix issue when the objective-c class was transformed to a KVO object --- vstgui/lib/platform/mac/caviewlayer.mm | 42 ++++------ .../lib/platform/mac/cocoa/cocoaopenglview.mm | 53 +++++-------- .../lib/platform/mac/cocoa/cocoatextedit.mm | 78 ++++++++----------- .../mac/cocoa/nsviewdraggingsession.mm | 46 ++++------- vstgui/lib/platform/mac/cocoa/nsviewframe.mm | 37 +++------ .../platform/mac/cocoa/nsviewoptionmenu.mm | 56 +++++-------- .../lib/platform/mac/cocoa/objcclassbuilder.h | 33 ++++++-- 7 files changed, 140 insertions(+), 205 deletions(-) diff --git a/vstgui/lib/platform/mac/caviewlayer.mm b/vstgui/lib/platform/mac/caviewlayer.mm index ecc07ddaa..cb77e3d9e 100644 --- a/vstgui/lib/platform/mac/caviewlayer.mm +++ b/vstgui/lib/platform/mac/caviewlayer.mm @@ -76,35 +76,21 @@ - (void)setDrawDelegate:(VSTGUI::IPlatformViewLayerDelegate*)viewLayerDelegate; @end //----------------------------------------------------------------------------- -struct VSTGUI_macOS_CALayer +struct VSTGUI_macOS_CALayer : VSTGUI::RuntimeObjCClass { - static id newInstance () - { - return [[instance ().viewLayerClass alloc] init]; - } - -private: static constexpr const auto viewLayerDelegateVarName = "_viewLayerDelegate"; - Class viewLayerClass {nullptr}; - - //----------------------------------------------------------------------------- - VSTGUI_macOS_CALayer () - { - viewLayerClass = VSTGUI::ObjCClassBuilder () - .init ("VSTGUI_CALayer", [CALayer class]) - .addMethod (@selector (init), Init) - .addMethod (@selector (actionForKey:), ActionForKey) - .addMethod (@selector (setDrawDelegate:), SetDrawDelegate) - .addMethod (@selector (drawInContext:), DrawInContext) - .addIvar (viewLayerDelegateVarName) - .finalize (); - } - //----------------------------------------------------------------------------- - ~VSTGUI_macOS_CALayer () noexcept + static Class CreateClass () { - objc_disposeClassPair (viewLayerClass); + return VSTGUI::ObjCClassBuilder () + .init ("VSTGUI_CALayer", [CALayer class]) + .addMethod (@selector (init), Init) + .addMethod (@selector (actionForKey:), ActionForKey) + .addMethod (@selector (setDrawDelegate:), SetDrawDelegate) + .addMethod (@selector (drawInContext:), DrawInContext) + .addIvar (viewLayerDelegateVarName) + .finalize (); } //----------------------------------------------------------------------------- @@ -117,7 +103,7 @@ static id newInstance () //----------------------------------------------------------------------------- static id Init (id self, SEL _cmd) { - self = VSTGUI::ObjCInstance (self).callSuper (_cmd); + self = makeInstance (self).callSuper (_cmd); if (self) { [self setNeedsDisplayOnBoundsChange:YES]; @@ -132,7 +118,7 @@ static id Init (id self, SEL _cmd) static void SetDrawDelegate (id self, SEL _cmd, VSTGUI::IPlatformViewLayerDelegate* delegate) { using namespace VSTGUI; - if (auto var = ObjCInstance (self).getVariable ( + if (auto var = makeInstance (self).getVariable ( viewLayerDelegateVarName)) var->set (delegate); } @@ -142,7 +128,7 @@ static void DrawInContext (id self, SEL _cmd, CGContextRef ctx) { using namespace VSTGUI; - if (auto var = ObjCInstance (self).getVariable ( + if (auto var = makeInstance (self).getVariable ( viewLayerDelegateVarName); var.has_value ()) { @@ -183,7 +169,7 @@ static void DrawInContext (id self, SEL _cmd, CGContextRef ctx) : layer (nullptr) { #if !TARGET_OS_IPHONE - layer = VSTGUI_macOS_CALayer::newInstance (); + layer = [VSTGUI_macOS_CALayer::alloc () init]; #else layer = [VSTGUI_CALayer new]; #endif diff --git a/vstgui/lib/platform/mac/cocoa/cocoaopenglview.mm b/vstgui/lib/platform/mac/cocoa/cocoaopenglview.mm index 67417bb3a..d19432b30 100644 --- a/vstgui/lib/platform/mac/cocoa/cocoaopenglview.mm +++ b/vstgui/lib/platform/mac/cocoa/cocoaopenglview.mm @@ -28,48 +28,33 @@ - (id)initWithFrame:(NSRect)frameRect namespace VSTGUI { //----------------------------------------------------------------------------- -struct VSTGUI_NSOpenGLView +struct VSTGUI_NSOpenGLView : RuntimeObjCClass { - static id alloc () { return [instance ().openGLViewClass alloc]; } - -private: static constexpr const auto cocoaOpenGLViewVarName = "cocoaOpenGLView"; - Class openGLViewClass = nullptr; - - //----------------------------------------------------------------------------- - VSTGUI_NSOpenGLView () - { - openGLViewClass = ObjCClassBuilder () - .init ("VSTGUI_NSOpenGLView", [NSOpenGLView class]) - .addMethod (@selector (initWithFrame:pixelFormat:callback:), Init) - .addMethod (@selector (dealloc), Dealloc) - .addMethod (@selector (update), Update_Reshape) - .addMethod (@selector (reshape), Update_Reshape) - .addMethod (@selector (isFlipped), IsFlipped) - .addMethod (@selector (drawRect:), DrawRect) - .addMethod (@selector (mouseMoved:), MouseXXX) - .addMethod (@selector (rightMouseDown:), MouseXXX) - .addMethod (@selector (rightMouseUp:), MouseXXX) - .addIvar (cocoaOpenGLViewVarName) - .finalize (); - } - - //----------------------------------------------------------------------------- - ~VSTGUI_NSOpenGLView () noexcept { objc_disposeClassPair (openGLViewClass); } - //----------------------------------------------------------------------------- - static VSTGUI_NSOpenGLView& instance () + static Class CreateClass () { - static VSTGUI_NSOpenGLView gInstance; - return gInstance; + return ObjCClassBuilder () + .init ("VSTGUI_NSOpenGLView", [NSOpenGLView class]) + .addMethod (@selector (initWithFrame:pixelFormat:callback:), Init) + .addMethod (@selector (dealloc), Dealloc) + .addMethod (@selector (update), Update_Reshape) + .addMethod (@selector (reshape), Update_Reshape) + .addMethod (@selector (isFlipped), IsFlipped) + .addMethod (@selector (drawRect:), DrawRect) + .addMethod (@selector (mouseMoved:), MouseXXX) + .addMethod (@selector (rightMouseDown:), MouseXXX) + .addMethod (@selector (rightMouseUp:), MouseXXX) + .addIvar (cocoaOpenGLViewVarName) + .finalize (); } //----------------------------------------------------------------------------- static id Init (id self, SEL _cmd, NSRect frameRect, NSOpenGLPixelFormat* format, CocoaOpenGLView* callback) { - ObjCInstance obj (self); + auto obj = makeInstance (self); self = obj.callSuper ( @selector (initWithFrame:pixelFormat:), frameRect, format); if (self) @@ -86,7 +71,7 @@ static id Init (id self, SEL _cmd, NSRect frameRect, NSOpenGLPixelFormat* format //----------------------------------------------------------------------------- static void Dealloc (id self, SEL _cmd) { - ObjCInstance obj (self); + auto obj = makeInstance (self); if (auto var = obj.getVariable (cocoaOpenGLViewVarName)) { if (auto callback = var->get ()) @@ -98,7 +83,7 @@ static void Dealloc (id self, SEL _cmd) //----------------------------------------------------------------------------- static void Update_Reshape (id self, SEL _cmd) { - ObjCInstance obj (self); + auto obj = makeInstance (self); if (auto var = obj.getVariable (cocoaOpenGLViewVarName)) { if (auto callback = var->get ()) @@ -112,7 +97,7 @@ static void Update_Reshape (id self, SEL _cmd) //------------------------------------------------------------------------------------ static void DrawRect (id self, SEL _cmd, NSRect rect) { - ObjCInstance obj (self); + auto obj = makeInstance (self); if (auto var = obj.getVariable (cocoaOpenGLViewVarName)) { if (auto callback = var->get ()) diff --git a/vstgui/lib/platform/mac/cocoa/cocoatextedit.mm b/vstgui/lib/platform/mac/cocoa/cocoatextedit.mm index 82459d677..02c4ad1de 100644 --- a/vstgui/lib/platform/mac/cocoa/cocoatextedit.mm +++ b/vstgui/lib/platform/mac/cocoa/cocoatextedit.mm @@ -38,59 +38,43 @@ -(id)initWithTextEdit:(id)textEit; //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ -struct VSTGUI_NSTextField +template +struct VSTGUI_NSTextFieldT : RuntimeObjCClass> { - static id alloc () { return [instance ().textFieldClass alloc]; } - static id allocSecure () { return [instance ().secureTextFieldClass alloc]; } + using Base = RuntimeObjCClass>; -private: static constexpr const auto textEditVarName = "_textEdit"; - Class textFieldClass {nullptr}; - Class secureTextFieldClass {nullptr}; - - VSTGUI_NSTextField () + static Class CreateClass () { - textFieldClass = - ObjCClassBuilder () - .init ("VSTGUI_NSTextField", [NSTextField class]) + if constexpr (SecureT) + { + return ObjCClassBuilder () + .init ("VSTGUI_NSSecureTextField", [NSSecureTextField class]) .addMethod (@selector (initWithTextEdit:), Init) .addMethod (@selector (syncSize), SyncSize) .addMethod (@selector (removeFromSuperview), RemoveFromSuperview) .addMethod (@selector (control:textView:doCommandBySelector:), DoCommandBySelector) .addMethod (@selector (textDidChange:), TextDidChange) - .addIvar (textEditVarName) + .addIvar (textEditVarName) .finalize (); - - secureTextFieldClass = - ObjCClassBuilder () - .init ("VSTGUI_NSSecureTextField", [NSSecureTextField class]) + } + else + { + return ObjCClassBuilder () + .init ("VSTGUI_NSTextField", [NSTextField class]) .addMethod (@selector (initWithTextEdit:), Init) .addMethod (@selector (syncSize), SyncSize) .addMethod (@selector (removeFromSuperview), RemoveFromSuperview) .addMethod (@selector (control:textView:doCommandBySelector:), DoCommandBySelector) .addMethod (@selector (textDidChange:), TextDidChange) - .addIvar (textEditVarName) + .addIvar (textEditVarName) .finalize (); - } - - ~VSTGUI_NSTextField () noexcept - { - if (textFieldClass) - objc_disposeClassPair (textFieldClass); - if (secureTextFieldClass) - objc_disposeClassPair (secureTextFieldClass); - } - - static VSTGUI_NSTextField& instance () - { - static VSTGUI_NSTextField gInstance; - return gInstance; + } } static id Init (id self, SEL _cmd, void* textEdit) { - ObjCInstance obj (self); if (self) { CocoaTextEdit* te = (CocoaTextEdit*)textEdit; @@ -119,14 +103,15 @@ static id Init (id self, SEL _cmd, void* textEdit) editFrameRect.origin.y = static_cast (textInset.y / 2.); editFrameRect.size.width -= textInset.x / 2.; editFrameRect.size.height -= textInset.y / 2. - 1.; - self = - obj.callSuper (@selector (initWithFrame:), editFrameRect); + self = Base::makeInstance (self).template callSuper ( + @selector (initWithFrame:), editFrameRect); if (!self) { [containerView release]; return nil; } - if (auto var = obj.getVariable (textEditVarName)) + auto obj = Base::makeInstance (self); + if (auto var = obj.template getVariable (textEditVarName)) var->set (tec); CoreTextFont* ctf = tec->platformGetFont ()->getPlatformFont ().cast (); @@ -217,7 +202,8 @@ static id Init (id self, SEL _cmd, void* textEdit) //------------------------------------------------------------------------------------ static void SyncSize (id self, SEL _cmd) { - if (auto te = ObjCInstance (self).getVariable (textEditVarName)) + if (auto te = Base::makeInstance (self).template getVariable ( + textEditVarName)) { auto textEdit = te->get (); if (!textEdit) @@ -236,8 +222,8 @@ static void SyncSize (id self, SEL _cmd) //------------------------------------------------------------------------------------ static void RemoveFromSuperview (id self, SEL _cmd) { - ObjCInstance obj (self); - if (auto var = obj.getVariable (textEditVarName)) + auto obj = Base::makeInstance (self); + if (auto var = obj.template getVariable (textEditVarName)) var->set (nullptr); NSView* containerView = [self superview]; if (containerView) @@ -245,7 +231,7 @@ static void RemoveFromSuperview (id self, SEL _cmd) [[containerView window] makeFirstResponder:[containerView superview]]; [containerView removeFromSuperview]; // [super removeFromSuperview]; - obj.callSuper (_cmd); + obj.template callSuper (_cmd); [containerView release]; } } @@ -253,20 +239,21 @@ static void RemoveFromSuperview (id self, SEL _cmd) //------------------------------------------------------------------------------------ static void TextDidChange (id self, SEL _cmd, NSNotification* notification) { - ObjCInstance obj (self); - if (auto var = obj.getVariable (textEditVarName)) + auto obj = Base::makeInstance (self); + if (auto var = obj.template getVariable (textEditVarName)) { if (auto te = var->get ()) te->platformTextDidChange (); } - obj.callSuper (_cmd, notification); + obj.template callSuper (_cmd, notification); } //------------------------------------------------------------------------------------ static BOOL DoCommandBySelector (id self, SEL _cmd, NSControl* control, NSTextView* textView, SEL commandSelector) { - auto var = ObjCInstance (self).getVariable (textEditVarName); + auto var = Base::makeInstance (self).template getVariable ( + textEditVarName); if (!var) return NO; IPlatformTextEditCallback* tec = var->get (); @@ -313,6 +300,9 @@ static BOOL DoCommandBySelector (id self, SEL _cmd, NSControl* control, NSTextVi } }; +using VSTGUI_NSTextField = VSTGUI_NSTextFieldT; +using VSTGUI_NSTextField_Secure = VSTGUI_NSTextFieldT; + //----------------------------------------------------------------------------- CocoaTextEdit::CocoaTextEdit (NSView* parent, IPlatformTextEditCallback* textEdit) : IPlatformTextEdit (textEdit) @@ -320,7 +310,7 @@ static BOOL DoCommandBySelector (id self, SEL _cmd, NSControl* control, NSTextVi , parent (parent) { if (textEdit->platformIsSecureTextEdit ()) - platformControl = [VSTGUI_NSTextField::allocSecure () initWithTextEdit:(id)this]; + platformControl = [VSTGUI_NSTextField_Secure::alloc () initWithTextEdit:(id)this]; else platformControl = [VSTGUI_NSTextField::alloc () initWithTextEdit:(id)this]; } diff --git a/vstgui/lib/platform/mac/cocoa/nsviewdraggingsession.mm b/vstgui/lib/platform/mac/cocoa/nsviewdraggingsession.mm index 0501614fd..6ab7ab439 100644 --- a/vstgui/lib/platform/mac/cocoa/nsviewdraggingsession.mm +++ b/vstgui/lib/platform/mac/cocoa/nsviewdraggingsession.mm @@ -29,15 +29,8 @@ - (id)initWithData:(const void*)data andSize:(size_t)size; namespace VSTGUI { //------------------------------------------------------------------------ -struct BinaryDataType +struct BinaryDataType : RuntimeObjCClass { - static Class& getClass () - { - static BinaryDataType instance; - return instance.cl; - } - -private: static constexpr const auto dataVarName = "_data"; static NSString* getCocoaPasteboardTypeString () @@ -48,7 +41,7 @@ - (id)initWithData:(const void*)data andSize:(size_t)size; static id Init (id self, SEL, const void* buffer, size_t bufferSize) { - ObjCInstance obj (self); + auto obj = makeInstance (self); self = obj.callSuper (@selector (init)); if (self) { @@ -61,7 +54,7 @@ static id Init (id self, SEL, const void* buffer, size_t bufferSize) static void Dealloc (id self, SEL _cmd) { - ObjCInstance obj (self); + auto obj = makeInstance (self); if (auto var = obj.getVariable (dataVarName); var.has_value () && var->get ()) { [var->get () release]; @@ -77,30 +70,23 @@ static void Dealloc (id self, SEL _cmd) static id PasteboardPropertyListForType (id self, SEL, NSPasteboardType) { - ObjCInstance obj (self); + auto obj = makeInstance (self); if (auto var = obj.getVariable (dataVarName); var.has_value () && var->get ()) return var->get (); return nullptr; } - Class cl {nullptr}; - - BinaryDataType () { initClass (); } - - ~BinaryDataType () { objc_disposeClassPair (cl); } - - void initClass () + static Class CreateClass () { - cl = ObjCClassBuilder () - .init ("VSTGUI_BinaryDataType", [NSObject class]) - .addProtocol ("NSPasteboardWriting") - .addMethod (@selector (initWithData:andSize:), Init) - .addMethod (@selector (dealloc), Dealloc) - .addMethod (@selector (writableTypesForPasteboard:), WritableTypesForPasteboard) - .addMethod (@selector (pasteboardPropertyListForType:), - PasteboardPropertyListForType) - .addIvar (dataVarName) - .finalize (); + return ObjCClassBuilder () + .init ("VSTGUI_BinaryDataType", [NSObject class]) + .addProtocol ("NSPasteboardWriting") + .addMethod (@selector (initWithData:andSize:), Init) + .addMethod (@selector (dealloc), Dealloc) + .addMethod (@selector (writableTypesForPasteboard:), WritableTypesForPasteboard) + .addMethod (@selector (pasteboardPropertyListForType:), PasteboardPropertyListForType) + .addIvar (dataVarName) + .finalize (); } }; @@ -159,8 +145,8 @@ void initClass () } case IDataPackage::kBinary: { - if (id data = [[[BinaryDataType::getClass () alloc] initWithData:buffer - andSize:size] autorelease]) + if (id data = [[BinaryDataType::alloc () initWithData:buffer + andSize:size] autorelease]) item = [[[NSDraggingItem alloc] initWithPasteboardWriter:data] autorelease]; break; } diff --git a/vstgui/lib/platform/mac/cocoa/nsviewframe.mm b/vstgui/lib/platform/mac/cocoa/nsviewframe.mm index 5b927842f..bc9ad3dfb 100644 --- a/vstgui/lib/platform/mac/cocoa/nsviewframe.mm +++ b/vstgui/lib/platform/mac/cocoa/nsviewframe.mm @@ -167,17 +167,12 @@ static NSPoint getGlobalMouseLocation (NSView* view) #endif //------------------------------------------------------------------------------------ -struct VSTGUI_NSView +struct VSTGUI_NSView : RuntimeObjCClass { - static id alloc () { return [instance ().viewClass alloc]; } - -private: static constexpr const auto nsViewFrameVarName = "_nsViewFrame"; - Class viewClass {nullptr}; - //------------------------------------------------------------------------------------ - VSTGUI_NSView () + static Class CreateClass () { ObjCClassBuilder builder; builder.init ("VSTGUI_NSView", [NSView class]) @@ -253,23 +248,13 @@ static NSPoint getGlobalMouseLocation (NSView* view) builder.addIvar ("_nsViewFrame"); - viewClass = builder.finalize (); - } - - //------------------------------------------------------------------------------------ - ~VSTGUI_NSView () { objc_disposeClassPair (viewClass); } - - //------------------------------------------------------------------------------------ - static VSTGUI_NSView& instance () - { - static VSTGUI_NSView gInstance; - return gInstance; + return builder.finalize (); } //------------------------------------------------------------------------------------ static NSViewFrame* getNSViewFrame (id obj) { - if (auto var = ObjCInstance (obj).getVariable (nsViewFrameVarName)) + if (auto var = makeInstance (obj).getVariable (nsViewFrameVarName)) return var->get (); return nullptr; } @@ -285,7 +270,7 @@ static NSPoint getGlobalMouseLocation (NSView* view) //------------------------------------------------------------------------------------ static id init (id self, SEL _cmd, void* _frame, NSView* parentView, const void* _size) { - ObjCInstance obj (self); + auto obj = makeInstance (self); const CRect* size = (const CRect*)_size; NSViewFrame* frame = (NSViewFrame*)_frame; @@ -377,7 +362,7 @@ static void updateTrackingAreas (id self, SEL _cmd) if (viewFrame) viewFrame->initTrackingArea (); - ObjCInstance (self).callSuper (_cmd); + makeInstance (self).callSuper (_cmd); } //------------------------------------------------------------------------------------ @@ -462,7 +447,7 @@ static void viewWillDraw (id self, SEL _cmd) layer.contentsFormat = kCAContentsFormatRGBA8Uint; } } - ObjCInstance (self).callSuper (_cmd); + makeInstance (self).callSuper (_cmd); } //------------------------------------------------------------------------ @@ -471,7 +456,7 @@ static void setNeedsDisplayInRect (id self, SEL _cmd, NSRect rect) NSViewFrame* frame = getNSViewFrame (self); if (frame) frame->setNeedsDisplayInRect (rect); - ObjCInstance (self).callSuper (_cmd, rect); + makeInstance (self).callSuper (_cmd, rect); } //------------------------------------------------------------------------------------ @@ -506,7 +491,7 @@ static void mouseDown (id self, SEL _cmd, NSEvent* theEvent) { if (![self onMouseDown:theEvent]) { - ObjCInstance (self).callSuper (_cmd, theEvent); + makeInstance (self).callSuper (_cmd, theEvent); } } @@ -515,7 +500,7 @@ static void mouseUp (id self, SEL _cmd, NSEvent* theEvent) { if (![self onMouseUp:theEvent]) { - ObjCInstance (self).callSuper (_cmd, theEvent); + makeInstance (self).callSuper (_cmd, theEvent); } } @@ -524,7 +509,7 @@ static void mouseMoved (id self, SEL _cmd, NSEvent* theEvent) { if (![self onMouseMoved:theEvent]) { - ObjCInstance (self).callSuper (_cmd, theEvent); + makeInstance (self).callSuper (_cmd, theEvent); } } diff --git a/vstgui/lib/platform/mac/cocoa/nsviewoptionmenu.mm b/vstgui/lib/platform/mac/cocoa/nsviewoptionmenu.mm index 5d3185a05..8fb92689a 100644 --- a/vstgui/lib/platform/mac/cocoa/nsviewoptionmenu.mm +++ b/vstgui/lib/platform/mac/cocoa/nsviewoptionmenu.mm @@ -33,41 +33,32 @@ - (id)initWithOptionMenu:(id)menu; //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ -struct VSTGUI_NSMenu +struct VSTGUI_NSMenu : RuntimeObjCClass { - //------------------------------------------------------------------------------------ - static id alloc () { return [instance ().menuClass alloc]; } - -private: static constexpr const auto privateVarName = "_private"; - Class menuClass {nullptr}; int32_t menuClassCount = 0; //------------------------------------------------------------------------------------ - VSTGUI_NSMenu () + static Class CreateClass () { - menuClass = ObjCClassBuilder () - .init ("VSTGUI_NSMenu", [NSMenu class]) - .addMethod (@selector (initWithOptionMenu:), Init) - .addMethod (@selector (dealloc), Dealloc) - .addMethod (@selector (validateMenuItem:), ValidateMenuItem) - .addMethod (@selector (menuItemSelected:), MenuItemSelected) - .addMethod (@selector (optionMenu), OptionMenu) - .addMethod (@selector (selectedMenu), SelectedMenu) - .addMethod (@selector (selectedItem), SelectedItem) - .addMethod (@selector (setSelectedMenu:), SetSelectedMenu) - .addMethod (@selector (setSelectedItem:), SetSelectedItem) - .addIvar (privateVarName) - .finalize (); + return ObjCClassBuilder () + .init ("VSTGUI_NSMenu", [NSMenu class]) + .addMethod (@selector (initWithOptionMenu:), Init) + .addMethod (@selector (dealloc), Dealloc) + .addMethod (@selector (validateMenuItem:), ValidateMenuItem) + .addMethod (@selector (menuItemSelected:), MenuItemSelected) + .addMethod (@selector (optionMenu), OptionMenu) + .addMethod (@selector (selectedMenu), SelectedMenu) + .addMethod (@selector (selectedItem), SelectedItem) + .addMethod (@selector (setSelectedMenu:), SetSelectedMenu) + .addMethod (@selector (setSelectedItem:), SetSelectedItem) + .addIvar (privateVarName) + .finalize (); } //------------------------------------------------------------------------------------ - ~VSTGUI_NSMenu () noexcept - { - objc_disposeClassPair (menuClass); - vstgui_assert (menuClassCount == 0); - } + ~VSTGUI_NSMenu () noexcept { vstgui_assert (menuClassCount == 0); } //------------------------------------------------------------------------------------ struct Var @@ -77,18 +68,11 @@ - (id)initWithOptionMenu:(id)menu; int32_t _selectedItem {0}; }; - //------------------------------------------------------------------------------------ - static VSTGUI_NSMenu& instance () - { - static VSTGUI_NSMenu gInstance; - return gInstance; - } - //------------------------------------------------------------------------------------ static id Init (id self, SEL _cmd, void* _menu) { instance ().menuClassCount++; - ObjCInstance obj (self); + auto obj = makeInstance (self); self = obj.callSuper (@selector (init)); if (self) { @@ -194,7 +178,7 @@ static id Init (id self, SEL _cmd, void* _menu) //----------------------------------------------------------------------------- static void setVar (id self, Var* var) { - if (auto v = ObjCInstance (self).getVariable (privateVarName)) + if (auto v = makeInstance (self).getVariable (privateVarName)) { if (auto old = v->get ()) delete old; @@ -205,7 +189,7 @@ static void setVar (id self, Var* var) //----------------------------------------------------------------------------- static Var* getVar (id self) { - if (auto v = ObjCInstance (self).getVariable (privateVarName); v.has_value ()) + if (auto v = makeInstance (self).getVariable (privateVarName); v.has_value ()) return v->get (); return nullptr; } @@ -216,7 +200,7 @@ static void Dealloc (id self, SEL _cmd) instance ().menuClassCount--; setVar (self, nullptr); - ObjCInstance (self).callSuper (_cmd); + makeInstance (self).callSuper (_cmd); } //------------------------------------------------------------------------------------ diff --git a/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h b/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h index 2de8c3421..b00b3591f 100644 --- a/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h +++ b/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h @@ -52,7 +52,10 @@ struct ObjCVariable //------------------------------------------------------------------------------------ struct ObjCInstance { - ObjCInstance (__unsafe_unretained id obj) : obj (obj) {} + ObjCInstance (__unsafe_unretained id obj, Class superClass = nullptr) : obj (obj) + { + os.super_class = superClass; + } template std::optional> getVariable (const char* name) const @@ -87,6 +90,9 @@ struct ObjCInstance if (os.receiver == nullptr) { os.receiver = obj; + } + if (os.super_class == nullptr) + { os.super_class = class_getSuperclass (object_getClass (obj)); } return (__bridge id) (&os); @@ -102,22 +108,35 @@ struct RuntimeObjCClass { using Base = RuntimeObjCClass; - static id alloc () + static id alloc () { return class_createInstance (instance ().cl, 0); } + + RuntimeObjCClass () { - static T gInstance; - return class_createInstance (gInstance.cl, 0); + cl = T::CreateClass (); + superClass = class_getSuperclass (cl); } - RuntimeObjCClass () { cl = T::CreateClass (); } - - ~RuntimeObjCClass () noexcept + virtual ~RuntimeObjCClass () noexcept { if (cl) objc_disposeClassPair (cl); } + static ObjCInstance makeInstance (__unsafe_unretained id obj) + { + return ObjCInstance (obj, instance ().superClass); + } + +protected: + static T& instance () + { + static T gInstance; + return gInstance; + } + private: Class cl {nullptr}; + Class superClass {nullptr}; }; //------------------------------------------------------------------------------------ From 9ca1475ea6b9594800ba7edb9bd5b51f0745b1ca Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 20 Jul 2022 15:39:31 +0200 Subject: [PATCH 35/51] support classes with custom alloc implementation like CALayer --- vstgui/lib/platform/mac/caviewlayer.mm | 7 ------- .../lib/platform/mac/cocoa/objcclassbuilder.h | 18 +++++++++++++++++- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/vstgui/lib/platform/mac/caviewlayer.mm b/vstgui/lib/platform/mac/caviewlayer.mm index cb77e3d9e..b2b754b08 100644 --- a/vstgui/lib/platform/mac/caviewlayer.mm +++ b/vstgui/lib/platform/mac/caviewlayer.mm @@ -93,13 +93,6 @@ static Class CreateClass () .finalize (); } - //----------------------------------------------------------------------------- - static VSTGUI_macOS_CALayer& instance () - { - static VSTGUI_macOS_CALayer gInstance; - return gInstance; - } - //----------------------------------------------------------------------------- static id Init (id self, SEL _cmd) { diff --git a/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h b/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h index b00b3591f..e2e87f6ff 100644 --- a/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h +++ b/vstgui/lib/platform/mac/cocoa/objcclassbuilder.h @@ -108,7 +108,20 @@ struct RuntimeObjCClass { using Base = RuntimeObjCClass; - static id alloc () { return class_createInstance (instance ().cl, 0); } + static id alloc () + { + static auto allocSel = sel_registerName ("alloc"); + if (auto method = class_getClassMethod (instance ().cl, allocSel)) + { + if (auto methodImpl = method_getImplementation (method)) + { + using fn2 = id (*) (id, SEL); + auto alloc = (fn2)methodImpl; + return alloc (instance ().cl, allocSel); + } + } + return nil; + } RuntimeObjCClass () { @@ -134,6 +147,9 @@ struct RuntimeObjCClass return gInstance; } + Class getClass () const { return cl; } + Class getSuperClass () const { return superClass; } + private: Class cl {nullptr}; Class superClass {nullptr}; From ace97da4d591b5dc432a3c4db15ab4d72e8470cd Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 20 Jul 2022 15:59:42 +0200 Subject: [PATCH 36/51] add more actual github runners --- .github/workflows/cmake_linux.yml | 2 +- .github/workflows/cmake_macos.yml | 2 +- .github/workflows/cmake_windows.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml index 7b2dba677..adb357291 100644 --- a/.github/workflows/cmake_linux.yml +++ b/.github/workflows/cmake_linux.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: - os: [ubuntu-18.04] + os: [ubuntu-18.04, ubuntu-22.04] steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index ad1a89deb..e362dde4b 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: - os: [macos-10.15, macos-11.0] + os: [macos-10.15, macos-11, macos-12] steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/cmake_windows.yml b/.github/workflows/cmake_windows.yml index 13b3338f3..54055fa33 100644 --- a/.github/workflows/cmake_windows.yml +++ b/.github/workflows/cmake_windows.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: - os: [windows-2019] + os: [windows-2019, windows-2022] steps: - uses: actions/checkout@v2 From 6ae83cef82a2c27a2fabd61fd038f3f7f1fc6f5f Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 20 Jul 2022 17:08:21 +0200 Subject: [PATCH 37/51] fix checking if linking to UniformTypeIdentifier is necessary --- vstgui/lib/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vstgui/lib/CMakeLists.txt b/vstgui/lib/CMakeLists.txt index a0e473b0c..b2da7a242 100644 --- a/vstgui/lib/CMakeLists.txt +++ b/vstgui/lib/CMakeLists.txt @@ -347,7 +347,11 @@ if(CMAKE_HOST_APPLE) "-framework QuartzCore" "-framework Accelerate" ) - if(CMAKE_OSX_DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 11.0) + find_library( + UTI_FRAMEWORK "UniformTypeIdentifiers" + NO_CACHE + ) + if(UTI_FRAMEWORK) set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} "-framework UniformTypeIdentifiers" From 58252cb16022f4fdf60bd8527d6c359181e91ece Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 20 Jul 2022 17:08:49 +0200 Subject: [PATCH 38/51] fix initial step value to prevent assert --- vstgui/tools/imagestitcher/source/documentcontroller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vstgui/tools/imagestitcher/source/documentcontroller.cpp b/vstgui/tools/imagestitcher/source/documentcontroller.cpp index cd7f717b7..979ae3554 100644 --- a/vstgui/tools/imagestitcher/source/documentcontroller.cpp +++ b/vstgui/tools/imagestitcher/source/documentcontroller.cpp @@ -230,7 +230,7 @@ UIDesc::ModelBindingPtr DocumentWindowController::createModelBinding () v.performEdit (0.); })); - displayFrameValue = Value::makeStepValue ("DisplayFrame", 0, 1); + displayFrameValue = Value::makeStepValue ("DisplayFrame", 1, 1); binding->addValue (displayFrameValue); auto animationRunning = Value::make ("RunAnimation"); From d5d64b7e220e68b407f367a00a370f9df347cb57 Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 20 Jul 2022 17:27:17 +0200 Subject: [PATCH 39/51] fix unittest linking --- vstgui/tests/unittest/CMakeLists.txt | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/vstgui/tests/unittest/CMakeLists.txt b/vstgui/tests/unittest/CMakeLists.txt index 7fff5f981..4ed83cbfb 100644 --- a/vstgui/tests/unittest/CMakeLists.txt +++ b/vstgui/tests/unittest/CMakeLists.txt @@ -102,11 +102,15 @@ if(CMAKE_HOST_APPLE) "-framework QuartzCore" "-framework Accelerate" ) - if(CMAKE_OSX_DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 11.0) - set(${target}_PLATFORM_LIBS - ${${target}_PLATFORM_LIBS} - "-framework UniformTypeIdentifiers" - ) + find_library( + UTI_FRAMEWORK "UniformTypeIdentifiers" + NO_CACHE + ) + if(UTI_FRAMEWORK) + set(PLATFORM_LIBRARIES + ${PLATFORM_LIBRARIES} + "-framework UniformTypeIdentifiers" + ) endif() endif() From f3459908c304a792787baa061723d91b110a77c5 Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 20 Jul 2022 17:56:11 +0200 Subject: [PATCH 40/51] fix unittest build --- vstgui/tests/unittest/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vstgui/tests/unittest/CMakeLists.txt b/vstgui/tests/unittest/CMakeLists.txt index 4ed83cbfb..3276e503e 100644 --- a/vstgui/tests/unittest/CMakeLists.txt +++ b/vstgui/tests/unittest/CMakeLists.txt @@ -107,8 +107,8 @@ if(CMAKE_HOST_APPLE) NO_CACHE ) if(UTI_FRAMEWORK) - set(PLATFORM_LIBRARIES - ${PLATFORM_LIBRARIES} + set(${target}_PLATFORM_LIBS + ${${target}_PLATFORM_LIBS} "-framework UniformTypeIdentifiers" ) endif() From b2cdc9877e1216c3196772d61f404a7fd27a18c4 Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 20 Jul 2022 18:31:53 +0200 Subject: [PATCH 41/51] see why it finds the framework on 10.15 --- .github/workflows/cmake_macos.yml | 3 ++- vstgui/lib/CMakeLists.txt | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index e362dde4b..5c427d985 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -8,7 +8,8 @@ jobs: strategy: matrix: - os: [macos-10.15, macos-11, macos-12] + os: [macos-10.15] +# os: [macos-10.15, macos-11, macos-12] steps: - uses: actions/checkout@v2 diff --git a/vstgui/lib/CMakeLists.txt b/vstgui/lib/CMakeLists.txt index b2da7a242..a3ab98d8f 100644 --- a/vstgui/lib/CMakeLists.txt +++ b/vstgui/lib/CMakeLists.txt @@ -351,6 +351,7 @@ if(CMAKE_HOST_APPLE) UTI_FRAMEWORK "UniformTypeIdentifiers" NO_CACHE ) + message(${UTI_FRAMEWORK}) if(UTI_FRAMEWORK) set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} From 0a1335c49d792f55ade4fe887afd0deb8c783d65 Mon Sep 17 00:00:00 2001 From: scheffle Date: Thu, 21 Jul 2022 09:26:13 +0200 Subject: [PATCH 42/51] check the uti framework variable --- vstgui/tests/unittest/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/vstgui/tests/unittest/CMakeLists.txt b/vstgui/tests/unittest/CMakeLists.txt index 3276e503e..34d169463 100644 --- a/vstgui/tests/unittest/CMakeLists.txt +++ b/vstgui/tests/unittest/CMakeLists.txt @@ -107,6 +107,7 @@ if(CMAKE_HOST_APPLE) NO_CACHE ) if(UTI_FRAMEWORK) + message(${UTI_FRAMEWORK}) set(${target}_PLATFORM_LIBS ${${target}_PLATFORM_LIBS} "-framework UniformTypeIdentifiers" From 34187df9ac46df845a4a1eb26f153448ed106ff2 Mon Sep 17 00:00:00 2001 From: scheffle Date: Thu, 21 Jul 2022 09:45:05 +0200 Subject: [PATCH 43/51] Update CMakeLists.txt --- vstgui/tests/unittest/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/vstgui/tests/unittest/CMakeLists.txt b/vstgui/tests/unittest/CMakeLists.txt index 34d169463..f4bda9273 100644 --- a/vstgui/tests/unittest/CMakeLists.txt +++ b/vstgui/tests/unittest/CMakeLists.txt @@ -102,6 +102,7 @@ if(CMAKE_HOST_APPLE) "-framework QuartzCore" "-framework Accelerate" ) + set(CMAKE_FRAMEWORK_PATH ${CMAKE_OSX_SYSROOT}) find_library( UTI_FRAMEWORK "UniformTypeIdentifiers" NO_CACHE From 356b4e04cc313fce503d79e25820f09aa19cba3b Mon Sep 17 00:00:00 2001 From: scheffle Date: Thu, 21 Jul 2022 10:07:31 +0200 Subject: [PATCH 44/51] fix linking issues --- .github/workflows/cmake_macos.yml | 3 +-- CMakeLists.txt | 2 +- vstgui/CMakeLists.txt | 2 +- vstgui/lib/CMakeLists.txt | 8 ++------ vstgui/lib/platform/mac/macfileselector.mm | 9 +++++++-- vstgui/tests/unittest/CMakeLists.txt | 23 ++++++++++------------ 6 files changed, 22 insertions(+), 25 deletions(-) diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index 5c427d985..e362dde4b 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -8,8 +8,7 @@ jobs: strategy: matrix: - os: [macos-10.15] -# os: [macos-10.15, macos-11, macos-12] + os: [macos-10.15, macos-11, macos-12] steps: - uses: actions/checkout@v2 diff --git a/CMakeLists.txt b/CMakeLists.txt index d65a8710c..ecc85fa91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5) if(NOT PROJECT_NAME) - set(CMAKE_OSX_DEPLOYMENT_TARGET CACHE STRING 10.12) + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.14 CACHE STRING "") project(vstgui) set(VSTGUI_MAIN_PROJECT_BUILD 1) diff --git a/vstgui/CMakeLists.txt b/vstgui/CMakeLists.txt index 1a0680266..e640c10cb 100644 --- a/vstgui/CMakeLists.txt +++ b/vstgui/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5) if(NOT PROJECT_NAME) - set(CMAKE_OSX_DEPLOYMENT_TARGET CACHE STRING 10.12) + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.14 CACHE STRING "") project(vstgui) set(VSTGUI_MAIN_PROJECT_BUILD 1) endif() diff --git a/vstgui/lib/CMakeLists.txt b/vstgui/lib/CMakeLists.txt index a3ab98d8f..0028a607f 100644 --- a/vstgui/lib/CMakeLists.txt +++ b/vstgui/lib/CMakeLists.txt @@ -347,12 +347,8 @@ if(CMAKE_HOST_APPLE) "-framework QuartzCore" "-framework Accelerate" ) - find_library( - UTI_FRAMEWORK "UniformTypeIdentifiers" - NO_CACHE - ) - message(${UTI_FRAMEWORK}) - if(UTI_FRAMEWORK) + if(CMAKE_OSX_DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 11.0) + target_compile_definitions(${target} "VSTGUI_USE_OBJC_UTTYPE") set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} "-framework UniformTypeIdentifiers" diff --git a/vstgui/lib/platform/mac/macfileselector.mm b/vstgui/lib/platform/mac/macfileselector.mm index 64f33f680..35d09f351 100644 --- a/vstgui/lib/platform/mac/macfileselector.mm +++ b/vstgui/lib/platform/mac/macfileselector.mm @@ -9,9 +9,12 @@ #import "macfileselector.h" #import "macstring.h" -#if defined(MAC_OS_VERSION_11_0) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0) +#pragma clang diagnostic push + +#if defined(VSTGUI_USE_OBJC_UTTYPE) #import -#define VSTGUI_USE_OBJC_UTTYPE +#else +#pragma clang diagnostic ignored "-Wdeprecated-declarations" #endif namespace VSTGUI { @@ -290,4 +293,6 @@ PlatformFileSelectorPtr createCocoaFileSelector (PlatformFileSelectorStyle style } // VSTGUI +#pragma clang diagnostic pop + /// @endcond diff --git a/vstgui/tests/unittest/CMakeLists.txt b/vstgui/tests/unittest/CMakeLists.txt index f4bda9273..ad6ce8ad9 100644 --- a/vstgui/tests/unittest/CMakeLists.txt +++ b/vstgui/tests/unittest/CMakeLists.txt @@ -102,18 +102,6 @@ if(CMAKE_HOST_APPLE) "-framework QuartzCore" "-framework Accelerate" ) - set(CMAKE_FRAMEWORK_PATH ${CMAKE_OSX_SYSROOT}) - find_library( - UTI_FRAMEWORK "UniformTypeIdentifiers" - NO_CACHE - ) - if(UTI_FRAMEWORK) - message(${UTI_FRAMEWORK}) - set(${target}_PLATFORM_LIBS - ${${target}_PLATFORM_LIBS} - "-framework UniformTypeIdentifiers" - ) - endif() endif() ########################################################################################## @@ -180,7 +168,7 @@ else() ) add_executable(${target} ${${target}_sources}) - target_link_libraries(${target} + target_link_libraries(${target} PRIVATE ${${target}_PLATFORM_LIBS} ) @@ -200,6 +188,15 @@ else() endif(VSTGUI_USE_XCODE_XCTEST) +if(CMAKE_HOST_APPLE) + if(CMAKE_OSX_DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 11.0) + target_compile_definitions(${target} "VSTGUI_USE_OBJC_UTTYPE") + target_link_libraries(${target} PRIVATE + "-framework UniformTypeIdentifiers" + ) + endif() +endif() + #if(CMAKE_HOST_APPLE) # option(VSTGUI_ENABLE_CODECOVERAGE "Generate Code Coverage Data" OFF) # if(VSTGUI_ENABLE_CODECOVERAGE) From 43609b2e392f1193dd8fd57e62ad9baf1ff28c85 Mon Sep 17 00:00:00 2001 From: scheffle Date: Thu, 4 Aug 2022 10:10:58 +0200 Subject: [PATCH 45/51] remove deprecated macOS 10.15 github action environment --- .github/workflows/cmake_macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index e362dde4b..ee8915cd7 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: - os: [macos-10.15, macos-11, macos-12] + os: [macos-11, macos-12] steps: - uses: actions/checkout@v2 From abc14db741dec174e53f0f2fc4ceaa5de02a01c3 Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 10 Aug 2022 14:17:12 +0200 Subject: [PATCH 46/51] change error message when compiler or system is not supported fixes #263 --- vstgui/lib/vstguibase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vstgui/lib/vstguibase.h b/vstgui/lib/vstguibase.h index e17448f65..f8cd704e9 100644 --- a/vstgui/lib/vstguibase.h +++ b/vstgui/lib/vstguibase.h @@ -135,7 +135,7 @@ #endif #else - #error unsupported compiler +#error unsupported system/compiler #endif #include From 510e93f8a167617ad98c222a191609a7ff86836b Mon Sep 17 00:00:00 2001 From: Yvan Grabit Date: Thu, 11 Aug 2022 10:24:33 +0200 Subject: [PATCH 47/51] [fix] avoid to read extra characters at the end in json resource (added on Windows) --- vstgui/uidescription/detail/uijsonpersistence.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vstgui/uidescription/detail/uijsonpersistence.cpp b/vstgui/uidescription/detail/uijsonpersistence.cpp index 4a8b06cb2..0808b5829 100644 --- a/vstgui/uidescription/detail/uijsonpersistence.cpp +++ b/vstgui/uidescription/detail/uijsonpersistence.cpp @@ -406,7 +406,7 @@ SharedPointer read (IContentProvider& stream) Handler handler; rapidjson::Reader reader; - auto result = reader.Parse (streamWrapper, handler); + auto result = reader.Parse (streamWrapper, handler); if (result.IsError ()) { #if DEBUG From b1dc21ea9844b761e4181fcab79b0bfdc2316882 Mon Sep 17 00:00:00 2001 From: Yvan Grabit Date: Thu, 11 Aug 2022 10:39:48 +0200 Subject: [PATCH 48/51] [fix] remove warning --- vstgui/lib/controls/ccontrol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vstgui/lib/controls/ccontrol.cpp b/vstgui/lib/controls/ccontrol.cpp index 91999719f..d6085e0b0 100644 --- a/vstgui/lib/controls/ccontrol.cpp +++ b/vstgui/lib/controls/ccontrol.cpp @@ -311,6 +311,7 @@ CControl::CheckDefaultValueEventFuncT CControl::CheckDefaultValueEventFunc = { return CheckDefaultValueFunc (c, buttonStateFromMouseEvent (event)); } + return false; #else #if TARGET_OS_IPHONE return event.buttonState.isLeft () && event.clickCount == 2; @@ -318,7 +319,6 @@ CControl::CheckDefaultValueEventFuncT CControl::CheckDefaultValueEventFunc = return event.buttonState.isLeft () && event.modifiers.is (ModifierKey::Control); #endif // TARGET_OS_IPHONE #endif // VSTGUI_ENABLE_DEPRECATED_METHODS - return false; }; //------------------------------------------------------------------------ From 860492eced01c6f2d406911776c3502390adca87 Mon Sep 17 00:00:00 2001 From: Yvan Grabit Date: Thu, 11 Aug 2022 10:49:25 +0200 Subject: [PATCH 49/51] [typo] code styling --- vstgui/lib/controls/ccontrol.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vstgui/lib/controls/ccontrol.cpp b/vstgui/lib/controls/ccontrol.cpp index d6085e0b0..cbfab3182 100644 --- a/vstgui/lib/controls/ccontrol.cpp +++ b/vstgui/lib/controls/ccontrol.cpp @@ -298,7 +298,7 @@ CControl::CheckDefaultValueFuncT CControl::CheckDefaultValueFunc = [] (CControl* return button.isDoubleClick (); #else return (button.isLeftButton () && button.getModifierState () == kDefaultValueModifier); -#endif +#endif // TARGET_OS_IPHONE }; #endif // VSTGUI_ENABLE_DEPRECATED_METHODS @@ -359,7 +359,7 @@ int32_t CControl::mapVstKeyModifier (int32_t vstModifier) modifiers |= kControl; return modifiers; } -#endif +#endif // VSTGUI_ENABLE_DEPRECATED_METHODS //------------------------------------------------------------------------ //------------------------------------------------------------------------ From 98045ef1ec3cf79e2373065e7f6f7f027bca4b05 Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 31 Aug 2022 10:14:29 +0200 Subject: [PATCH 50/51] increase version to 4.11.1 --- vstgui/lib/vstguibase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vstgui/lib/vstguibase.h b/vstgui/lib/vstguibase.h index f8cd704e9..ce40fbbbd 100644 --- a/vstgui/lib/vstguibase.h +++ b/vstgui/lib/vstguibase.h @@ -13,7 +13,7 @@ //----------------------------------------------------------------------------- #define VSTGUI_VERSION_MAJOR 4 #define VSTGUI_VERSION_MINOR 11 -#define VSTGUI_VERSION_PATCHLEVEL 0 +#define VSTGUI_VERSION_PATCHLEVEL 1 //----------------------------------------------------------------------------- // Platform definitions From c04c4afc6989f063dba66775efbf4e77699d2603 Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 31 Aug 2022 10:24:45 +0200 Subject: [PATCH 51/51] fix building standalones with Xcode 14 --- vstgui/standalone/cmake/modules/vstgui_add_executable.cmake | 1 + vstgui/standalone/examples/standalone/resource/resources.uidesc | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/vstgui/standalone/cmake/modules/vstgui_add_executable.cmake b/vstgui/standalone/cmake/modules/vstgui_add_executable.cmake index cb4734b48..61e08e7b1 100644 --- a/vstgui/standalone/cmake/modules/vstgui_add_executable.cmake +++ b/vstgui/standalone/cmake/modules/vstgui_add_executable.cmake @@ -36,6 +36,7 @@ function(vstgui_add_executable target sources) add_executable(${target} ${sources} ${PkgInfoResource}) set_target_properties(${target} PROPERTIES MACOSX_BUNDLE TRUE + XCODE_ATTRIBUTE_GENERATE_PKGINFO_FILE NO XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT $<$:dwarf>$<$>:dwarf-with-dsym> XCODE_ATTRIBUTE_DEPLOYMENT_POSTPROCESSING $<$:NO>$<$>:YES> OUTPUT_NAME "${target}" diff --git a/vstgui/standalone/examples/standalone/resource/resources.uidesc b/vstgui/standalone/examples/standalone/resource/resources.uidesc index d83a352e2..5e7d3b019 100644 --- a/vstgui/standalone/examples/standalone/resource/resources.uidesc +++ b/vstgui/standalone/examples/standalone/resource/resources.uidesc @@ -118,7 +118,7 @@ }, "custom": { "UIDescFilePath": { - "path": "/Volumes/vst3/vstgui/vstgui/standalone/examples/standalone/resource/resources.uidesc" + "path": "/Users/scheffle/Source/vstgui/vstgui/standalone/examples/standalone/resource/resources.uidesc" } } }