From 2fa234bce63a4f180a58a830b96938e0bd4a9e66 Mon Sep 17 00:00:00 2001 From: scheffle Date: Sun, 4 Apr 2021 10:49:19 +0200 Subject: [PATCH 01/20] increase version number --- 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 03e3e8642..4e1d95331 100644 --- a/vstgui/lib/vstguibase.h +++ b/vstgui/lib/vstguibase.h @@ -12,7 +12,7 @@ // VSTGUI Version //----------------------------------------------------------------------------- #define VSTGUI_VERSION_MAJOR 4 -#define VSTGUI_VERSION_MINOR 10 +#define VSTGUI_VERSION_MINOR 11 //----------------------------------------------------------------------------- // Platform definitions From 0dbd8340e73d1ba08edaca4f64b1d0b4d9389324 Mon Sep 17 00:00:00 2001 From: scheffle Date: Sun, 4 Apr 2021 11:28:51 +0200 Subject: [PATCH 02/20] macOS: fix menu icon with scale factor != 1 --- vstgui/lib/platform/mac/cocoa/nsviewoptionmenu.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vstgui/lib/platform/mac/cocoa/nsviewoptionmenu.mm b/vstgui/lib/platform/mac/cocoa/nsviewoptionmenu.mm index 9bd9f1944..96edeb84e 100644 --- a/vstgui/lib/platform/mac/cocoa/nsviewoptionmenu.mm +++ b/vstgui/lib/platform/mac/cocoa/nsviewoptionmenu.mm @@ -140,7 +140,7 @@ static id VSTGUI_NSMenu_Init (id self, SEL _cmd, void* _menu) CGImageRef image = cgBitmap ? cgBitmap->getCGImage () : nullptr; if (image) { - NSImage* nsImage = imageFromCGImageRef (image); + NSImage* nsImage = imageFromCGImageRef (image, cgBitmap->getScaleFactor ()); if (nsImage) { [nsItem setImage:nsImage]; From fd492f0a09b6830bbc04dc4da53df4297fbde1bd Mon Sep 17 00:00:00 2001 From: scheffle Date: Mon, 5 Apr 2021 11:19:12 +0200 Subject: [PATCH 03/20] macOS: create retina compatible menu icons and drag images out of CBitmaps --- vstgui/lib/platform/mac/cocoa/cocoahelpers.h | 10 ++------ vstgui/lib/platform/mac/cocoa/cocoahelpers.mm | 23 +++++++++++++++++++ .../mac/cocoa/nsviewdraggingsession.mm | 14 +---------- vstgui/lib/platform/mac/cocoa/nsviewframe.mm | 7 ++---- .../platform/mac/cocoa/nsviewoptionmenu.mm | 15 ++++-------- 5 files changed, 32 insertions(+), 37 deletions(-) diff --git a/vstgui/lib/platform/mac/cocoa/cocoahelpers.h b/vstgui/lib/platform/mac/cocoa/cocoahelpers.h index a19072ffc..d2b76c743 100644 --- a/vstgui/lib/platform/mac/cocoa/cocoahelpers.h +++ b/vstgui/lib/platform/mac/cocoa/cocoahelpers.h @@ -7,6 +7,7 @@ #import "../../../crect.h" #import "../../../cpoint.h" #import "../../../ccolor.h" +#import "../../../vstguifwd.h" #if MAC_COCOA && defined (__OBJC__) @@ -68,6 +69,7 @@ extern HIDDEN VstKeyCode CreateVstKeyCodeFromNSEvent (NSEvent* theEvent); extern HIDDEN NSString* GetVirtualKeyCodeString (int32_t virtualKeyCode); extern HIDDEN int32_t eventButton (NSEvent* theEvent); extern HIDDEN void convertPointToGlobal (NSView* view, NSPoint& p); +extern HIDDEN NSImage* bitmapToNSImage (VSTGUI::CBitmap* bitmap); //------------------------------------------------------------------------------------ // Helpers @@ -114,14 +116,6 @@ HIDDEN inline NSColor* nsColorFromCColor (const VSTGUI::CColor& color) alpha:color.normAlpha ()]; } -//------------------------------------------------------------------------------------ -HIDDEN inline NSImage* imageFromCGImageRef (CGImageRef image, double scaleFactor = 1.) -{ - auto width = CGImageGetWidth (image) / scaleFactor; - auto height = CGImageGetHeight (image) / scaleFactor; - return [[NSImage alloc] initWithCGImage:image size:NSMakeSize (width, height)]; -} - //------------------------------------------------------------------------------------ struct MacEventModifier { diff --git a/vstgui/lib/platform/mac/cocoa/cocoahelpers.mm b/vstgui/lib/platform/mac/cocoa/cocoahelpers.mm index 48c801d5a..33752cd61 100644 --- a/vstgui/lib/platform/mac/cocoa/cocoahelpers.mm +++ b/vstgui/lib/platform/mac/cocoa/cocoahelpers.mm @@ -8,6 +8,8 @@ #include "../../../vstkeycode.h" #include "../../../cview.h" +#include "../../../cbitmap.h" +#include "../cgbitmap.h" //------------------------------------------------------------------------------------ HIDDEN Class generateUniqueClass (NSMutableString* className, Class baseClass) @@ -222,5 +224,26 @@ HIDDEN void convertPointToGlobal (NSView* view, NSPoint& p) p = r.origin; } +//----------------------------------------------------------------------------- +HIDDEN NSImage* bitmapToNSImage (CBitmap* bitmap) +{ + if (!bitmap) + return nil; + + NSImage* image = + [[NSImage alloc] initWithSize:NSMakeSize (bitmap->getWidth (), bitmap->getHeight ())]; + for (auto& platformBitmap : *bitmap) + { + if (auto cgBitmap = dynamic_cast (platformBitmap.get ())) + { + if (auto rep = [[NSBitmapImageRep alloc] initWithCGImage:cgBitmap->getCGImage ()]) + { + [image addRepresentation:rep]; + [rep release]; + } + } + } + return image; +} #endif // MAC_COCOA diff --git a/vstgui/lib/platform/mac/cocoa/nsviewdraggingsession.mm b/vstgui/lib/platform/mac/cocoa/nsviewdraggingsession.mm index 0cfd10a1c..b349598a1 100644 --- a/vstgui/lib/platform/mac/cocoa/nsviewdraggingsession.mm +++ b/vstgui/lib/platform/mac/cocoa/nsviewdraggingsession.mm @@ -259,19 +259,7 @@ void initClass () //----------------------------------------------------------------------------- NSImage* NSViewDraggingSession::nsImageForDragOperation (CBitmap* bitmap) { - if (!bitmap) - return nil; - auto platformBitmap = bitmap->getPlatformBitmap (); - if (!platformBitmap) - return nil; - auto cgBitmap = platformBitmap.cast (); - if (!cgBitmap) - return nil; - auto cgImage = cgBitmap->getCGImage (); - if (!cgImage) - return nil; - auto scaleFactor = platformBitmap->getScaleFactor (); - return [imageFromCGImageRef (cgImage, scaleFactor) autorelease]; + return bitmapToNSImage (bitmap); } //------------------------------------------------------------------------ diff --git a/vstgui/lib/platform/mac/cocoa/nsviewframe.mm b/vstgui/lib/platform/mac/cocoa/nsviewframe.mm index bd6404aa2..807d82362 100644 --- a/vstgui/lib/platform/mac/cocoa/nsviewframe.mm +++ b/vstgui/lib/platform/mac/cocoa/nsviewframe.mm @@ -1307,8 +1307,6 @@ static id VSTGUI_NSView_makeTouchbar (id self) lastDragOperationResult = kDragError; if (nsView) { - CGBitmap* cgBitmap = dragBitmap ? dynamic_cast (dragBitmap->getPlatformBitmap ().get ()) : nullptr; - CGImageRef cgImage = cgBitmap ? cgBitmap->getCGImage () : nullptr; NSPoint bitmapOffset = { static_cast(offset.x), static_cast(offset.y) }; NSEvent* event = [NSApp currentEvent]; @@ -1316,10 +1314,9 @@ static id VSTGUI_NSView_makeTouchbar (id self) [event type] == MacEventType::LeftMouseDragged)) return kDragRefused; NSPoint nsLocation = [event locationInWindow]; - NSImage* nsImage = nil; - if (cgImage) + NSImage* nsImage = bitmapToNSImage (dragBitmap); + if (nsImage) { - nsImage = [imageFromCGImageRef (cgImage) autorelease]; nsLocation = [nsView convertPoint:nsLocation fromView:nil]; bitmapOffset.x += nsLocation.x; bitmapOffset.y += nsLocation.y + [nsImage size].height; diff --git a/vstgui/lib/platform/mac/cocoa/nsviewoptionmenu.mm b/vstgui/lib/platform/mac/cocoa/nsviewoptionmenu.mm index 96edeb84e..cae35d8b9 100644 --- a/vstgui/lib/platform/mac/cocoa/nsviewoptionmenu.mm +++ b/vstgui/lib/platform/mac/cocoa/nsviewoptionmenu.mm @@ -133,19 +133,12 @@ static id VSTGUI_NSMenu_Init (id self, SEL _cmd, void* _menu) [nsItem setKeyEquivalentModifierMask:keyModifiers]; } } - if (nsItem && item->getIcon ()) + if (nsItem) { - IPlatformBitmap* platformBitmap = item->getIcon ()->getPlatformBitmap (); - CGBitmap* cgBitmap = platformBitmap ? dynamic_cast (platformBitmap) : nullptr; - CGImageRef image = cgBitmap ? cgBitmap->getCGImage () : nullptr; - if (image) + if (auto nsImage = bitmapToNSImage (item->getIcon ())) { - NSImage* nsImage = imageFromCGImageRef (image, cgBitmap->getScaleFactor ()); - if (nsImage) - { - [nsItem setImage:nsImage]; - [nsImage release]; - } + [nsItem setImage:nsImage]; + [nsImage release]; } } } From c540959f6f6615e694b0cca908b4680afd578a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Hansen?= Date: Thu, 6 May 2021 09:00:54 +0200 Subject: [PATCH 04/20] Round segmentIndex properly. --- vstgui/lib/controls/csegmentbutton.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vstgui/lib/controls/csegmentbutton.cpp b/vstgui/lib/controls/csegmentbutton.cpp index 4058167ed..5ab13f873 100644 --- a/vstgui/lib/controls/csegmentbutton.cpp +++ b/vstgui/lib/controls/csegmentbutton.cpp @@ -517,7 +517,10 @@ uint32_t CSegmentButton::getSegmentIndex (float value) const { if (value < 0.f || value > 1.f) return kPushBack; - return static_cast (static_cast (segments.size () - 1) * value); + + const auto segmentIndex = static_cast (segments.size () - 1) * value; + const auto segmentIndexRounded = static_cast (segmentIndex + 0.5f); + return segmentIndexRounded; } //----------------------------------------------------------------------------- From 23be3e796efbf8320c39084d1d83c1155d26bb0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Hansen?= Date: Fri, 7 May 2021 11:32:09 +0200 Subject: [PATCH 05/20] Add unit test for segment button with many segments (catch rounding errors). --- .../lib/controls/csegmentbutton_test.cpp | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/vstgui/tests/unittest/lib/controls/csegmentbutton_test.cpp b/vstgui/tests/unittest/lib/controls/csegmentbutton_test.cpp index 74a948d57..a171a3705 100644 --- a/vstgui/tests/unittest/lib/controls/csegmentbutton_test.cpp +++ b/vstgui/tests/unittest/lib/controls/csegmentbutton_test.cpp @@ -302,6 +302,32 @@ TESTCASE(CSegmentButtonTest, parent->removed (root); ); + + TEST(mouseDownEventWithManySegments, + // Create segment button with 32 segments and attach it + const auto numSegments = 32; + CRect r (0, 0, 20 * numSegments, 100); + auto b = new CSegmentButton (r); + b->setStyle (CSegmentButton::Style::kHorizontal); + for (auto i = 0; i < numSegments; ++i) + b->addSegment ({}); + for (const auto& s : b->getSegments()) + EXPECT (s.rect == CRect (0, 0, 0, 0)); + auto root = owned (new CViewContainer (r)); + auto parent = new CViewContainer (r); + root->addView (parent); + parent->addView (b); + parent->attached (root); + + // Select the e.g. 20th segment + constexpr auto kSelectedSegment = 20; + CPoint p (0, 0); + p (20 * kSelectedSegment + 5, 0); + EXPECT (b->onMouseDown (p, kLButton) == kMouseDownEventHandledButDontNeedMovedOrUpEvents); + EXPECT (b->getSelectedSegment () == kSelectedSegment); + + parent->removed (root); + ); TEST(focusPathSetting, CSegmentButton b (CRect (0, 0, 10, 10)); From 66087d85ca0a03cf8802f4bd1f6a312c46dca5e3 Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 12 May 2021 22:06:32 +0200 Subject: [PATCH 06/20] Testing (#202) * move test main function to its own file * integrate unit tests into Xcode UI * add missing includes --- vstgui/tests/unittest/CMakeLists.txt | 108 +++++++---- .../lib/controls/ctextbutton_test.cpp | 2 +- vstgui/tests/unittest/lib/crect_test.cpp | 2 +- .../unittest/lib/cviewcontainer_test.cpp | 1 + .../unittest/lib/utf8stringview_test.cpp | 10 +- .../uiviewcreator/ccheckboxcreator_test.cpp | 2 +- .../uiviewcreator/ctexteditcreator_test.cpp | 4 +- .../uiviewcreator/stringlistcreator_test.cpp | 2 +- vstgui/tests/unittest/unittestmain.cpp | 176 ++++++++++++++++++ vstgui/tests/unittest/unittests.cpp | 144 -------------- vstgui/tests/unittest/unittests.h | 10 +- vstgui/tests/unittest/xcodetestintegration.mm | 157 ++++++++++++++++ 12 files changed, 421 insertions(+), 197 deletions(-) create mode 100644 vstgui/tests/unittest/unittestmain.cpp create mode 100644 vstgui/tests/unittest/xcodetestintegration.mm diff --git a/vstgui/tests/unittest/CMakeLists.txt b/vstgui/tests/unittest/CMakeLists.txt index 159f6b7c7..0e7ea5f39 100644 --- a/vstgui/tests/unittest/CMakeLists.txt +++ b/vstgui/tests/unittest/CMakeLists.txt @@ -125,45 +125,77 @@ if(UNIX AND NOT CMAKE_HOST_APPLE) endif() ########################################################################################## -#include_directories(../) -add_executable(${target} ${${target}_sources}) -target_link_libraries(${target} - ${${target}_PLATFORM_LIBS} -) -vstgui_set_cxx_version(${target} 14) -target_compile_definitions(${target} ${VSTGUI_COMPILE_DEFINITIONS} ENABLE_UNIT_TESTS=1 VSTGUI_LIVE_EDITING=1) -vstgui_source_group_by_folder(${target}) +if(XCODE) + set(${target}_sources + "${${target}_sources}" + "${VSTGUI_TEST_BASE}xcodetestintegration.mm" + ) -add_custom_command(TARGET ${target} POST_BUILD COMMAND "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittests") + add_library(${target} MODULE ${${target}_sources}) + vstgui_set_cxx_version(${target} 14) + target_compile_definitions(${target} ${VSTGUI_COMPILE_DEFINITIONS} ENABLE_UNIT_TESTS=1 VSTGUI_LIVE_EDITING=1) + target_link_libraries(${target} + ${${target}_PLATFORM_LIBS} + "-framework XCTest" + ) -########################################################################################## -if(UNIX AND NOT CMAKE_HOST_APPLE) - target_include_directories(${target} PRIVATE ${X11_INCLUDE_DIR}) - target_include_directories(${target} PRIVATE ${GTK3_INCLUDE_DIRS}) - target_include_directories(${target} PRIVATE ${GTKMM3_INCLUDE_DIRS}) - target_include_directories(${target} PRIVATE ${FREETYPE_INCLUDE_DIRS}) -endif() + set_target_properties(${target} + PROPERTIES + BUNDLE TRUE + XCODE_ATTRIBUTE_GENERATE_PKGINFO_FILE YES + XCODE_ATTRIBUTE_WRAPPER_EXTENSION xctest + XCODE_ATTRIBUTE_ENABLE_TESTABILITY YES + ) -if(CMAKE_HOST_APPLE) - option(VSTGUI_ENABLE_CODECOVERAGE "Generate Code Coverage Data" OFF) - if(VSTGUI_ENABLE_CODECOVERAGE) - add_executable(codecoverage ${${target}_sources}) - - set(target codecoverage) - - target_link_libraries(${target} - "-framework Cocoa" - "-framework OpenGL" - "-framework QuartzCore" - "-framework Accelerate" - "--coverage" - ) - - vstgui_set_cxx_version(${target} 14) - target_compile_definitions(${target} ${VSTGUI_COMPILE_DEFINITIONS} ENABLE_UNIT_TESTS=1 VSTGUI_LIVE_EDITING=1 VSTGUI_ENABLE_DEPRECATED_METHODS=0) - vstgui_source_group_by_folder(${target}) - target_compile_options(${target} PUBLIC "--coverage") - add_custom_command(TARGET ${target} POST_BUILD COMMAND "/usr/bin/ruby" "${CMAKE_CURRENT_SOURCE_DIR}/lcov/generate.rb" "${PROJECT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/vstgui.build/Debug/codecoverage.build/Objects-normal/x86_64" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${target}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/coverage_output" VERBATIM) - endif() -endif() + vstgui_source_group_by_folder(${target}) + +else() + set(${target}_sources + ${${target}_sources} + "${VSTGUI_TEST_BASE}unittestmain.cpp" + ) + + add_executable(${target} ${${target}_sources}) + target_link_libraries(${target} + ${${target}_PLATFORM_LIBS} + ) + + vstgui_set_cxx_version(${target} 14) + target_compile_definitions(${target} ${VSTGUI_COMPILE_DEFINITIONS} ENABLE_UNIT_TESTS=1 VSTGUI_LIVE_EDITING=1) + vstgui_source_group_by_folder(${target}) + + add_custom_command(TARGET ${target} POST_BUILD COMMAND "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittests") + + ########################################################################################## + if(UNIX AND NOT CMAKE_HOST_APPLE) + target_include_directories(${target} PRIVATE ${X11_INCLUDE_DIR}) + target_include_directories(${target} PRIVATE ${GTK3_INCLUDE_DIRS}) + target_include_directories(${target} PRIVATE ${GTKMM3_INCLUDE_DIRS}) + target_include_directories(${target} PRIVATE ${FREETYPE_INCLUDE_DIRS}) + endif() + +endif(XCODE) + +#if(CMAKE_HOST_APPLE) +# option(VSTGUI_ENABLE_CODECOVERAGE "Generate Code Coverage Data" OFF) +# if(VSTGUI_ENABLE_CODECOVERAGE) +# add_executable(codecoverage ${${target}_sources}) +# +# set(target codecoverage) +# +# target_link_libraries(${target} +# "-framework Cocoa" +# "-framework OpenGL" +# "-framework QuartzCore" +# "-framework Accelerate" +# "--coverage" +# ) +# +# vstgui_set_cxx_version(${target} 14) +# target_compile_definitions(${target} ${VSTGUI_COMPILE_DEFINITIONS} ENABLE_UNIT_TESTS=1 VSTGUI_LIVE_EDITING=1 VSTGUI_ENABLE_DEPRECATED_METHODS=0) +# vstgui_source_group_by_folder(${target}) +# target_compile_options(${target} PUBLIC "--coverage") +# add_custom_command(TARGET ${target} POST_BUILD COMMAND "/usr/bin/ruby" "${CMAKE_CURRENT_SOURCE_DIR}/lcov/generate.rb" "${PROJECT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/vstgui.build/Debug/codecoverage.build/Objects-normal/x86_64" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${target}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/coverage_output" VERBATIM) +# endif() +#endif() diff --git a/vstgui/tests/unittest/lib/controls/ctextbutton_test.cpp b/vstgui/tests/unittest/lib/controls/ctextbutton_test.cpp index 97c0eb248..528e6052c 100644 --- a/vstgui/tests/unittest/lib/controls/ctextbutton_test.cpp +++ b/vstgui/tests/unittest/lib/controls/ctextbutton_test.cpp @@ -7,7 +7,7 @@ namespace VSTGUI { -TESTCASE(CCheckboxTest, +TESTCASE(CTextButtonTest, TEST(mouseEventsKickStyle, auto b = owned (new CTextButton (CRect (10, 10, 50, 20))); diff --git a/vstgui/tests/unittest/lib/crect_test.cpp b/vstgui/tests/unittest/lib/crect_test.cpp index 9a81a7891..fabf2c036 100644 --- a/vstgui/tests/unittest/lib/crect_test.cpp +++ b/vstgui/tests/unittest/lib/crect_test.cpp @@ -91,7 +91,7 @@ TESTCASE(CRectTest, EXPECT(r.getWidth () == 100.); ); - TEST(setWidth, + TEST(setHeight, CRect r (0., 0., 0., 0.); EXPECT(r.getHeight () == 0.); r.setHeight (100.); diff --git a/vstgui/tests/unittest/lib/cviewcontainer_test.cpp b/vstgui/tests/unittest/lib/cviewcontainer_test.cpp index 6162543e5..4a3e3ee98 100644 --- a/vstgui/tests/unittest/lib/cviewcontainer_test.cpp +++ b/vstgui/tests/unittest/lib/cviewcontainer_test.cpp @@ -143,6 +143,7 @@ TESTCASE(CViewContainerTest, ); TEST(addView, + assert (container); CView* view = new CView (CRect (0, 0, 10, 10)); CView* view2 = new CView (CRect (0, 0, 10, 10)); diff --git a/vstgui/tests/unittest/lib/utf8stringview_test.cpp b/vstgui/tests/unittest/lib/utf8stringview_test.cpp index dbc37284c..fcb8c0673 100644 --- a/vstgui/tests/unittest/lib/utf8stringview_test.cpp +++ b/vstgui/tests/unittest/lib/utf8stringview_test.cpp @@ -41,7 +41,8 @@ TESTCASE ( EXPECT(str.calculateByteCount () == 46); ); - TEST(contains, UTF8StringView str (asciiStr); + TEST(contains, + UTF8StringView str (asciiStr); EXPECT(str.contains ("simple") == true); EXPECT(str.contains ("not") == false); ); @@ -74,7 +75,7 @@ TESTCASE ( EXPECT(str1 != str3); ); - TEST(contains, + TEST(containsCheckCase, UTF8StringView str (asciiStr); EXPECT(str.contains ("simple")); EXPECT(str.contains ("Simple") == false); @@ -86,11 +87,6 @@ TESTCASE ( EXPECT(str.startsWith ("This")); ); - TEST(endsWith, - UTF8StringView str (asciiStr); - EXPECT(str.endsWith ("String")); - ); - TEST(toDouble, UTF8StringView str ("5.1"); EXPECT(str.toDouble () == 5.1); diff --git a/vstgui/tests/unittest/uidescription/uiviewcreator/ccheckboxcreator_test.cpp b/vstgui/tests/unittest/uidescription/uiviewcreator/ccheckboxcreator_test.cpp index d98a4d4dd..9751825b2 100644 --- a/vstgui/tests/unittest/uidescription/uiviewcreator/ccheckboxcreator_test.cpp +++ b/vstgui/tests/unittest/uidescription/uiviewcreator/ccheckboxcreator_test.cpp @@ -13,7 +13,7 @@ namespace VSTGUI { using namespace UIViewCreator; -TESTCASE(COnOffButtonCreatorTest, +TESTCASE(CCheckBoxCreatorTest, TEST(title, DummyUIDescription uidesc; diff --git a/vstgui/tests/unittest/uidescription/uiviewcreator/ctexteditcreator_test.cpp b/vstgui/tests/unittest/uidescription/uiviewcreator/ctexteditcreator_test.cpp index d17c4e1b7..0dd4f1e4b 100644 --- a/vstgui/tests/unittest/uidescription/uiviewcreator/ctexteditcreator_test.cpp +++ b/vstgui/tests/unittest/uidescription/uiviewcreator/ctexteditcreator_test.cpp @@ -29,14 +29,14 @@ TESTCASE(CTextEditCreatorTest, }); ); - TEST(autoSizeToFit, + TEST(secureStyle, DummyUIDescription uidesc; testAttribute (kCTextEdit, kAttrSecureStyle, true, &uidesc, [&] (CTextEdit* v) { return v->getSecureStyle () == true; }); ); - TEST(autoSizeToFit, + TEST(placeholderTitle, DummyUIDescription uidesc; auto testValue = "This is a placeholder"; testAttribute (kCTextEdit, kAttrPlaceholderTitle, testValue, &uidesc, [&] (CTextEdit* b) { diff --git a/vstgui/tests/unittest/uidescription/uiviewcreator/stringlistcreator_test.cpp b/vstgui/tests/unittest/uidescription/uiviewcreator/stringlistcreator_test.cpp index 2321d4c64..ed50817b9 100644 --- a/vstgui/tests/unittest/uidescription/uiviewcreator/stringlistcreator_test.cpp +++ b/vstgui/tests/unittest/uidescription/uiviewcreator/stringlistcreator_test.cpp @@ -114,7 +114,7 @@ TESTCASE(StringListControlCreatorTest, }); ); - TEST(lineWidth, + TEST(textInset, DummyUIDescription uidesc; testAttribute(kCStringListControl, kAttrTextInset, 14., &uidesc, [&] (CListControl* v) { return getDrawer (v)->getTextInset () == 14.; diff --git a/vstgui/tests/unittest/unittestmain.cpp b/vstgui/tests/unittest/unittestmain.cpp new file mode 100644 index 000000000..659f1328a --- /dev/null +++ b/vstgui/tests/unittest/unittestmain.cpp @@ -0,0 +1,176 @@ +// This file is part of VSTGUI. It is subject to the license terms +// in the LICENSE file found in the top-level directory of this +// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE + +#include "unittests.h" + +#if ENABLE_UNIT_TESTS +#include "../../lib/vstguidebug.h" +#include "../../lib/vstguiinit.h" + +#include +#include +#include + +#if MAC +#include +#endif + +#if WINDOWS +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#include +#endif + +//------------------------------------------------------------------------ +namespace VSTGUI { +namespace UnitTest { + +using namespace std::chrono; + +//---------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------- +class StdOutContext : public Context +{ +private: + struct Result { + int succeded; + int failed; + + Result () : succeded (0), failed (0) {} + + Result& operator +=(const Result& r) { succeded += r.succeded; failed += r.failed; return *this; } + }; +public: + StdOutContext () : intend (0) {} + + void printRaw (const char* str) override + { + testOutput += str; + testOutput += "\n"; + } + + void printOutput () + { + if (testOutput.empty () == false) + { + printf ("%s", testOutput.c_str ()); + testOutput = ""; + } + } + void printIntend () + { + for (int i = 0; i < intend; i++) printf ("\t"); + } + + Result runTestCase (const TestCase& testCase) + { + Result result; + printf ("%s\n", testCase.getName ().c_str()); + intend++; + for (auto& it : testCase) + { + try { + if (testCase.setup ()) + { + testCase.setup () (this); + } + if (runTest (it.first, it.second)) + { + result.succeded++; + } + else + { + result.failed++; + } + if (testCase.teardown ()) + { + testCase.teardown () (this); + } + } catch (const std::exception&) + { + result.failed++; + } + } + intend--; + return result; + } + + bool runTest (const std::string& testName, const TestFunction& f) + { + time_point start, end; + printIntend (); + printf ("%s", testName.c_str()); + intend++; + start = system_clock::now (); + bool result; + try { + result = f (this); + } catch (const error& exc) + { + result = false; + print ("%s", exc.what () ? exc.what () : "unknown"); + } catch (const std::exception& exc) + { + result = false; + printf ("Exception: %s", exc.what () ? exc.what () : "unknown"); + } + end = system_clock::now (); + intend--; + printf (" [%s] -> %lld µs\n", result ? "OK" : "Failed", duration_cast (end-start).count ()); + printOutput (); + return result; + } + + int run () + { + Result result; + time_point start, end; + start = system_clock::now (); + for (auto& it : UnitTestRegistry::instance ()) + { + result += runTestCase (std::move (it)); + } + end = system_clock::now (); + print ("\nDone running %d tests in %lldms. [%d Failed]\n", result.succeded+result.failed, duration_cast (end-start).count (), result.failed); + printOutput (); + return result.failed; + } +private: + int intend; + std::string testOutput; +}; + +static int RunTests () +{ + StdOutContext context; + return context.run (); +} + +//------------------------------------------------------------------------ +} // UnitTest +} // VSTGUI + +int main () +{ + VSTGUI::setAssertionHandler ([] (const char* file, const char* line, const char* desc) { + throw std::logic_error (desc ? desc : "unknown"); + }); +#if MAC + VSTGUI::init (CFBundleGetMainBundle ()); +#elif WINDOWS + CoInitialize (nullptr); + VSTGUI::init (GetModuleHandle (nullptr)); +#elif LINUX + VSTGUI::init (nullptr); +#endif + auto result = VSTGUI::UnitTest::RunTests (); + VSTGUI::exit (); + return result; +} + +#endif + diff --git a/vstgui/tests/unittest/unittests.cpp b/vstgui/tests/unittest/unittests.cpp index 774010b0e..ba0dcef0b 100644 --- a/vstgui/tests/unittest/unittests.cpp +++ b/vstgui/tests/unittest/unittests.cpp @@ -8,10 +8,6 @@ #include "../../lib/vstguidebug.h" #include "../../lib/vstguiinit.h" -#if MAC -#include -#endif - #include #include #include @@ -133,148 +129,8 @@ void Context::print (const char* fmt, ...) #endif } -using namespace std::chrono; - -//---------------------------------------------------------------------------------------------------- -//---------------------------------------------------------------------------------------------------- -//---------------------------------------------------------------------------------------------------- -class StdOutContext : public Context -{ -private: - struct Result { - int succeded; - int failed; - - Result () : succeded (0), failed (0) {} - - Result& operator +=(const Result& r) { succeded += r.succeded; failed += r.failed; return *this; } - }; -public: - StdOutContext () : intend (0) {} - - void printRaw (const char* str) override - { - testOutput += str; - testOutput += "\n"; - } - - void printOutput () - { - if (testOutput.empty () == false) - { - printf ("%s", testOutput.c_str ()); - testOutput = ""; - } - } - void printIntend () - { - for (int i = 0; i < intend; i++) printf ("\t"); - } - - Result runTestCase (const TestCase& testCase) - { - Result result; - printf ("%s\n", testCase.getName ().c_str()); - intend++; - for (auto& it : testCase) - { - try { - if (testCase.setup ()) - { - testCase.setup () (this); - } - if (runTest (it.first, it.second)) - { - result.succeded++; - } - else - { - result.failed++; - } - if (testCase.teardown ()) - { - testCase.teardown () (this); - } - } catch (const std::exception&) - { - result.failed++; - } - } - intend--; - return result; - } - - bool runTest (const std::string& testName, const TestFunction& f) - { - time_point start, end; - printIntend (); - printf ("%s", testName.c_str()); - intend++; - start = system_clock::now (); - bool result; - try { - result = f (this); - } catch (const error& exc) - { - result = false; - print ("%s", exc.what () ? exc.what () : "unknown"); - } catch (const std::exception& exc) - { - result = false; - printf ("Exception: %s", exc.what () ? exc.what () : "unknown"); - } - end = system_clock::now (); - intend--; - printf (" [%s] -> %lld µs\n", result ? "OK" : "Failed", duration_cast (end-start).count ()); - printOutput (); - return result; - } - - int run () - { - Result result; - time_point start, end; - start = system_clock::now (); - for (auto& it : UnitTestRegistry::instance ()) - { - result += runTestCase (std::move (it)); - } - end = system_clock::now (); - print ("\nDone running %d tests in %lldms. [%d Failed]\n", result.succeded+result.failed, duration_cast (end-start).count (), result.failed); - printOutput (); - return result.failed; - } -private: - int intend; - std::string testOutput; -}; - -static int RunTests () -{ - StdOutContext context; - return context.run (); -} - }} // namespaces -int main () -{ - VSTGUI::setAssertionHandler ([] (const char* file, const char* line, const char* desc) { - throw std::logic_error (desc ? desc : "unknown"); - }); -#if MAC - VSTGUI::init (CFBundleGetMainBundle ()); -#elif WINDOWS - CoInitialize (nullptr); - VSTGUI::init (GetModuleHandle (nullptr)); -#elif LINUX - VSTGUI::init (nullptr); -#endif - auto result = VSTGUI::UnitTest::RunTests (); - VSTGUI::exit (); - return result; -} - TESTCASE(Example, static int result; diff --git a/vstgui/tests/unittest/unittests.h b/vstgui/tests/unittest/unittests.h index b547e973f..5b399b4b0 100644 --- a/vstgui/tests/unittest/unittests.h +++ b/vstgui/tests/unittest/unittests.h @@ -61,7 +61,13 @@ namespace UnitTest { class error : public std::logic_error { public: - error (const char* str) : std::logic_error (str) {} + error (const char* file, size_t line, const char* str) + : std::logic_error (str), filePath (file), lineNo (line) + { + } + + std::string filePath; + size_t lineNo; }; #define VSTGUI_UNITTEST_MAKE_STRING_PRIVATE_DONT_USE(x) # x @@ -70,7 +76,7 @@ class error : public std::logic_error //---------------------------------------------------------------------------------------------------- #define TESTCASE(name,function) static VSTGUI::UnitTest::TestCaseRegistrar name##TestCaseRegistrar (VSTGUI_UNITTEST_MAKE_STRING(name), [](VSTGUI::UnitTest::TestCase* testCase) { function }) #define TEST(name,function) testCase->registerTest (VSTGUI_UNITTEST_MAKE_STRING(name), [](VSTGUI::UnitTest::Context* context) { { function } return true; }); -#define EXPECT(condition) if (!(condition)) { throw VSTGUI::UnitTest::error (__FILE__ ":" VSTGUI_UNITTEST_MAKE_STRING(__LINE__) ": Expected: " VSTGUI_UNITTEST_MAKE_STRING(condition)); } +#define EXPECT(condition) if (!(condition)) { throw VSTGUI::UnitTest::error (__FILE__, __LINE__, "Expected: " VSTGUI_UNITTEST_MAKE_STRING(condition)); } #define FAIL(reason) { context->print (__FILE__ ":" VSTGUI_UNITTEST_MAKE_STRING(__LINE__) ": Failure: " reason); return false; } #define EXPECT_EXCEPTION(call, name) \ diff --git a/vstgui/tests/unittest/xcodetestintegration.mm b/vstgui/tests/unittest/xcodetestintegration.mm new file mode 100644 index 000000000..99388f8b8 --- /dev/null +++ b/vstgui/tests/unittest/xcodetestintegration.mm @@ -0,0 +1,157 @@ +// 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 + +#import +#import +#import + +#import "../../lib/cstring.h" +#import "../../lib/vstguiinit.h" +#import "unittests.h" + +#import +#import +#import +#import + +using namespace VSTGUI::UnitTest; + +static std::string currentFile; +static std::string currentLineNo; + +//------------------------------------------------------------------------ +void setupFunc (id self, SEL _cmd) +{ + auto cls = [self class]; + std::string clsName (class_getName (cls) + 7); + auto it = + std::find_if (UnitTestRegistry::instance ().begin (), UnitTestRegistry::instance ().end (), + [&] (auto& testCase) { return testCase.getName () == clsName; }); + assert (it != UnitTestRegistry::instance ().end ()); + auto ivar = class_getInstanceVariable ([self class], "_testCase"); + object_setIvar (self, ivar, reinterpret_cast (&(*it))); +} + +//------------------------------------------------------------------------ +void testFunc (id self, SEL _cmd) +{ + auto ivar = class_getInstanceVariable ([self class], "_testCase"); + auto testCase = reinterpret_cast (object_getIvar (self, ivar)); + auto name = std::string (sel_getName (_cmd) + 4); + auto it = std::find_if (testCase->begin (), testCase->end (), + [&] (auto& pair) { return pair.first == name; }); + if (it == testCase->end ()) + { + + return; + } + struct TestContext : Context + { + void printRaw (const char* str) override { text += str; } + std::string text; + } context; + + if (auto setup = testCase->setup ()) + setup (&context); + + XCTSourceCodeLocation* sourceCodeLocation = nullptr; + bool result; + try + { + result = it->second (&context); + } + catch (const error& exc) + { + result = false; + context.print ("%s", exc.what () ? exc.what () : "unknown"); + sourceCodeLocation = [[[XCTSourceCodeLocation alloc] + initWithFilePath:[NSString stringWithUTF8String:exc.filePath.data ()] + lineNumber:exc.lineNo] autorelease]; + } + catch (const std::logic_error& exc) + { + result = false; + context.print ("%s", exc.what () ? exc.what () : "unknown"); + } + catch (const std::exception& exc) + { + result = false; + context.print ("Exception: %s", exc.what () ? exc.what () : "unknown"); + } + if (!result) + { + if (!sourceCodeLocation) + { + auto lineNo = VSTGUI::UTF8StringView (currentLineNo.data ()).toInteger (); + sourceCodeLocation = [[[XCTSourceCodeLocation alloc] + initWithFilePath:[NSString stringWithUTF8String:currentFile.data ()] + lineNumber:lineNo] autorelease]; + } + auto sourceCodeContext = + [[[XCTSourceCodeContext alloc] initWithLocation:sourceCodeLocation] autorelease]; + auto issue = + [[[XCTIssue alloc] initWithType:XCTIssueTypeAssertionFailure + compactDescription:[NSString stringWithUTF8String:context.text.data ()] + detailedDescription:nullptr + sourceCodeContext:sourceCodeContext + associatedError:nullptr + attachments:@[]] autorelease]; + + [self recordIssue:issue]; + } + + if (auto teardown = testCase->teardown ()) + teardown (&context); +} + +//------------------------------------------------------------------------ +@interface VSTGUITestCaseFactory : XCTestCase +@end + +@implementation VSTGUITestCaseFactory + +//------------------------------------------------------------------------ ++ (void)initialize +{ + VSTGUI::init (CFBundleGetMainBundle ()); + VSTGUI::setAssertionHandler ([] (const char* file, const char* line, const char* desc) { + if (desc) + throw std::logic_error (desc); + currentFile = file; + currentLineNo = line; + std::string text = "assert: "; + text += file; + text += ":"; + text += line; + throw std::logic_error (text.data ()); + }); + + auto baseClass = objc_getClass ("XCTestCase"); + for (auto& testCase : UnitTestRegistry::instance ()) + { + std::string className = "VSTGUI_" + testCase.getName (); + auto cls = objc_allocateClassPair (baseClass, className.data (), 0); + if (!cls) + { + NSLog (@"Duplicate TestCase name: %s", testCase.getName ().data ()); + continue; + } + class_addIvar (cls, "_testCase", sizeof (void*), (uint8_t)log2 (sizeof (void*)), + @encode (void*)); + class_addMethod (cls, @selector (setUp), reinterpret_cast (setupFunc), "v@:"); + for (auto& test : testCase) + { + std::string name = "test" + test.first; + name[4] = toupper(name[4]); + auto sel = sel_registerName (name.data ()); + if (!class_addMethod (cls, sel, reinterpret_cast (testFunc), "v@:")) + { + NSLog (@"Duplicate Method name: %s [%s]", name.data (), className.data ()); + } + } + objc_registerClassPair (cls); + } +} + +@end From 8ca18a162e217c104e2ffd3d2c9ab456a8d0913f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Hansen?= Date: Mon, 24 May 2021 12:03:26 +0200 Subject: [PATCH 07/20] Return an empty string, when string list is empty (#204) --- vstgui/tests/unittest/uidescription/uiattributes_test.cpp | 5 +++++ vstgui/uidescription/uiattributes.cpp | 3 +++ 2 files changed, 8 insertions(+) diff --git a/vstgui/tests/unittest/uidescription/uiattributes_test.cpp b/vstgui/tests/unittest/uidescription/uiattributes_test.cpp index f885f9d11..a4085d102 100644 --- a/vstgui/tests/unittest/uidescription/uiattributes_test.cpp +++ b/vstgui/tests/unittest/uidescription/uiattributes_test.cpp @@ -191,6 +191,11 @@ TESTCASE(UIAttributesTest, EXPECT(UIAttributes::stringToRect ("0, 12.5, 5, 8", r) && r == CRect (0, 12.5, 5, 8)) ) + TEST(stringArrayToString_emptyStringArray, + const UIAttributes::StringArray strings; + const auto s = UIAttributes::stringArrayToString(strings); + EXPECT(s.empty()) + ) ); } // VSTGUI diff --git a/vstgui/uidescription/uiattributes.cpp b/vstgui/uidescription/uiattributes.cpp index 28267f960..35201d2ea 100644 --- a/vstgui/uidescription/uiattributes.cpp +++ b/vstgui/uidescription/uiattributes.cpp @@ -196,6 +196,9 @@ bool UIAttributes::stringToRect (const std::string& str, CRect& r) //----------------------------------------------------------------------------- std::string UIAttributes::stringArrayToString (const StringArray& values) { + if (values.empty()) + return {}; + std::string value; size_t numValues = values.size (); for (size_t i = 0; i < numValues - 1; i++) From b1c016dc6fb68dff0a3a32c4bdad0f4638cd5a0f Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Tue, 25 May 2021 17:42:53 +0200 Subject: [PATCH 08/20] Fix the build with gcc 11 (#203) --- vstgui/lib/vstguifwd.h | 1 + 1 file changed, 1 insertion(+) diff --git a/vstgui/lib/vstguifwd.h b/vstgui/lib/vstguifwd.h index 3aff5f203..9d5250879 100644 --- a/vstgui/lib/vstguifwd.h +++ b/vstgui/lib/vstguifwd.h @@ -6,6 +6,7 @@ #include "vstguibase.h" #include +#include #include namespace VSTGUI { From ef9f7cd59903ca52e89e925a34a2e06e4fa42e4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Hansen?= Date: Wed, 2 Jun 2021 20:09:47 +0200 Subject: [PATCH 09/20] Fix segment button not being updated on parameter change from host. --- vstgui/plugin-bindings/vst3editor.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vstgui/plugin-bindings/vst3editor.cpp b/vstgui/plugin-bindings/vst3editor.cpp index ca3740d86..e3fc3daf9 100644 --- a/vstgui/plugin-bindings/vst3editor.cpp +++ b/vstgui/plugin-bindings/vst3editor.cpp @@ -317,7 +317,11 @@ class ParameterChangeListener : public Steinberg::FObject c->setValue ((float)value - minValue); } else + { c->setValue ((float)value); + if (c->isDirty ()) + c->valueChanged (); + } } else c->setValueNormalized ((float)value); From 751b3a18d42957a2761d2f133e9709c7be3353c6 Mon Sep 17 00:00:00 2001 From: scheffle Date: Thu, 13 May 2021 11:45:27 +0200 Subject: [PATCH 10/20] fix indexOf algo --- vstgui/lib/algorithm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vstgui/lib/algorithm.h b/vstgui/lib/algorithm.h index 5b206ae80..bda8820a3 100644 --- a/vstgui/lib/algorithm.h +++ b/vstgui/lib/algorithm.h @@ -16,7 +16,7 @@ template Optional indexOf (Iter first, Iter last, const Type& value) { auto it = std::find (first, last, value); - if (first == last) + if (it == last) return {}; return {static_cast (std::distance (first, it))}; } From 943fe18a5d6d167e60de9201b2f602b1d1eb54bb Mon Sep 17 00:00:00 2001 From: scheffle Date: Sun, 2 May 2021 11:55:20 +0200 Subject: [PATCH 11/20] add macro to conditionally compile for newer vstgui versions --- vstgui/lib/vstguibase.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vstgui/lib/vstguibase.h b/vstgui/lib/vstguibase.h index 4e1d95331..743092639 100644 --- a/vstgui/lib/vstguibase.h +++ b/vstgui/lib/vstguibase.h @@ -543,6 +543,12 @@ struct BitScopeToggleT B bit; }; +//----------------------------------------------------------------------------- +#define VSTGUI_NEWER_THAN(major, minor) \ + (VSTGUI_VERSION > major || VSTGUI_VERSION_MAJOR == major && VSTGUI_VERSION_MINOR > minor) + +#define VSTGUI_NEWER_THAN_4_10 VSTGUI_NEWER_THAN (4, 10) + } // VSTGUI //----------------------------------------------------------------------------- From d4c20289c49cb2aba64264d41998091f6651c02d Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 9 Jun 2021 16:21:44 +0200 Subject: [PATCH 12/20] fix wrong clip rect calculation on linux The correctly transformed clip rect is already in the current state. Applying the current transform may add other transforms that were set after the clip was set. --- vstgui/lib/platform/linux/cairocontext.cpp | 11 +++++++---- vstgui/lib/platform/linux/cairocontext.h | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/vstgui/lib/platform/linux/cairocontext.cpp b/vstgui/lib/platform/linux/cairocontext.cpp index 69330bdec..0bf8cd828 100644 --- a/vstgui/lib/platform/linux/cairocontext.cpp +++ b/vstgui/lib/platform/linux/cairocontext.cpp @@ -56,10 +56,7 @@ inline bool needPixelAlignment (CDrawMode mode) DrawBlock::DrawBlock (Context& context) : context (context) { auto ct = context.getCurrentTransform (); - CRect clip; - context.getClipRect (clip); - ct.transform (clip); - clip.bound (context.getSurfaceRect ()); + CRect clip = context.getCurrentStateClipRect (); if (clip.isEmpty ()) { clipIsEmpty = true; @@ -124,6 +121,12 @@ void Context::init () super::init (); } +//----------------------------------------------------------------------------- +CRect Context::getCurrentStateClipRect () const +{ + return getCurrentState ().clipRect; +} + //----------------------------------------------------------------------------- void Context::beginDraw () { diff --git a/vstgui/lib/platform/linux/cairocontext.h b/vstgui/lib/platform/linux/cairocontext.h index 24881ebb4..cf78bd259 100644 --- a/vstgui/lib/platform/linux/cairocontext.h +++ b/vstgui/lib/platform/linux/cairocontext.h @@ -58,6 +58,7 @@ class Context : public COffscreenContext void beginDraw () override; void endDraw () override; + CRect getCurrentStateClipRect () const; private: void init () override; void setSourceColor (CColor color); From 21c6d11422482acce63f889f17540f2ec08ed4e8 Mon Sep 17 00:00:00 2001 From: scheffle Date: Sat, 12 Jun 2021 14:48:46 +0200 Subject: [PATCH 13/20] add visualize redraw areas to mac standalone apps in debug mode and add the possibility to programmatically enable/disable to visualize redraw areas on mac thru the mac platform factory --- vstgui/lib/platform/mac/cocoa/nsviewframe.h | 4 +- vstgui/lib/platform/mac/cocoa/nsviewframe.mm | 12 +++- vstgui/lib/platform/mac/macfactory.h | 3 + vstgui/lib/platform/mac/macfactory.mm | 13 ++++ .../source/platform/mac/macapplication.mm | 62 ++++++++++++++++--- 5 files changed, 81 insertions(+), 13 deletions(-) diff --git a/vstgui/lib/platform/mac/cocoa/nsviewframe.h b/vstgui/lib/platform/mac/cocoa/nsviewframe.h index e8193fe29..888eef408 100644 --- a/vstgui/lib/platform/mac/cocoa/nsviewframe.h +++ b/vstgui/lib/platform/mac/cocoa/nsviewframe.h @@ -112,9 +112,7 @@ class NSViewFrame : public IPlatformFrame, public ICocoaPlatformFrame, public IP bool trackingAreaInitialized; bool inDraw; bool useInvalidRects {false}; -#if DEBUG - bool visualizeDirtyRects {false}; -#endif + CCursorType cursor; CButtonState mouseDownButtonState {}; CInvalidRectList invalidRectList; diff --git a/vstgui/lib/platform/mac/cocoa/nsviewframe.mm b/vstgui/lib/platform/mac/cocoa/nsviewframe.mm index 807d82362..ac621f8cb 100644 --- a/vstgui/lib/platform/mac/cocoa/nsviewframe.mm +++ b/vstgui/lib/platform/mac/cocoa/nsviewframe.mm @@ -35,6 +35,7 @@ using namespace VSTGUI; #if DEBUG + //------------------------------------------------------------------------ @interface DebugRedrawAnimDelegate : NSObject @property (retain, readwrite) CALayer* layer; @@ -43,13 +44,20 @@ @interface DebugRedrawAnimDelegate : NSObject @implementation DebugRedrawAnimDelegate +//------------------------------------------------------------------------ +- (void)dealloc +{ + self.layer = nil; + [super dealloc]; +} + //------------------------------------------------------------------------ - (void)animationDidStop:(CAAnimation*)anim finished:(BOOL)flag { if (flag) { [self.layer removeFromSuperlayer]; - [self.layer release]; + self.layer = nil; } } @@ -905,7 +913,7 @@ static id VSTGUI_NSView_makeTouchbar (id self) void NSViewFrame::addDebugRedrawRect (CRect r, bool isClipBoundingBox) { #if DEBUG - if (visualizeDirtyRects && nsView.layer) + if (getPlatformFactory ().asMacFactory ()->enableVisualizeRedrawAreas () && nsView.layer) { auto delegate = [[DebugRedrawAnimDelegate new] autorelease]; auto anim = [CABasicAnimation animation]; diff --git a/vstgui/lib/platform/mac/macfactory.h b/vstgui/lib/platform/mac/macfactory.h index ada77140a..4c71b3ccb 100644 --- a/vstgui/lib/platform/mac/macfactory.h +++ b/vstgui/lib/platform/mac/macfactory.h @@ -22,6 +22,9 @@ class MacFactory final : public IPlatformFactory void setUseAsynchronousLayerDrawing (bool state) const noexcept; bool getUseAsynchronousLayerDrawing () const noexcept; + void enableVisualizeRedrawAreas (bool state) const noexcept; + bool enableVisualizeRedrawAreas () const noexcept; + /** Return platform ticks (millisecond resolution) * @return ticks */ diff --git a/vstgui/lib/platform/mac/macfactory.mm b/vstgui/lib/platform/mac/macfactory.mm index 5fcac633d..a929276b4 100644 --- a/vstgui/lib/platform/mac/macfactory.mm +++ b/vstgui/lib/platform/mac/macfactory.mm @@ -33,6 +33,7 @@ struct mach_timebase_info timebaseInfo; CFBundleRef bundle {nullptr}; bool useAsynchronousLayerDrawing {true}; + bool visualizeRedrawAreas {false}; }; //----------------------------------------------------------------------------- @@ -61,6 +62,18 @@ return impl->useAsynchronousLayerDrawing; } +//----------------------------------------------------------------------------- +void MacFactory::enableVisualizeRedrawAreas (bool state) const noexcept +{ + impl->visualizeRedrawAreas = state; +} + +//----------------------------------------------------------------------------- +bool MacFactory::enableVisualizeRedrawAreas () const noexcept +{ + return impl->visualizeRedrawAreas; +} + //----------------------------------------------------------------------------- uint64_t MacFactory::getTicks () const noexcept { diff --git a/vstgui/standalone/source/platform/mac/macapplication.mm b/vstgui/standalone/source/platform/mac/macapplication.mm index bcfa77574..acbc2ec3a 100644 --- a/vstgui/standalone/source/platform/mac/macapplication.mm +++ b/vstgui/standalone/source/platform/mac/macapplication.mm @@ -122,6 +122,10 @@ - (BOOL)validateMenuItem:(nonnull NSMenuItem*)menuItem { return Detail::getApplicationPlatformAccess ()->canHandleCommand ([command command]); } + else if (menuItem.action == @selector (visualizeRedrawAreas:) || menuItem.action == @selector (useAsynchronousCALayerDrawing:)) + { + return YES; + } return NO; } @@ -402,15 +406,20 @@ - (void)setupMainMenu } NSMenuItem* debugMenu = [mainMenu itemWithTitle:@"Debug"]; - if (debugMenu && debugMenu.submenu) + if (debugMenu && debugMenu.submenu && [debugMenu.submenu itemWithTitle:@"Color Panel"] == nil) { - if ([debugMenu.submenu itemWithTitle:@"Color Panel"] == nil) - { - [debugMenu.submenu addItem:[NSMenuItem separatorItem]]; - [debugMenu.submenu addItemWithTitle:@"Color Panel" - action:@selector (orderFrontColorPanel:) - keyEquivalent:@""]; - } + [debugMenu.submenu addItem:[NSMenuItem separatorItem]]; + [debugMenu.submenu addItemWithTitle:@"Color Panel" + action:@selector (orderFrontColorPanel:) + keyEquivalent:@""]; + [debugMenu.submenu addItem:[NSMenuItem separatorItem]]; + [debugMenu.submenu addItemWithTitle:@"Use Asynchronous CALayer Drawing" + action:@selector (useAsynchronousCALayerDrawing:) + keyEquivalent:@""]; + [debugMenu.submenu addItemWithTitle:@"Visualize Redraw Areas" + action:@selector (visualizeRedrawAreas:) + keyEquivalent:@""]; + [self updateDebugMenuItems]; } // move Windows menu to the end @@ -436,6 +445,43 @@ - (void)triggerSetupMainMenu }); } +//------------------------------------------------------------------------ +- (void)visualizeRedrawAreas:(id)sender +{ + auto state = VSTGUI::getPlatformFactory ().asMacFactory ()->enableVisualizeRedrawAreas (); + VSTGUI::getPlatformFactory ().asMacFactory ()->enableVisualizeRedrawAreas (!state); + [self updateDebugMenuItems]; +} + +//------------------------------------------------------------------------ +- (void)useAsynchronousCALayerDrawing:(id)sender +{ + auto state = VSTGUI::getPlatformFactory ().asMacFactory ()->getUseAsynchronousLayerDrawing (); + VSTGUI::getPlatformFactory ().asMacFactory ()->setUseAsynchronousLayerDrawing (!state); + [self updateDebugMenuItems]; +} + +//------------------------------------------------------------------------ +- (void)updateDebugMenuItems +{ + NSMenuItem* debugMenu = [NSApp.mainMenu itemWithTitle:@"Debug"]; + if (debugMenu && debugMenu.submenu) + { + if (auto item = [debugMenu.submenu itemWithTitle:@"Visualize Redraw Areas"]) + { + auto state = + VSTGUI::getPlatformFactory ().asMacFactory ()->enableVisualizeRedrawAreas (); + item.state = state ? NSControlStateValueOn : NSControlStateValueOff; + } + if (auto item = [debugMenu.submenu itemWithTitle:@"Use Asynchronous CALayer Drawing"]) + { + auto state = + VSTGUI::getPlatformFactory ().asMacFactory ()->getUseAsynchronousLayerDrawing (); + item.state = state ? NSControlStateValueOn : NSControlStateValueOff; + } + } +} + #if !VSTGUI_STANDALONE_USE_GENERIC_ALERTBOX_ON_MACOS //------------------------------------------------------------------------ - (nonnull NSAlert*)createAlert:(const AlertBoxConfig&)config From 84b19e0ea42c3a46efe02715d9c5242fbaae409b Mon Sep 17 00:00:00 2001 From: scheffle Date: Sun, 13 Jun 2021 10:33:40 +0200 Subject: [PATCH 14/20] add patchlevel to vstgui version makros to support simple bug fix releases without API changes --- vstgui/lib/vstguibase.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vstgui/lib/vstguibase.h b/vstgui/lib/vstguibase.h index 743092639..516b5ee52 100644 --- a/vstgui/lib/vstguibase.h +++ b/vstgui/lib/vstguibase.h @@ -12,7 +12,8 @@ // VSTGUI Version //----------------------------------------------------------------------------- #define VSTGUI_VERSION_MAJOR 4 -#define VSTGUI_VERSION_MINOR 11 +#define VSTGUI_VERSION_MINOR 10 +#define VSTGUI_VERSION_PATCHLEVEL 1 //----------------------------------------------------------------------------- // Platform definitions From bd2d596b47e47989147f451eec67c23f167493f0 Mon Sep 17 00:00:00 2001 From: scheffle Date: Sun, 13 Jun 2021 18:25:44 +0200 Subject: [PATCH 15/20] implement cairo hitTest --- vstgui/lib/platform/linux/cairopath.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/vstgui/lib/platform/linux/cairopath.cpp b/vstgui/lib/platform/linux/cairopath.cpp index 9597e106c..7e095e892 100644 --- a/vstgui/lib/platform/linux/cairopath.cpp +++ b/vstgui/lib/platform/linux/cairopath.cpp @@ -30,11 +30,21 @@ CGradient* Path::createGradient (double color1Start, double color2Start, //------------------------------------------------------------------------ bool Path::hitTest (const CPoint& p, bool evenOddFilled, CGraphicsTransform* transform) { -#warning TODO: Implementation (use cairo_in_fill) - (void)p; - (void)evenOddFilled; - (void)transform; - return false; + auto result = false; + if (auto cPath = getPath (cr)) + { + auto tp = p; + if (transform) + transform->transform (tp); + cairo_save (cr); + cairo_new_path (cr); + cairo_append_path (cr, cPath); + cairo_set_fill_rule (cr, evenOddFilled ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING); + cairo_clip (cr); + result = cairo_in_clip (cr, tp.x, tp.y); + cairo_restore (cr); + } + return result; } //------------------------------------------------------------------------ From 140277b571727e8c9514b471d9ba5624c9174bb9 Mon Sep 17 00:00:00 2001 From: scheffle Date: Sun, 13 Jun 2021 18:26:05 +0200 Subject: [PATCH 16/20] implement pango leading metrics --- vstgui/lib/platform/linux/cairofont.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/vstgui/lib/platform/linux/cairofont.cpp b/vstgui/lib/platform/linux/cairofont.cpp index 2579134ad..d572dc3e4 100644 --- a/vstgui/lib/platform/linux/cairofont.cpp +++ b/vstgui/lib/platform/linux/cairofont.cpp @@ -156,6 +156,12 @@ Font::Font (UTF8StringPtr name, const CCoord& size, const int32_t& style) { impl->ascent = pango_units_to_double (pango_font_metrics_get_ascent (metrics)); impl->descent = pango_units_to_double (pango_font_metrics_get_descent (metrics)); +#ifdef PANGO_AVAILABLE_IN_1_44 + auto height = pango_units_to_double (pango_font_metrics_get_height (metrics)); + impl->leading = height - (impl->ascent + impl->descent); +#else + impl->leading = 0.; +#endif pango_font_metrics_unref (metrics); } @@ -210,7 +216,6 @@ double Font::getDescent () const //------------------------------------------------------------------------ double Font::getLeading () const { -#warning TODO: Implementation return impl->leading; } From e2e5b3d35e82edfbc88e1f499694c7d008ad050c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Hansen?= Date: Tue, 15 Jun 2021 15:45:33 +0200 Subject: [PATCH 17/20] Do not let newValue exceed 1.0 when adding up valueOffset multiple times. --- vstgui/lib/controls/csegmentbutton.cpp | 3 +++ .../lib/controls/csegmentbutton_test.cpp | 27 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/vstgui/lib/controls/csegmentbutton.cpp b/vstgui/lib/controls/csegmentbutton.cpp index 5ab13f873..22073f242 100644 --- a/vstgui/lib/controls/csegmentbutton.cpp +++ b/vstgui/lib/controls/csegmentbutton.cpp @@ -349,6 +349,9 @@ CMouseEventResult CSegmentButton::onMouseDown (CPoint& where, const CButtonState break; // out of for loop } newValue += valueOffset; + + // Last segment can lead to newValue > 1.0 + newValue = std::min(newValue, 1.f); } } return kMouseDownEventHandledButDontNeedMovedOrUpEvents; diff --git a/vstgui/tests/unittest/lib/controls/csegmentbutton_test.cpp b/vstgui/tests/unittest/lib/controls/csegmentbutton_test.cpp index a171a3705..36577589f 100644 --- a/vstgui/tests/unittest/lib/controls/csegmentbutton_test.cpp +++ b/vstgui/tests/unittest/lib/controls/csegmentbutton_test.cpp @@ -329,6 +329,33 @@ TESTCASE(CSegmentButtonTest, parent->removed (root); ); + TEST(mouseDownEventOnLastSegment, + // Create segment button with 31 segments and attach it. + // 31 segments causing rounding errors inside segment button. + const auto numSegments = 31; + CRect r(0, 0, 20 * numSegments, 100); + auto b = new CSegmentButton(r); + b->setStyle(CSegmentButton::Style::kHorizontal); + for (auto i = 0; i < numSegments; ++i) + b->addSegment({}); + for (const auto& s : b->getSegments()) + EXPECT(s.rect == CRect(0, 0, 0, 0)); + auto root = owned(new CViewContainer(r)); + auto parent = new CViewContainer(r); + root->addView(parent); + parent->addView(b); + parent->attached(root); + + // Select the last segment + constexpr auto kSelectedSegment = numSegments - 1; + CPoint p(0, 0); + p(20 * kSelectedSegment + 5, 0); + EXPECT(b->onMouseDown(p, kLButton) == kMouseDownEventHandledButDontNeedMovedOrUpEvents); + EXPECT(b->getSelectedSegment() == kSelectedSegment); + + parent->removed(root); + ); + TEST(focusPathSetting, CSegmentButton b (CRect (0, 0, 10, 10)); EXPECT (b.drawFocusOnTop () == false); From d9555018f387c70d9b66cbebfa6de4adf4a5aaa7 Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 23 Jun 2021 13:50:59 +0200 Subject: [PATCH 18/20] Update stb_textedit to v1.13 --- vstgui/lib/platform/common/stb_textedit.h | 112 +++++++++++----------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/vstgui/lib/platform/common/stb_textedit.h b/vstgui/lib/platform/common/stb_textedit.h index 91a52da1b..cd38a25ab 100644 --- a/vstgui/lib/platform/common/stb_textedit.h +++ b/vstgui/lib/platform/common/stb_textedit.h @@ -1,4 +1,4 @@ -// stb_textedit.h - v1.12 - public domain - Sean Barrett +// stb_textedit.h - v1.13 - public domain - Sean Barrett // Development of this library was sponsored by RAD Game Tools // // This C header file implements the guts of a multi-line text-editing @@ -13,7 +13,7 @@ // texts, as its performance does not scale and it has limited undo). // // Non-trivial behaviors are modelled after Windows text controls. -// +// // // LICENSE // @@ -29,6 +29,7 @@ // // VERSION HISTORY // +// 1.13 (2019-02-07) fix bug in undo size management // 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash // 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield // 1.10 (2016-10-25) supress warnings about casting away const with -Wcast-qual @@ -86,8 +87,8 @@ // moderate sizes. The undo system does no memory allocations, so // it grows STB_TexteditState by the worst-case storage which is (in bytes): // -// [4 + sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATE_COUNT -// + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHAR_COUNT +// [4 + 3 * sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATE_COUNT +// + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHAR_COUNT // // // Implementation mode: @@ -110,7 +111,7 @@ // Symbols that must be the same in header-file and implementation mode: // // STB_TEXTEDIT_CHARTYPE the character type -// STB_TEXTEDIT_POSITIONTYPE small type that a valid cursor position +// STB_TEXTEDIT_POSITIONTYPE small type that is a valid cursor position // STB_TEXTEDIT_UNDOSTATECOUNT the number of undo states to allow // STB_TEXTEDIT_UNDOCHARCOUNT the number of characters to store in the undo buffer // @@ -170,7 +171,7 @@ // Keyboard input must be encoded as a single integer value; e.g. a character code // and some bitflags that represent shift states. to simplify the interface, SHIFT must // be a bitflag, so we can test the shifted state of cursor movements to allow selection, -// i.e. (STB_TEXTED_K_RIGHT|STB_TEXTEDIT_K_SHIFT) should be shifted right-arrow. +// i.e. (STB_TEXTEDIT_K_RIGHT|STB_TEXTEDIT_K_SHIFT) should be shifted right-arrow. // // You can encode other things, such as CONTROL or ALT, in additional bits, and // then test for their presence in e.g. STB_TEXTEDIT_K_WORDLEFT. For example, @@ -212,20 +213,20 @@ // call this with the mouse x,y on a mouse down; it will update the cursor // and reset the selection start/end to the cursor point. the x,y must // be relative to the text widget, with (0,0) being the top left. -// +// // drag: // call this with the mouse x,y on a mouse drag/up; it will update the // cursor and the selection end point -// +// // cut: // call this to delete the current selection; returns true if there was // one. you should FIRST copy the current selection to the system paste buffer. // (To copy, just copy the current selection out of the string yourself.) -// +// // paste: // call this to paste text at the current cursor point or over the current // selection if there is one. -// +// // key: // call this for keyboard inputs sent to the textfield. you can use it // for "key down" events or for "translated" key events. if you need to @@ -236,7 +237,7 @@ // clear. STB_TEXTEDIT_KEYTYPE defaults to int, but you can #define it to // anything other type you wante before including. // -// +// // When rendering, you can read the cursor position and selection state from // the STB_TexteditState. // @@ -295,9 +296,9 @@ typedef struct { // private data STB_TEXTEDIT_POSITIONTYPE where; - short insert_length; - short delete_length; - short char_storage; + STB_TEXTEDIT_POSITIONTYPE insert_length; + STB_TEXTEDIT_POSITIONTYPE delete_length; + int char_storage; } StbUndoRecord; typedef struct @@ -306,7 +307,7 @@ typedef struct StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT]; STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT]; short undo_point, redo_point; - short undo_char_point, redo_char_point; + int undo_char_point, redo_char_point; } StbUndoState; typedef struct @@ -558,7 +559,6 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s // now scan to find xpos find->x = r.x0; - i = 0; for (i=0; first+i < n; ++i) find->x += STB_TEXTEDIT_GETWIDTH(str, first, i); } @@ -688,7 +688,7 @@ static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state) static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) { if (STB_TEXT_HAS_SELECTION(state)) { - stb_textedit_delete_selection(str,state); // implicity clamps + stb_textedit_delete_selection(str,state); // implicitly clamps state->has_preferred_x = 0; return 1; } @@ -740,7 +740,7 @@ static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, state->has_preferred_x = 0; } } else { - stb_textedit_delete_selection(str,state); // implicity clamps + stb_textedit_delete_selection(str,state); // implicitly clamps if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { stb_text_makeundo_insert(state, state->cursor, 1); ++state->cursor; @@ -756,7 +756,7 @@ static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, state->insert_mode = !state->insert_mode; break; #endif - + case STB_TEXTEDIT_K_UNDO: stb_text_undo(str, state); state->has_preferred_x = 0; @@ -771,7 +771,7 @@ static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, // if currently there's a selection, move cursor to start of selection if (STB_TEXT_HAS_SELECTION(state)) stb_textedit_move_to_first(state); - else + else if (state->cursor > 0) --state->cursor; state->has_preferred_x = 0; @@ -820,7 +820,7 @@ static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, #ifdef STB_TEXTEDIT_MOVEWORDRIGHT case STB_TEXTEDIT_K_WORDRIGHT: - if (STB_TEXT_HAS_SELECTION(state)) + if (STB_TEXT_HAS_SELECTION(state)) stb_textedit_move_to_last(str, state); else { state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor); @@ -898,7 +898,7 @@ static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, } break; } - + case STB_TEXTEDIT_K_UP: case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT: { StbFindState find; @@ -975,7 +975,7 @@ static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, } state->has_preferred_x = 0; break; - + #ifdef STB_TEXTEDIT_K_TEXTSTART2 case STB_TEXTEDIT_K_TEXTSTART2: #endif @@ -992,7 +992,7 @@ static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, state->select_start = state->select_end = 0; state->has_preferred_x = 0; break; - + #ifdef STB_TEXTEDIT_K_TEXTSTART2 case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT: #endif @@ -1096,11 +1096,11 @@ static void stb_textedit_discard_undo(StbUndoState *state) if (state->undo_rec[0].char_storage >= 0) { int n = state->undo_rec[0].insert_length, i; // delete n characters from all other records - state->undo_char_point = state->undo_char_point - (short) n; // vsnet05 + state->undo_char_point -= n; STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE))); for (i=0; i < state->undo_point; ++i) if (state->undo_rec[i].char_storage >= 0) - state->undo_rec[i].char_storage = state->undo_rec[i].char_storage - (short) n; // vsnet05 // @OPTIMIZE: get rid of char_storage and infer it + state->undo_rec[i].char_storage -= n; // @OPTIMIZE: get rid of char_storage and infer it } --state->undo_point; STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0]))); @@ -1120,12 +1120,12 @@ static void stb_textedit_discard_redo(StbUndoState *state) if (state->undo_rec[k].char_storage >= 0) { int n = state->undo_rec[k].insert_length, i; // move the remaining redo character data to the end of the buffer - state->redo_char_point = state->redo_char_point + (short) n; // vsnet05 + state->redo_char_point += n; STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE))); // adjust the position of all the other records to account for above memmove for (i=state->redo_point; i < k; ++i) if (state->undo_rec[i].char_storage >= 0) - state->undo_rec[i].char_storage += (short) n; // vsnet05 + state->undo_rec[i].char_storage += n; } // now move all the redo records towards the end of the buffer; the first one is at 'redo_point' STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0]))); @@ -1165,15 +1165,15 @@ static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, return NULL; r->where = pos; - r->insert_length = (short) insert_len; - r->delete_length = (short) delete_len; + r->insert_length = (STB_TEXTEDIT_POSITIONTYPE) insert_len; + r->delete_length = (STB_TEXTEDIT_POSITIONTYPE) delete_len; if (insert_len == 0) { r->char_storage = -1; return NULL; } else { r->char_storage = state->undo_char_point; - state->undo_char_point = state->undo_char_point + (short) insert_len; + state->undo_char_point += insert_len; return &state->undo_char[r->char_storage]; } } @@ -1222,7 +1222,7 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) r = &s->undo_rec[s->redo_point-1]; r->char_storage = s->redo_char_point - u.delete_length; - s->redo_char_point = s->redo_char_point - (short) u.delete_length; + s->redo_char_point = s->redo_char_point - u.delete_length; // now save the characters for (i=0; i < u.delete_length; ++i) @@ -1367,38 +1367,38 @@ This software is available under 2 licenses -- choose whichever you prefer. ------------------------------------------------------------------------------ ALTERNATIVE A - MIT License Copyright (c) 2017 Sean Barrett -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ ALTERNATIVE B - Public Domain (www.unlicense.org) This is free and unencumbered software released into the public domain. -Anyone is free to copy, modify, publish, use, compile, sell, or distribute this -software, either in source code form or as a compiled binary, for any purpose, +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. -In jurisdictions that recognize copyright laws, the author or authors of this -software dedicate any and all copyright interest in the software to the public -domain. We make this dedication for the benefit of the public at large and to -the detriment of our heirs and successors. We intend this dedication to be an -overt act of relinquishment in perpetuity of all present and future rights to +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ */ From 76704e67bbe26574b4cdee3fa96931adb84018c1 Mon Sep 17 00:00:00 2001 From: scheffle Date: Wed, 23 Jun 2021 14:04:40 +0200 Subject: [PATCH 19/20] add missing includes fix #189 --- vstgui/lib/platform/linux/x11fileselector.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vstgui/lib/platform/linux/x11fileselector.cpp b/vstgui/lib/platform/linux/x11fileselector.cpp index f0fd776f0..ab80daafa 100644 --- a/vstgui/lib/platform/linux/x11fileselector.cpp +++ b/vstgui/lib/platform/linux/x11fileselector.cpp @@ -5,6 +5,8 @@ #include "../../cfileselector.h" #include #include +#include +#include #include #include #include From 77ab5432fa8372f81b2f2b380a94aca9aa8383f2 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Wed, 23 Jun 2021 19:17:29 +0200 Subject: [PATCH 20/20] Fix compile-time check for pango --- vstgui/lib/platform/linux/cairofont.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vstgui/lib/platform/linux/cairofont.cpp b/vstgui/lib/platform/linux/cairofont.cpp index d572dc3e4..f906e0e22 100644 --- a/vstgui/lib/platform/linux/cairofont.cpp +++ b/vstgui/lib/platform/linux/cairofont.cpp @@ -156,7 +156,7 @@ Font::Font (UTF8StringPtr name, const CCoord& size, const int32_t& style) { impl->ascent = pango_units_to_double (pango_font_metrics_get_ascent (metrics)); impl->descent = pango_units_to_double (pango_font_metrics_get_descent (metrics)); -#ifdef PANGO_AVAILABLE_IN_1_44 +#if (PANGO_VERSION_MAJOR > 1) || ((PANGO_VERSION_MAJOR == 1) && PANGO_VERSION_MINOR >= 44) auto height = pango_units_to_double (pango_font_metrics_get_height (metrics)); impl->leading = height - (impl->ascent + impl->descent); #else