Initial release

This commit is contained in:
civ
2026-08-16 18:24:52 +07:00
commit 876886a39a
13244 changed files with 2353959 additions and 0 deletions
@@ -0,0 +1,66 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/algorithm.h"
#include "../unittests.h"
namespace VSTGUI {
//------------------------------------------------------------------------
TEST_CASE (Algorithm, Clamp)
{
EXPECT_EQ (clamp (2.8, 1.4, 1.8), 1.8);
EXPECT_EQ (clamp (1.2, 1.4, 1.8), 1.4);
}
//------------------------------------------------------------------------
TEST_CASE (Algorithm, ClampNorm)
{
EXPECT_EQ (clampNorm (1.8), 1.);
EXPECT_EQ (clampNorm (-0.1), 0.);
}
//------------------------------------------------------------------------
TEST_CASE (Algorithm, NormalizedToSteps)
{
EXPECT_EQ (normalizedToSteps (0., 1), 0);
EXPECT_EQ (normalizedToSteps (0.49, 1), 0);
EXPECT_EQ (normalizedToSteps (0.50, 1), 1);
EXPECT_EQ (normalizedToSteps (0.51, 1), 1);
EXPECT_EQ (normalizedToSteps (1., 1), 1);
EXPECT_EQ (normalizedToSteps (0., 3), 0);
EXPECT_EQ (normalizedToSteps (0.24, 3), 0);
EXPECT_EQ (normalizedToSteps (0.25, 3), 1);
EXPECT_EQ (normalizedToSteps (0.26, 3), 1);
EXPECT_EQ (normalizedToSteps (0.49, 3), 1);
EXPECT_EQ (normalizedToSteps (0.50, 3), 2);
EXPECT_EQ (normalizedToSteps (0.51, 3), 2);
EXPECT_EQ (normalizedToSteps (0.74, 3), 2);
EXPECT_EQ (normalizedToSteps (0.75, 3), 3);
EXPECT_EQ (normalizedToSteps (0.76, 3), 3);
EXPECT_EQ (normalizedToSteps (1., 3), 3);
EXPECT_EQ (normalizedToSteps (0., 1, 1), 1);
EXPECT_EQ (normalizedToSteps (0.5, 1, 1), 2);
EXPECT_EQ (normalizedToSteps (1., 1, 1), 2);
}
//------------------------------------------------------------------------
TEST_CASE (Agorithm, StepsToNormalized)
{
EXPECT_EQ (stepsToNormalized<double> (1, 1), 1.);
EXPECT_EQ (stepsToNormalized<double> (0, 1), 0.);
EXPECT_EQ (stepsToNormalized<double> (0, 4), 0.);
EXPECT_EQ (stepsToNormalized<double> (1, 4), 0.25);
EXPECT_EQ (stepsToNormalized<double> (2, 4), 0.50);
EXPECT_EQ (stepsToNormalized<double> (3, 4), 0.75);
EXPECT_EQ (stepsToNormalized<double> (4, 4), 1.);
EXPECT_EQ (stepsToNormalized<double> (2, 1, 1), 1.);
EXPECT_EQ (stepsToNormalized<double> (1, 1, 1), 0.);
}
} // VSTGUI
@@ -0,0 +1,247 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/animation/animations.h"
#include "../../../../lib/controls/ccontrol.h"
#include "../../../../lib/cview.h"
#include "../../../../lib/cviewcontainer.h"
#include "../../unittests.h"
namespace VSTGUI {
using namespace Animation;
namespace {
//-----------------------------------------------------------------------------
class TestView : public CView
{
public:
TestView () : CView (CRect (0, 0, 0, 0)) {}
};
//-----------------------------------------------------------------------------
class TestControl : public CControl
{
public:
TestControl () : CControl (CRect (0, 0, 0, 0)) {}
void draw (CDrawContext* pContext) override {}
CLASS_METHODS (TestControl, CControl)
};
} // anonymous
TEST_CASE (AlphaValueAnimtionTest, Animation)
{
TestView view;
EXPECT (view.getAlphaValue () == 1.f);
AlphaValueAnimation a (0.f);
a.animationStart (&view, "");
a.animationTick (&view, "", 0.5f);
EXPECT (view.getAlphaValue () == 0.5f);
a.animationTick (&view, "", 1.f);
EXPECT (view.getAlphaValue () == 0.f);
a.animationFinished (&view, "", false);
EXPECT (view.getAlphaValue () == 0.f);
}
//-----------------------------------------------------------------------------
TEST_CASE (ViewSizeAnimationTest, Animation)
{
TestView view;
EXPECT (view.getViewSize () == CRect (0, 0, 0, 0));
ViewSizeAnimation a (CRect (10, 10, 100, 100));
a.animationStart (&view, "");
a.animationTick (&view, "", 0.5f);
EXPECT (view.getViewSize () == CRect (5, 5, 50, 50));
a.animationTick (&view, "", 1.f);
EXPECT (view.getViewSize () == CRect (10, 10, 100, 100));
a.animationFinished (&view, "", false);
EXPECT (view.getViewSize () == CRect (10, 10, 100, 100));
}
TEST_CASE (ViewSizeAnimationTest, UnfinishedAnimation)
{
TestView view;
ViewSizeAnimation a (CRect (10, 10, 100, 100));
a.animationStart (&view, "");
a.animationTick (&view, "", 0.5f);
EXPECT (view.getViewSize () == CRect (5, 5, 50, 50));
a.animationFinished (&view, "", false);
EXPECT (view.getViewSize () == CRect (10, 10, 100, 100));
}
//-----------------------------------------------------------------------------
TEST_CASE (ControlValueAnimationTest, Animation)
{
TestControl control;
EXPECT (control.getValue () == 0.f);
ControlValueAnimation a (1.f);
a.animationStart (&control, "");
EXPECT (control.getValue () == 0.f);
a.animationTick (&control, "", 0.3f);
EXPECT (control.getValue () == 0.3f);
a.animationTick (&control, "", 0.5f);
EXPECT (control.getValue () == 0.5f);
a.animationFinished (&control, "", false);
EXPECT (control.getValue () == 1.f);
}
//-----------------------------------------------------------------------------
TEST_CASE (ExchangeViewAnimationTest, AlphaValueFade)
{
auto parentContainer = owned (new CViewContainer (CRect (0, 0, 0, 0)));
auto container = new CViewContainer (CRect (0, 0, 0, 0));
container->attached (parentContainer);
auto oldView = new TestView ();
auto newView = new TestView ();
container->addView (oldView);
ExchangeViewAnimation a (oldView, newView, ExchangeViewAnimation::kAlphaValueFade);
a.animationStart (container, "");
EXPECT (oldView->getAlphaValue () == 1.f);
EXPECT (newView->getAlphaValue () == 0.f);
a.animationTick (container, "", 0.5f);
EXPECT (oldView->getAlphaValue () == 0.5f);
EXPECT (newView->getAlphaValue () == 0.5f);
a.animationTick (container, "", 1.f);
a.animationFinished (container, "", false);
EXPECT (oldView->isAttached () == false);
EXPECT (newView->getAlphaValue () == 1.f);
container->removed (parentContainer);
}
TEST_CASE (ExchangeViewAnimationTest, PushInFromLeft)
{
CRect r (0, 0, 100, 100);
auto parentContainer = owned (new CViewContainer (r));
auto container = new CViewContainer (r);
container->attached (parentContainer);
auto oldView = new CView (r);
auto newView = new CView (r);
container->addView (oldView);
ExchangeViewAnimation a (oldView, newView, ExchangeViewAnimation::kPushInFromLeft);
a.animationStart (container, "");
EXPECT (oldView->getViewSize () == r);
EXPECT (newView->getViewSize () == CRect (-100, 0, 0, 100));
a.animationTick (container, "", 0.5f);
EXPECT (newView->getViewSize () == CRect (-50, 0, 50, 100));
a.animationTick (container, "", 1.f);
a.animationFinished (container, "", false);
EXPECT (oldView->isAttached () == false);
EXPECT (newView->getViewSize () == r);
container->removed (parentContainer);
}
TEST_CASE (ExchangeViewAnimationTest, PushInFromRight)
{
CRect r (0, 0, 100, 100);
auto parentContainer = owned (new CViewContainer (r));
auto container = new CViewContainer (r);
container->attached (parentContainer);
auto oldView = new CView (r);
auto newView = new CView (r);
container->addView (oldView);
ExchangeViewAnimation a (oldView, newView, ExchangeViewAnimation::kPushInFromRight);
a.animationStart (container, "");
EXPECT (oldView->getViewSize () == r);
EXPECT (newView->getViewSize () == CRect (100, 0, 200, 100));
a.animationTick (container, "", 0.5f);
EXPECT (newView->getViewSize () == CRect (50, 0, 150, 100));
a.animationTick (container, "", 1.f);
a.animationFinished (container, "", false);
EXPECT (oldView->isAttached () == false);
EXPECT (newView->getViewSize () == r);
container->removed (parentContainer);
}
TEST_CASE (ExchangeViewAnimationTest, PushInFromTop)
{
CRect r (0, 0, 100, 100);
auto parentContainer = owned (new CViewContainer (r));
auto container = new CViewContainer (r);
container->attached (parentContainer);
auto oldView = new CView (r);
auto newView = new CView (r);
container->addView (oldView);
ExchangeViewAnimation a (oldView, newView, ExchangeViewAnimation::kPushInFromTop);
a.animationStart (container, "");
EXPECT (oldView->getViewSize () == r);
EXPECT (newView->getViewSize () == CRect (0, -100, 100, 0));
a.animationTick (container, "", 0.5f);
EXPECT (newView->getViewSize () == CRect (0, -50, 100, 50));
a.animationTick (container, "", 1.f);
a.animationFinished (container, "", false);
EXPECT (oldView->isAttached () == false);
EXPECT (newView->getViewSize () == r);
container->removed (parentContainer);
}
TEST_CASE (ExchangeViewAnimationTest, PushInFromBottom)
{
CRect r (0, 0, 100, 100);
auto parentContainer = owned (new CViewContainer (r));
auto container = new CViewContainer (r);
container->attached (parentContainer);
auto oldView = new CView (r);
auto newView = new CView (r);
container->addView (oldView);
ExchangeViewAnimation a (oldView, newView, ExchangeViewAnimation::kPushInFromBottom);
a.animationStart (container, "");
EXPECT (oldView->getViewSize () == r);
EXPECT (newView->getViewSize () == CRect (0, 100, 100, 200));
a.animationTick (container, "", 0.5f);
EXPECT (newView->getViewSize () == CRect (0, 50, 100, 150));
a.animationTick (container, "", 1.f);
a.animationFinished (container, "", false);
EXPECT (oldView->isAttached () == false);
EXPECT (newView->getViewSize () == r);
container->removed (parentContainer);
}
TEST_CASE (ExchangeViewAnimationTest, PushInOutFromLeft)
{
CRect r (0, 0, 100, 100);
auto parentContainer = owned (new CViewContainer (r));
auto container = new CViewContainer (r);
container->attached (parentContainer);
auto oldView = new CView (r);
auto newView = new CView (r);
container->addView (oldView);
ExchangeViewAnimation a (oldView, newView, ExchangeViewAnimation::kPushInOutFromLeft);
a.animationStart (container, "");
EXPECT (oldView->getViewSize () == r);
EXPECT (newView->getViewSize () == CRect (-100, 0, 0, 100));
a.animationTick (container, "", 0.5f);
EXPECT (oldView->getViewSize () == CRect (50, 0, 150, 100));
EXPECT (newView->getViewSize () == CRect (-50, 0, 50, 100));
a.animationTick (container, "", 1.f);
a.animationFinished (container, "", false);
EXPECT (oldView->isAttached () == false);
EXPECT (newView->getViewSize () == r);
container->removed (parentContainer);
}
TEST_CASE (ExchangeViewAnimationTest, PushInOutFromRight)
{
CRect r (0, 0, 100, 100);
auto parentContainer = owned (new CViewContainer (r));
auto container = new CViewContainer (r);
container->attached (parentContainer);
auto oldView = new CView (r);
auto newView = new CView (r);
container->addView (oldView);
ExchangeViewAnimation a (oldView, newView, ExchangeViewAnimation::kPushInOutFromRight);
a.animationStart (container, "");
EXPECT (oldView->getViewSize () == r);
EXPECT (newView->getViewSize () == CRect (100, 0, 200, 100));
a.animationTick (container, "", 0.5f);
EXPECT (oldView->getViewSize () == CRect (-50, 0, 50, 100));
EXPECT (newView->getViewSize () == CRect (50, 0, 150, 100));
a.animationFinished (container, "", true);
EXPECT (oldView->isAttached () == false);
EXPECT (newView->getViewSize () == r);
container->removed (parentContainer);
}
} // VSTGUI
@@ -0,0 +1,120 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/animation/animations.h"
#include "../../../../lib/animation/animator.h"
#include "../../../../lib/animation/timingfunctions.h"
#include "../../../../lib/cview.h"
#include "../../unittests.h"
#if MAC
#include <CoreFoundation/CoreFoundation.h>
namespace VSTGUI {
using namespace Animation;
namespace {
struct RemoveAnimationInCallback : public IAnimationTarget
{
RemoveAnimationInCallback (Animator* animator) : animator (animator) {}
Animator* animator;
void animationStart (CView* view, IdStringPtr name) override {}
void animationTick (CView* view, IdStringPtr name, float pos) override
{
animator->removeAnimations (view);
}
void animationFinished (CView* view, IdStringPtr name, bool wasCanceled) override {}
};
} // anonymous
//-----------------------------------------------------------------------------
TEST_CASE (AnimatorTest, AddAnimation)
{
auto a = owned (new Animator ());
auto view = owned (new CView (CRect (0, 0, 0, 0)));
a->addAnimation (view, "Test", new AlphaValueAnimation (0.f), new LinearTimingFunction (100),
[] (CView*, const IdStringPtr, IAnimationTarget*) {
CFRunLoopStop (CFRunLoopGetCurrent ());
});
CFRunLoopRun ();
EXPECT (view->getAlphaValue () == 0.f);
}
TEST_CASE (AnimatorTest, CancelAnimation)
{
auto a = owned (new Animator ());
auto view = owned (new CView (CRect (0, 0, 0, 0)));
a->addAnimation (view, "Test", new AlphaValueAnimation (0.f), new LinearTimingFunction (2000));
CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.2, false);
a->removeAnimation (view, "Test");
EXPECT (view->getAlphaValue () != 0.f);
}
TEST_CASE (AnimatorTest, CancelAnimationWithCallback)
{
auto a = owned (new Animator ());
auto view = owned (new CView (CRect (0, 0, 0, 0)));
bool cancelDoneFunctionCalled = false;
auto doneFunc = [&] (auto, auto, auto) { cancelDoneFunctionCalled = true; };
a->addAnimation (view, "Test", new AlphaValueAnimation (0.f), new LinearTimingFunction (2000),
doneFunc, false);
CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.2, false);
a->removeAnimation (view, "Test");
EXPECT_FALSE (cancelDoneFunctionCalled);
EXPECT (view->getAlphaValue () != 0.f);
a->addAnimation (view, "Test", new AlphaValueAnimation (0.f), new LinearTimingFunction (2000),
doneFunc, true);
CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.2, false);
a->removeAnimation (view, "Test");
EXPECT_TRUE (cancelDoneFunctionCalled);
}
TEST_CASE (AnimatorTest, RemoveAnimationInCallback)
{
auto a = owned (new Animator ());
auto view = owned (new CView (CRect (0, 0, 0, 0)));
a->addAnimation (view, "Test", new RemoveAnimationInCallback (a),
new LinearTimingFunction (100),
[] (CView*, const IdStringPtr, IAnimationTarget*) {
CFRunLoopStop (CFRunLoopGetCurrent ());
});
CFRunLoopRun ();
}
#if VSTGUI_ENABLE_DEPRECATED_METHODS
#include "../../../../lib/private/disabledeprecatedmessage.h"
struct MessageReceiver : public CBaseObject
{
CMessageResult notify (CBaseObject* sender, IdStringPtr message) override
{
messageReceived = true;
CFRunLoopStop (CFRunLoopGetCurrent ());
return kMessageNotified;
}
bool messageReceived {false};
};
TEST_CASE (AnimatorTest, AnimationMessage)
{
auto a = owned (new Animator ());
auto view = owned (new CView (CRect (0, 0, 0, 0)));
MessageReceiver recevier;
a->addAnimation (view, "Test", new AlphaValueAnimation (0.f), new LinearTimingFunction (100),
&recevier);
CFRunLoopRun ();
EXPECT (recevier.messageReceived == true)
}
#include "../../../../lib/private/enabledeprecatedmessage.h"
#endif
} // VSTGUI
#endif // MAC
@@ -0,0 +1,98 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/animation/timingfunctions.h"
#include "../../../../lib/controls/ccontrol.h"
#include "../../../../lib/cview.h"
#include "../../../../lib/cviewcontainer.h"
#include "../../unittests.h"
namespace VSTGUI {
using namespace Animation;
TEST_CASE (TimingFunctionTest, LinearTimingFunction)
{
LinearTimingFunction f (100);
ITimingFunction& tf = dynamic_cast<ITimingFunction&> (f);
EXPECT (tf.getPosition (0) == 0.f);
EXPECT (tf.getPosition (50) == 0.5f);
EXPECT (tf.getPosition (100) == 1.f);
EXPECT (tf.getPosition (150) == 1.f);
}
TEST_CASE (TimingFunctionTest, PowerTwoTimingFunction)
{
PowerTimingFunction f (100, 2);
ITimingFunction& tf = dynamic_cast<ITimingFunction&> (f);
EXPECT (tf.getPosition (0) == 0.f);
EXPECT (tf.getPosition (50) == 0.25f);
EXPECT (tf.getPosition (86) == 0.7396f);
EXPECT (tf.getPosition (100) == 1.f);
EXPECT (tf.getPosition (150) == 1.f);
}
TEST_CASE (TimingFunctionTest, PowerFourTimingFunction)
{
PowerTimingFunction f (100, 4);
ITimingFunction& tf = dynamic_cast<ITimingFunction&> (f);
EXPECT (tf.getPosition (0) == 0.f);
EXPECT (tf.getPosition (50) == 0.0625f);
EXPECT (tf.getPosition (100) == 1.f);
EXPECT (tf.getPosition (150) == 1.f);
}
TEST_CASE (TimingFunctionTest, InterpolationTimingFunction)
{
InterpolationTimingFunction f (100);
f.addPoint (0.5, 0.4f);
ITimingFunction& tf = dynamic_cast<ITimingFunction&> (f);
EXPECT (tf.getPosition (0) == 0.f);
EXPECT (tf.getPosition (25) == 0.2f);
EXPECT (tf.getPosition (50) == 0.4f);
EXPECT (tf.getPosition (75) == 0.7f);
EXPECT (tf.getPosition (100) == 1.f);
EXPECT (tf.getPosition (150) == 1.f);
}
TEST_CASE (TimingFunctionTest, RepeatTimingFunction)
{
auto lf = new LinearTimingFunction (100);
RepeatTimingFunction f (lf, 2, false);
ITimingFunction& tf = dynamic_cast<ITimingFunction&> (f);
EXPECT (tf.getPosition (0) == 0.f);
EXPECT (tf.getPosition (50) == 0.5f);
EXPECT (tf.getPosition (100) == 1.f);
EXPECT (tf.isDone (100) == false);
EXPECT (tf.getPosition (110) == 0.1f);
EXPECT (tf.getPosition (150) == 0.5f);
EXPECT (tf.getPosition (200) == 1.0f);
EXPECT (tf.isDone (200) == true);
}
TEST_CASE (TimingFunctionTest, RepeatTimingFunctionReverse)
{
auto lf = new LinearTimingFunction (100);
RepeatTimingFunction f (lf, 2, true);
ITimingFunction& tf = dynamic_cast<ITimingFunction&> (f);
EXPECT (tf.getPosition (0) == 0.f);
EXPECT (tf.getPosition (50) == 0.5f);
EXPECT (tf.getPosition (100) == 1.f);
EXPECT (tf.isDone (100) == false);
EXPECT (tf.getPosition (110) == 0.9f);
EXPECT (tf.getPosition (150) == 0.5f);
EXPECT (tf.getPosition (200) == 0.f);
EXPECT (tf.isDone (200) == true);
}
TEST_CASE (TimingFunctionTest, CubicBezierTimingFunction)
{
CubicBezierTimingFunction f (100, CPoint (0.42, 0.), CPoint (0.58, 1.));
EXPECT (f.getPosition (0) == 0.f);
EXPECT (f.getPosition (25) < 0.25f);
EXPECT (f.getPosition (50) == 0.5f);
EXPECT (f.getPosition (75) > 0.75f);
EXPECT (f.getPosition (100) == 1.0f);
}
} // VSTGUI
@@ -0,0 +1,201 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cbitmap.h"
#include "../../../lib/ccolor.h"
#include "../../../lib/platform/iplatformbitmap.h"
#include "../../../lib/platform/platformfactory.h"
#include "../unittests.h"
namespace VSTGUI {
//------------------------------------------------------------------------
TEST_CASE (CBitmap, ScaleFactor)
{
CPoint p (10, 10);
auto b1 = getPlatformFactory ().createBitmap (p);
CBitmap bitmap (b1);
p (20, 20);
auto b2 = getPlatformFactory ().createBitmap (p);
b2->setScaleFactor (2.);
EXPECT_TRUE (bitmap.addBitmap (b2));
p (21, 21);
auto b3 = getPlatformFactory ().createBitmap (p);
EXPECT_EXCEPTION (bitmap.addBitmap (b3), "wrong bitmap size");
EXPECT_EQ (bitmap.getBestPlatformBitmapForScaleFactor (0.5), b1);
EXPECT_EQ (bitmap.getBestPlatformBitmapForScaleFactor (1.0), b1);
EXPECT_EQ (bitmap.getBestPlatformBitmapForScaleFactor (1.4), b1);
EXPECT_EQ (bitmap.getBestPlatformBitmapForScaleFactor (1.5), b2);
EXPECT_EQ (bitmap.getBestPlatformBitmapForScaleFactor (1.6), b2);
EXPECT_EQ (bitmap.getBestPlatformBitmapForScaleFactor (2.6), b2);
}
//------------------------------------------------------------------------
TEST_CASE (CBitmap, PixelAccess)
{
CBitmap bitmap (10, 10);
EXPECT_EQ (bitmap.getWidth (), 10);
EXPECT_EQ (bitmap.getHeight (), 10);
auto accessor = owned (CBitmapPixelAccess::create (&bitmap));
EXPECT (accessor);
uint32_t x = 0;
uint32_t y = 0;
CColor color;
do
{
accessor->getColor (color);
EXPECT_EQ (color, CColor (0, 0, 0, 0));
accessor->setColor (kRedCColor);
accessor->getColor (color);
EXPECT_EQ (color, kRedCColor);
accessor->setColor (kGreenCColor);
accessor->getColor (color);
EXPECT_EQ (color, kGreenCColor);
accessor->setColor (kBlueCColor);
accessor->getColor (color);
EXPECT_EQ (color, kBlueCColor);
EXPECT_EQ (accessor->getX (), x);
EXPECT_EQ (accessor->getY (), y);
if (++x == accessor->getBitmapWidth ())
{
++y;
x = 0;
}
} while (++(*accessor));
}
//------------------------------------------------------------------------
TEST_CASE (CBitmap, PixelAccess2)
{
CBitmap bitmap (10, 10);
CColor color (255, 1, 2, 150);
if (auto accessor = owned (CBitmapPixelAccess::create (&bitmap)))
{
do
{
accessor->setColor (color);
} while (++(*accessor));
}
if (auto accessor = owned (CBitmapPixelAccess::create (&bitmap)))
{
do
{
CColor c;
accessor->getColor (c);
EXPECT_EQ (c, color);
} while (++(*accessor));
}
}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
TEST_CASE (CMultiFrameBitmap, NotInitialized)
{
CMultiFrameBitmap bitmap (100, 100);
auto fr = bitmap.calcFrameRect (0);
EXPECT_EQ (fr, CRect (0, 0, 100, 100));
}
//------------------------------------------------------------------------
TEST_CASE (CMultiFrameBitmap, CalcFrameRect)
{
CMultiFrameBitmap bitmap (100, 100);
EXPECT_TRUE (bitmap.setMultiFrameDesc ({{50, 50}, 4, 2}));
EXPECT_EQ (bitmap.getFrameSize (), CPoint (50., 50.));
EXPECT_EQ (bitmap.getNumFrames (), 4);
EXPECT_EQ (bitmap.getNumFramesPerRow (), 2);
EXPECT_EQ (bitmap.calcFrameRect (0), CRect (0, 0, 50, 50));
EXPECT_EQ (bitmap.calcFrameRect (1), CRect (50, 0, 100, 50));
EXPECT_EQ (bitmap.calcFrameRect (2), CRect (0, 50, 50, 100));
EXPECT_EQ (bitmap.calcFrameRect (3), CRect (50, 50, 100, 100));
EXPECT_EQ (bitmap.calcFrameRect (4), CRect (50, 50, 100, 100));
}
//------------------------------------------------------------------------
TEST_CASE (CMultiFrameBitmap, InvalidFrameDesc)
{
CMultiFrameBitmap bitmap (100, 100);
EXPECT_FALSE (bitmap.setMultiFrameDesc ({{50, 50}, 4, 1}));
EXPECT_FALSE (bitmap.setMultiFrameDesc ({{50, 50}, 4, 4}));
}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
struct MultiFrameBitmapViewTest : MultiFrameBitmapView<MultiFrameBitmapViewTest>
{
void invalid () {}
};
//------------------------------------------------------------------------
TEST_CASE (MultiFrameBitmapViewTest, Default)
{
MultiFrameBitmapViewTest testView;
CMultiFrameBitmap bitmap (100, 100);
EXPECT_TRUE (bitmap.setMultiFrameDesc ({{50, 50}, 4, 2}));
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 0.f), 0);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 0.33f), 1);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 0.66f), 2);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 1.f), 3);
EXPECT_EQ (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 0), 0.f);
EXPECT_EQ (
static_cast<int> (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 1) * 100.f), 33);
EXPECT_EQ (
static_cast<int> (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 2) * 100.f), 66);
EXPECT_EQ (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 3), 1.f);
}
//------------------------------------------------------------------------
TEST_CASE (MultiFrameBitmapViewTest, Range)
{
MultiFrameBitmapViewTest testView;
CMultiFrameBitmap bitmap (100, 100);
EXPECT_TRUE (bitmap.setMultiFrameDesc ({{50, 50}, 4, 2}));
testView.setMultiFrameBitmapRange (0, 1);
auto range = testView.getMultiFrameBitmapRange ();
EXPECT_EQ (range.first, 0);
EXPECT_EQ (range.second, 1);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 0.f), 0);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 1.f), 1);
EXPECT_EQ (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 0), 0.f);
EXPECT_EQ (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 1), 1.f);
testView.setMultiFrameBitmapRange (2, -1);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 0.f), 2);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 1.f), 3);
EXPECT_EQ (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 2), 0.f);
EXPECT_EQ (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 3), 1.f);
testView.setMultiFrameBitmapRange (2, 3);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 0.f), 2);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 1.f), 3);
EXPECT_EQ (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 2), 0.f);
EXPECT_EQ (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 3), 1.f);
}
//------------------------------------------------------------------------
TEST_CASE (MultiFrameBitmapViewTest, Inverse)
{
MultiFrameBitmapViewTest testView;
CMultiFrameBitmap bitmap (100, 100);
EXPECT_TRUE (bitmap.setMultiFrameDesc ({{50, 50}, 4, 2}));
testView.setMultiFrameBitmapRange (0, 1);
EXPECT_EQ (testView.getInverseIndex (bitmap, 0), 1);
EXPECT_EQ (testView.getInverseIndex (bitmap, 1), 0);
testView.setMultiFrameBitmapRange (2, -1);
EXPECT_EQ (testView.getInverseIndex (bitmap, 2), 3);
EXPECT_EQ (testView.getInverseIndex (bitmap, 3), 2);
testView.setMultiFrameBitmapRange (2, 3);
EXPECT_EQ (testView.getInverseIndex (bitmap, 2), 3);
EXPECT_EQ (testView.getInverseIndex (bitmap, 3), 2);
}
//------------------------------------------------------------------------
} // VSTGUI
@@ -0,0 +1,31 @@
// 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"
#include "../../../lib/cbuttonstate.h"
namespace VSTGUI {
TEST_CASE (CButtonStateTests, Test)
{
CButtonState s;
EXPECT_EQ (s.getButtonState (), 0);
EXPECT_EQ (s.getModifierState (), 0);
s = kLButton;
EXPECT_TRUE (s.isLeftButton ());
s |= kShift;
EXPECT_TRUE (s.isLeftButton ());
EXPECT_EQ (s.getModifierState (), kShift);
s = kRButton;
EXPECT_TRUE (s.isRightButton ());
s |= kDoubleClick;
EXPECT_TRUE (s.isDoubleClick ());
EXPECT (s & CButtonState (kDoubleClick));
CButtonState s2 (s);
EXPECT_EQ (s, s2);
s2 = ~s;
EXPECT_NE (s, s2);
}
} // VSTGUI
@@ -0,0 +1,36 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cclipboard.h"
#include "../unittests.h"
namespace VSTGUI {
#if !WINDOWS
// the OLE clipboard functionality returns Ole not initialized even tho we call OleInitialize()
// so we disable the test for now on Windows
TEST_CASE (CClipboardTest, String)
{
EXPECT_TRUE (CClipboard::setString ("This is a test string"));
auto cbStr = CClipboard::getString ();
EXPECT_TRUE (cbStr);
EXPECT (*cbStr == "This is a test string");
}
TEST_CASE (CClipboardTest, FilePath)
{
#if WINDOWS
constexpr auto path = "C:\\Windows\\test.txt";
#else
constexpr auto path = "/tmp/test.txt";
#endif
EXPECT_TRUE (CClipboard::setFilePath (path));
auto cbStr = CClipboard::getFilePath ();
EXPECT_TRUE (cbStr);
EXPECT (*cbStr == path);
}
#endif
} // VSTGUI
@@ -0,0 +1,181 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/ccolor.h"
#include "../../../lib/cstring.h"
#include "../unittests.h"
namespace VSTGUI {
using namespace std::string_view_literals;
TEST_CASE (CColorTest, MakeCColor)
{
CColor c = MakeCColor (10, 20, 30, 40);
EXPECT_EQ (c.red, 10);
EXPECT_EQ (c.green, 20);
EXPECT_EQ (c.blue, 30);
EXPECT_EQ (c.alpha, 40);
}
TEST_CASE (CColorTest, Luma)
{
CColor c (30, 50, 80, 255);
EXPECT_EQ (c.getLuma (), 47);
}
TEST_CASE (CColorTest, Lightness)
{
CColor c (80, 30, 50, 255);
EXPECT_EQ (c.getLightness (), 55);
}
TEST_CASE (CColorTest, OperatorEqual)
{
CColor c (30, 40, 50, 60);
EXPECT_TRUE (c == CColor (30, 40, 50, 60));
}
TEST_CASE (CColorTest, OperatorNotEqual)
{
CColor c (30, 40, 50, 60);
EXPECT (c != CColor (50, 40, 50, 60));
EXPECT (c != CColor (30, 50, 50, 60));
EXPECT (c != CColor (30, 40, 60, 60));
EXPECT (c != CColor (30, 40, 50, 70));
}
TEST_CASE (CColorTest, CopyConstructor)
{
CColor c (60, 50, 40, 100);
CColor c2 (c);
EXPECT_EQ (c, c2);
}
TEST_CASE (CColorTest, AssignOperator)
{
CColor c;
c (20, 30, 40, 50);
EXPECT_EQ (c, CColor (20, 30, 40, 50));
}
#if DEBUG
static constexpr auto advanceCount = 16;
#else
static constexpr auto advanceCount = 1;
#endif
TEST_CASE (CColorTest, HSV)
{
double hue;
double saturation;
double value;
for (uint16_t red = 0; red <= 255; red += advanceCount)
{
for (uint16_t green = 0; green <= 255; green += advanceCount)
{
for (uint16_t blue = 0; blue <= 255; blue += advanceCount)
{
CColor c (static_cast<uint8_t> (red), static_cast<uint8_t> (green),
static_cast<uint8_t> (blue));
c.toHSV (hue, saturation, value);
c.fromHSV (hue, saturation, value);
EXPECT_EQ (c.red, red)
EXPECT_EQ (c.green, green)
EXPECT_EQ (c.blue, blue)
EXPECT_EQ (c.alpha, 255);
}
}
}
}
TEST_CASE (CColorTest, HSL)
{
double hue;
double saturation;
double lightness;
for (uint16_t red = 0; red <= 255; red += advanceCount)
{
for (uint16_t green = 0; green <= 255; green += advanceCount)
{
for (uint16_t blue = 0; blue <= 255; blue += advanceCount)
{
CColor c (static_cast<uint8_t> (red), static_cast<uint8_t> (green),
static_cast<uint8_t> (blue));
c.toHSL (hue, saturation, lightness);
c.fromHSL (hue, saturation, lightness);
EXPECT_EQ (c.red, red)
EXPECT_EQ (c.green, green)
EXPECT_EQ (c.blue, blue)
EXPECT_EQ (c.alpha, 255);
}
}
}
}
TEST_CASE (CColorTest, IsColorRepresentation)
{
EXPECT_TRUE (CColor::isColorRepresentation ("#FF00FFFF"sv));
// EXPECT_FALSE (CColor::isColorRepresentation ("#ABCDEFGH"));
EXPECT_FALSE (CColor::isColorRepresentation ("star"sv));
}
TEST_CASE (CColorTest, ToString)
{
auto str = CColor (255, 255, 255).toString ();
EXPECT_EQ (str, "#ffffffff")
}
TEST_CASE (CColorTest, FromString)
{
CColor c;
EXPECT_TRUE (c.fromString ("#FFFFFFFF"sv));
EXPECT_EQ (c, CColor (255, 255, 255));
c.fromString ("#FF0000FF"sv);
EXPECT_EQ (c, CColor (255, 0, 0));
c.fromString ("#00FF00FF"sv);
EXPECT_EQ (c, CColor (0, 255, 0));
c.fromString ("#0000FFFF"sv);
EXPECT_EQ (c, CColor (0, 0, 255));
c.fromString ("#0000FF00"sv);
EXPECT_EQ (c, CColor (0, 0, 255, 0));
}
TEST_CASE (CColorTest, SetNormalized)
{
CColor c (0, 0, 0, 0);
c.setNormRed (1.);
c.setNormGreen (1.);
c.setNormBlue (1.);
c.setNormAlpha (1.);
EXPECT_EQ (c.red, 255);
EXPECT_EQ (c.green, 255);
EXPECT_EQ (c.blue, 255);
EXPECT_EQ (c.alpha, 255);
c.setNormRed (0.5);
c.setNormGreen (0.5);
c.setNormBlue (0.5);
c.setNormAlpha (0.5);
EXPECT_EQ (c.red, 128);
EXPECT_EQ (c.green, 128);
EXPECT_EQ (c.blue, 128);
EXPECT_EQ (c.alpha, 128);
}
TEST_CASE (CColorTest, GetNormalized)
{
CColor r (kRedCColor);
EXPECT_EQ (r.normRed<double> (), 1.);
EXPECT_EQ (r.normGreen<double> (), 0.);
EXPECT_EQ (r.normBlue<double> (), 0.);
EXPECT_EQ (r.normAlpha<double> (), 1.);
r.green = 127;
EXPECT_EQ (r.normGreen<double> (), 127. / 255.);
r.blue = 33;
EXPECT_EQ (r.normBlue<double> (), 33. / 255.);
r.alpha = 250;
EXPECT_EQ (r.normAlpha<double> (), 250. / 255.);
}
} // VSTGUI
@@ -0,0 +1,46 @@
// 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"
#include "../../../lib/cfont.h"
namespace VSTGUI {
TESTCASE(CFontTests,
TEST(attributes,
CFontDesc f;
EXPECT(f.getName ().empty ());
EXPECT(f.getSize () == 0.);
EXPECT(f.getStyle () == kNormalFace);
f.setName ("Test");
EXPECT(strcmp (f.getName (), "Test") == 0);
f.setSize (20.2);
EXPECT(f.getSize () == 20.2);
f.setStyle (kBoldFace|kItalicFace);
EXPECT(f.getStyle () == (kBoldFace|kItalicFace));
CFontDesc::cleanup ();
);
TEST(copyConstructor,
CFontDesc f (*kSystemFont);
EXPECT(f == *kSystemFont);
);
TEST(notEqualOperator,
CFontDesc f (*kSystemFont);
EXPECT(f == *kSystemFont);
f.setSize (f.getSize ()+1);
EXPECT(f != *kSystemFont);
f = *kSystemFont;
f.setStyle (kBoldFace);
EXPECT(f != *kSystemFont);
f = *kSystemFont;
f.setName ("Bla");
EXPECT(f != *kSystemFont);
);
);
} // VSTGUI
@@ -0,0 +1,736 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/ccolor.h"
#include "../../../lib/cframe.h"
#include "../../../lib/events.h"
#include "../unittests.h"
#include "eventhelpers.h"
#include "platform_helper.h"
#include <vector>
namespace VSTGUI {
namespace {
class MouseObserver : public IMouseObserver
{
public:
void reset ()
{
enteredViews.clear ();
exitedViews.clear ();
}
void onMouseEntered (CView* view, CFrame* frame) override { enteredViews.push_back (view); }
void onMouseExited (CView* view, CFrame* frame) override { exitedViews.push_back (view); }
void onMouseEvent (MouseEvent&, CFrame*) override {}
std::vector<CView*> enteredViews;
std::vector<CView*> exitedViews;
};
bool contains (const std::vector<CView*>& c, CView* view)
{
auto it = std::find (c.begin (), c.end (), view);
return it != c.end ();
}
class View : public CView
{
public:
View () : CView (CRect (0, 0, 10, 10)) {}
bool onMouseDownCalled {false};
bool onKeyDownCalled {false};
bool onKeyUpCalled {false};
CMouseEventResult onMouseDown (CPoint& p, const CButtonState& buttons) override
{
onMouseDownCalled = true;
return kMouseEventHandled;
}
#if VSTGUI_ENABLE_DEPRECATED_METHODS
int32_t onKeyDown (VstKeyCode& key) override
{
onKeyDownCalled = true;
return 1;
}
int32_t onKeyUp (VstKeyCode& key) override
{
onKeyUpCalled = true;
return 1;
}
#else
void onKeyboardEvent (KeyboardEvent& event) override
{
if (event.type == EventType::KeyDown)
{
onKeyDownCalled = true;
event.consumed = true;
}
else if (event.type == EventType::KeyUp)
{
onKeyUpCalled = true;
event.consumed = true;
}
}
#endif
};
class ContainerTestingKeyboardEvents : public CViewContainer
{
public:
bool onKeyDownCalled {false};
bool onKeyUpCalled {false};
ContainerTestingKeyboardEvents () : CViewContainer (CRect (0, 0, 20, 20)) {}
#if VSTGUI_ENABLE_DEPRECATED_METHODS
int32_t onKeyDown (VstKeyCode& key) override
{
if (onKeyDownCalled)
return -1;
onKeyDownCalled = true;
return 1;
}
int32_t onKeyUp (VstKeyCode& key) override
{
if (onKeyUpCalled)
return -1;
onKeyUpCalled = true;
return 1;
}
#else
void onKeyboardEvent (KeyboardEvent& event) override
{
if (event.type == EventType::KeyDown)
{
onKeyDownCalled = true;
event.consumed = true;
}
else if (event.type == EventType::KeyUp)
{
onKeyUpCalled = true;
event.consumed = true;
}
}
#endif
};
class KeyboardHook : public IKeyboardHook
{
public:
bool keyDownCalled {false};
bool keyUpCalled {false};
void onKeyboardEvent (KeyboardEvent& event, CFrame* frame) override
{
if (event.type == EventType::KeyDown)
{
keyDownCalled = true;
}
else if (event.type == EventType::KeyUp)
{
keyUpCalled = true;
}
event.consumed = true;
}
};
class CollectInvalidRectView : public CView
{
public:
CRect redrawRect;
uint32_t callCount {0};
CollectInvalidRectView () : CView (CRect (0, 0, 10, 10)) {}
CMouseEventResult onMouseDown (CPoint& p, const CButtonState& buttons) override
{
invalidRect (CRect (3, 3, 8, 8));
invalidRect (CRect (0, 0, 8, 8));
invalidRect (CRect (1, 1, 2, 2));
return kMouseEventHandled;
}
void drawRect (CDrawContext* c, const CRect& r) override
{
++callCount;
redrawRect = r;
CView::drawRect (c, r);
}
};
} // anonymouse
TEST_CASE (CFrameTest, SetZoom)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
EXPECT (frame->setZoom (0.) == false);
EXPECT (frame->setZoom (2.) == true);
EXPECT (frame->getViewSize () == CRect (0, 0, 200, 200));
EXPECT (frame->setZoom (0.5) == true);
EXPECT (frame->getViewSize () == CRect (0, 0, 50, 50));
EXPECT (frame->setZoom (1.0) == true);
EXPECT (frame->getViewSize () == CRect (0, 0, 100, 100));
}
TEST_CASE (CFrameTest, MouseEnterExit)
{
MouseObserver observer;
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
frame->registerMouseObserver (&observer);
auto v1 = new View ();
auto v2 = new View ();
CRect r2 (10, 10, 20, 20);
v2->setViewSize (r2);
v2->setMouseableArea (r2);
frame->addView (v1);
frame->addView (v2);
frame->attached (frame);
dispatchMouseEvent<MouseMoveEvent> (frame, {30., 30.});
EXPECT (observer.enteredViews.size () == 0);
EXPECT (observer.exitedViews.size () == 0);
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {19., 19.});
EXPECT (observer.enteredViews.size () == 1);
EXPECT (contains (observer.enteredViews, v2));
EXPECT (observer.exitedViews.size () == 0);
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {9., 9.});
EXPECT (observer.enteredViews.size () == 1);
EXPECT (contains (observer.enteredViews, v1));
EXPECT (observer.exitedViews.size () == 1);
EXPECT (contains (observer.exitedViews, v2));
frame->unregisterMouseObserver (&observer);
}
TEST_CASE (CFrameTest, MouseEnterExitInContainer)
{
MouseObserver observer;
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
frame->registerMouseObserver (&observer);
auto v1 = new View ();
auto v2 = new View ();
CRect r2 (10, 10, 20, 20);
v2->setViewSize (r2);
v2->setMouseableArea (r2);
auto container = new CViewContainer (CRect (0, 0, 80, 80));
auto container2 = new CViewContainer (CRect (0, 0, 50, 50));
frame->addView (container);
container->addView (container2);
container2->addView (v1);
container2->addView (v2);
frame->attached (frame);
dispatchMouseEvent<MouseMoveEvent> (frame, {90., 90.});
EXPECT (observer.enteredViews.size () == 0);
EXPECT (observer.exitedViews.size () == 0);
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {79., 79.});
EXPECT (observer.enteredViews.size () == 1);
EXPECT (contains (observer.enteredViews, container));
EXPECT (observer.exitedViews.size () == 0);
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {49., 49.});
EXPECT (observer.enteredViews.size () == 1);
EXPECT (contains (observer.enteredViews, container2));
EXPECT (observer.exitedViews.size () == 0);
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {19., 19.});
EXPECT (observer.enteredViews.size () == 1);
EXPECT (contains (observer.enteredViews, v2));
EXPECT (observer.exitedViews.size () == 0);
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {18., 18.});
EXPECT (observer.enteredViews.size () == 0);
EXPECT (observer.exitedViews.size () == 0);
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {9., 9.});
EXPECT (observer.enteredViews.size () == 1);
EXPECT (contains (observer.enteredViews, v1));
EXPECT (observer.exitedViews.size () == 1);
EXPECT (contains (observer.exitedViews, v2));
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {51., 51.});
EXPECT (observer.enteredViews.size () == 0);
EXPECT (observer.exitedViews.size () == 2);
EXPECT (contains (observer.exitedViews, v1));
EXPECT (contains (observer.exitedViews, container2));
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {81., 81.});
EXPECT (observer.enteredViews.size () == 0);
EXPECT (observer.exitedViews.size () == 1);
EXPECT (contains (observer.exitedViews, container));
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {9., 9.});
EXPECT (observer.enteredViews.size () == 3);
EXPECT (observer.exitedViews.size () == 0);
EXPECT (contains (observer.enteredViews, container));
EXPECT (contains (observer.enteredViews, container2));
EXPECT (contains (observer.enteredViews, v1));
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {81., 81.});
EXPECT (observer.enteredViews.size () == 0);
EXPECT (observer.exitedViews.size () == 3);
EXPECT (contains (observer.exitedViews, container));
EXPECT (contains (observer.exitedViews, container2));
EXPECT (contains (observer.exitedViews, v1));
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {79., 79.});
EXPECT (observer.enteredViews.size () == 1);
EXPECT (observer.exitedViews.size () == 0);
EXPECT (contains (observer.enteredViews, container));
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {8., 8.});
EXPECT (observer.enteredViews.size () == 2);
EXPECT (observer.exitedViews.size () == 0);
EXPECT (contains (observer.enteredViews, container2));
EXPECT (contains (observer.enteredViews, v1));
observer.reset ();
frame->unregisterMouseObserver (&observer);
}
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;
CPoint mouseMoveEventPos {};
CMouseEventResult onMouseMoved (CPoint& where, const CButtonState& buttons) override
{
mouseMoveEventPos = where;
return kMouseEventNotHandled;
}
};
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto container = new TestViewContainer (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<MouseMoveEvent> (frame, {30., 30.}, MouseButton::None),
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<MouseMoveEvent> (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)
{
MouseObserver observer;
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
frame->registerMouseObserver (&observer);
auto v1 = new View ();
frame->addView (v1);
frame->attached (frame);
dispatchMouseEvent<MouseMoveEvent> (frame, {5., 5.});
EXPECT (contains (observer.enteredViews, v1));
observer.reset ();
frame->removeView (v1);
EXPECT (contains (observer.exitedViews, v1));
frame->unregisterMouseObserver (&observer);
}
TEST_CASE (CFrameTest, FocusSettings)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
EXPECT (frame->getFocusColor () == kRedCColor);
EXPECT (frame->getFocusWidth () == 2.);
EXPECT (frame->focusDrawingEnabled () == false);
frame->setFocusColor (kWhiteCColor);
EXPECT (frame->getFocusColor () == kWhiteCColor);
frame->setFocusColor (kGreenCColor);
EXPECT (frame->getFocusColor () == kGreenCColor);
frame->setFocusWidth (5.);
EXPECT (frame->getFocusWidth () == 5.);
frame->setFocusWidth (8.);
EXPECT (frame->getFocusWidth () == 8.);
frame->setFocusDrawingEnabled (true);
EXPECT (frame->focusDrawingEnabled () == true);
frame->setFocusDrawingEnabled (false);
EXPECT (frame->focusDrawingEnabled () == false);
}
TEST_CASE (CFrameTest, SetModalView)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto view = shared (new View ());
EXPECT (frame->getModalView () == nullptr);
auto session = frame->beginModalViewSession (view);
EXPECT (session);
EXPECT (frame->getModalView () == view);
auto container = shared (new CViewContainer (CRect (0, 0, 0, 0)));
auto session2 = frame->beginModalViewSession (container);
EXPECT (session2)
EXPECT (frame->getModalView () == container);
EXPECT (frame->endModalViewSession (*session) == false);
EXPECT (frame->endModalViewSession (*session2) == true);
EXPECT (frame->getModalView () == view);
EXPECT (frame->endModalViewSession (*session) == true);
EXPECT (frame->getModalView () == nullptr);
}
TEST_CASE (CFrameTest, KeyDownEvent)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto view = new View ();
frame->addView (view);
frame->attached (frame);
frame->onActivate (true);
KeyboardEvent event;
event.type = EventType::KeyDown;
frame->dispatchEvent (event);
EXPECT (event.consumed == false);
frame->setFocusView (view);
frame->dispatchEvent (event);
EXPECT (event.consumed == true);
event.consumed = false;
EXPECT (view->onKeyDownCalled);
frame->removeAll ();
auto container = new ContainerTestingKeyboardEvents ();
auto view2 = new CView (CRect (0, 0, 10, 10));
container->addView (view2);
frame->addView (container);
frame->setFocusView (view2);
frame->dispatchEvent (event);
EXPECT (event.consumed == true);
event.consumed = false;
EXPECT (container->onKeyDownCalled);
frame->setFocusView (nullptr);
view2->setWantsFocus (true);
EXPECT (frame->getFocusView () == nullptr);
event.virt = VirtualKey::Tab;
frame->dispatchEvent (event);
EXPECT (event.consumed == true);
event.consumed = false;
EXPECT (frame->getFocusView () == view2);
auto view3 = shared (new View ());
auto modalSession = frame->beginModalViewSession (view3);
frame->dispatchEvent (event);
EXPECT (event.consumed == true);
EXPECT (view3->onKeyDownCalled);
frame->endModalViewSession (*modalSession);
}
TEST_CASE (CFrameTest, KeyUpEvent)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto view = new View ();
frame->addView (view);
frame->attached (frame);
frame->onActivate (true);
KeyboardEvent event;
event.type = EventType::KeyUp;
frame->dispatchEvent (event);
EXPECT (event.consumed == false);
frame->setFocusView (view);
frame->dispatchEvent (event);
EXPECT (event.consumed == true);
event.consumed = false;
EXPECT (view->onKeyUpCalled);
frame->removeAll ();
auto container = new ContainerTestingKeyboardEvents ();
auto view2 = new CView (CRect (0, 0, 10, 10));
container->addView (view2);
frame->addView (container);
frame->setFocusView (view2);
frame->dispatchEvent (event);
EXPECT (event.consumed == true);
event.consumed = false;
EXPECT (container->onKeyUpCalled);
auto view3 = shared (new View ());
auto modalSession = frame->beginModalViewSession (view3);
frame->dispatchEvent (event);
EXPECT (event.consumed == true);
EXPECT (view3->onKeyUpCalled);
frame->endModalViewSession (*modalSession);
}
TEST_CASE (CFrameTest, AdvanceNextFocusView)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto view = new View ();
frame->attached (frame);
frame->addView (view);
frame->onActivate (true);
EXPECT (frame->getFocusView () == nullptr);
view->setWantsFocus (true);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view);
frame->removeAll ();
auto container = new CViewContainer ({0., 0., 20., 20.});
auto view2 = new View ();
container->addView (view2);
frame->addView (container);
EXPECT (frame->getFocusView () == nullptr);
view2->setWantsFocus (true);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view2);
auto container2 = new CViewContainer ({0., 0., 20., 20.});
auto view3 = new View ();
container2->addView (view3);
container->addView (container2);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == nullptr);
view3->setWantsFocus (true);
frame->setFocusView (view2);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view3);
auto view4 = new View ();
view4->setWantsFocus (true);
container2->addView (view4);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view4);
auto container3 = new CViewContainer ({0., 0., 20., 20.});
auto view5 = new View ();
view5->setWantsFocus (true);
container3->addView (view5);
container->addView (container3);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view5);
auto view6 = new View ();
view6->setWantsFocus (true);
frame->addView (view6);
frame->advanceNextFocusView (nullptr);
EXPECT (frame->getFocusView () == view6);
}
TEST_CASE (CFrameTest, AdvanceNextFocusViewInModalView)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto view = shared (new View ());
frame->attached (frame);
auto modalSession = frame->beginModalViewSession (view);
EXPECT (frame->getFocusView () == nullptr);
frame->onActivate (true);
view->setWantsFocus (true);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view);
frame->endModalViewSession (*modalSession);
auto container = shared (new CViewContainer ({0., 0., 20., 20.}));
auto view2 = new View ();
container->addView (view2);
modalSession = frame->beginModalViewSession (container);
EXPECT (frame->getFocusView () == nullptr);
view2->setWantsFocus (true);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view2);
auto container2 = new CViewContainer ({0., 0., 20., 20.});
auto view3 = new View ();
container2->addView (view3);
container->addView (container2);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view2);
view3->setWantsFocus (true);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view3);
auto view4 = new View ();
view4->setWantsFocus (true);
container2->addView (view4);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view4);
auto container3 = new CViewContainer ({0., 0., 20., 20.});
auto view5 = new View ();
view5->setWantsFocus (true);
container3->addView (view5);
container->addView (container3);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view5);
frame->endModalViewSession (*modalSession);
}
TEST_CASE (CFrameTest, GetViewAtModalView)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto container = new CViewContainer ({0., 0., 20., 20.});
auto view = new View ();
container->addView (view);
frame->attached (frame);
auto modalSession = frame->beginModalViewSession (container);
EXPECT (frame->getViewAt (CPoint (1, 1)) == container);
EXPECT (frame->getViewAt (CPoint (1, 1), GetViewOptions (GetViewOptions::kDeep)) == view);
EXPECT (frame->getViewAt (CPoint (90, 90)) == nullptr);
frame->endModalViewSession (*modalSession);
}
TEST_CASE (CFrameTest, GetContainerAtModalView)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto container = new CViewContainer ({0., 0., 20., 20.});
CRect r (0, 0, 50, 50);
container->setViewSize (r);
container->setMouseableArea (r);
auto container2 = new CViewContainer ({0., 0., 20., 20.});
container->addView (container2);
frame->attached (frame);
EXPECT (frame->getContainerAt (CPoint (1, 1)) == frame);
auto modalSession = frame->beginModalViewSession (container);
EXPECT (frame->getContainerAt (CPoint (1, 1), GetViewOptions (GetViewOptions::kNone)) ==
container);
EXPECT (frame->getContainerAt (CPoint (1, 1), GetViewOptions (GetViewOptions::kDeep)) ==
container2);
EXPECT (frame->getContainerAt (CPoint (80, 80), GetViewOptions (GetViewOptions::kDeep)) ==
nullptr);
frame->endModalViewSession (*modalSession);
}
TEST_CASE (CFrameTest, MouseDownModalView)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto container = new CViewContainer ({0., 0., 20., 20.});
auto view1 = new View ();
container->addView (view1);
frame->attached (frame);
auto modalSession = frame->beginModalViewSession (container);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (frame, {80., 80.}, MouseButton::Left),
EventConsumeState::NotHandled);
EXPECT_FALSE (view1->onMouseDownCalled);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (frame, {1., 1.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (view1->onMouseDownCalled);
frame->endModalViewSession (*modalSession);
}
TEST_CASE (CFrameTest, Activate)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto view = new View ();
view->setWantsFocus (true);
auto view2 = new View ();
view2->setWantsFocus (true);
frame->addView (view);
frame->addView (view2);
frame->attached (frame);
EXPECT (frame->getFocusView () == nullptr);
frame->onActivate (false);
EXPECT (frame->getFocusView () == nullptr);
frame->onActivate (true);
EXPECT (frame->getFocusView () == view);
frame->setFocusView (view2);
frame->onActivate (false);
EXPECT (frame->getFocusView () == nullptr);
frame->onActivate (true);
EXPECT (frame->getFocusView () == view2);
}
TEST_CASE (CFrameTest, KeyboardHook)
{
KeyboardHook hook;
EXPECT (hook.keyDownCalled == false);
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
frame->attached (frame);
frame->registerKeyboardHook (&hook);
KeyboardEvent event;
event.type = EventType::KeyDown;
frame->dispatchEvent (event);
EXPECT (hook.keyDownCalled);
EXPECT (hook.keyUpCalled == false);
event.type = EventType::KeyUp;
frame->dispatchEvent (event);
EXPECT (hook.keyUpCalled);
frame->unregisterKeyboardHook (&hook);
}
TEST_CASE (CFrameTest, Open)
{
auto platformHandle = UnitTest::PlatformParentHandle::create ();
EXPECT (platformHandle);
auto frame = new CFrame (CRect (0, 0, 100, 100), nullptr);
EXPECT (frame->open (nullptr) == false);
EXPECT (frame->open (platformHandle->getHandle (), platformHandle->getType ()));
frame->close ();
}
TEST_CASE (CFrameTest, SetPosition)
{
auto platformHandle = UnitTest::PlatformParentHandle::create ();
EXPECT (platformHandle);
auto frame = new CFrame (CRect (0, 0, 100, 100), nullptr);
frame->open (platformHandle->getHandle (), platformHandle->getType ());
EXPECT (frame->setPosition (10, 10));
CRect r;
frame->getSize (r);
EXPECT (r == CRect (10, 10, 110, 110));
frame->close ();
}
#if 0
TEST_CASE (CFrameTest, CollectInvalidRectsOnMouseDown)
{
// It is expected that this test failes on Mac OS X 10.11 because of OS changes
auto platformHandle = UnitTest::PlatformParentHandle::create ();
auto frame = new CFrame (CRect (0, 0, 100, 100), nullptr);
auto view = new CollectInvalidRectView ();
frame->addView (view);
frame->open (platformHandle->getHandle (), platformHandle->getType ());
platformHandle->forceRedraw ();
EXPECT (view->callCount == 1);
EXPECT (view->redrawRect == view->getViewSize ());
auto platformFrameCallback = dynamic_cast<IPlatformFrameCallback*> (frame);
MouseDownEvent downEvent (CPoint (), MouseButton::Left);
platformFrameCallback->platformOnEvent (downEvent);
platformHandle->forceRedraw ();
EXPECT (view->redrawRect == CRect (0, 0, 8, 8));
EXPECT (view->callCount == 2);
frame->close ();
}
#endif
#if VSTGUI_ENABLE_DEPRECATED_METHODS
#include "../../../lib/private/disabledeprecatedmessage.h"
TEST_CASE (CFameLegacyTest, SetModalView)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto view = owned (new View ());
EXPECT (frame->getModalView () == nullptr);
EXPECT (frame->setModalView (view));
EXPECT (frame->getModalView () == view);
auto container = owned (new CViewContainer (CRect (0, 0, 0, 0)));
EXPECT (frame->setModalView (container) == false);
EXPECT (frame->setModalView (nullptr));
EXPECT (frame->setModalView (container));
EXPECT (frame->getModalView () == container);
EXPECT (frame->setModalView (nullptr));
EXPECT (frame->getModalView () == nullptr);
}
#include "../../../lib/private/enabledeprecatedmessage.h"
#endif
} // VSTGUI
@@ -0,0 +1,50 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cinvalidrectlist.h"
#include "../unittests.h"
namespace VSTGUI {
TEST_CASE (CInvalidRectListTest, RectEqual)
{
CInvalidRectList list;
EXPECT_TRUE (list.add ({0, 0, 100, 100}));
EXPECT_FALSE (list.add ({0, 0, 100, 100}));
EXPECT_EQ (list.data ().size (), 1u);
}
TEST_CASE (CInvalidRectListTest, AddBiggerOne)
{
CInvalidRectList list;
EXPECT_TRUE (list.add ({0, 0, 100, 100}));
EXPECT_TRUE (list.add ({0, 0, 200, 200}));
EXPECT_EQ (list.data ().size (), 1u);
}
TEST_CASE (CInvalidRectListTest, AddSmallerOne)
{
CInvalidRectList list;
EXPECT_TRUE (list.add ({0, 0, 100, 100}));
EXPECT_FALSE (list.add ({10, 10, 20, 20}));
EXPECT_EQ (list.data ().size (), 1u);
}
TEST_CASE (CInvalidRectListTest, AddOverlappingOne)
{
CInvalidRectList list;
EXPECT_TRUE (list.add ({0, 0, 100, 100}));
EXPECT_TRUE (list.add ({90, 0, 120, 100}));
EXPECT_EQ (list.data ().size (), 1u);
}
TEST_CASE (CInvalidRectListTest, AddMulti)
{
CInvalidRectList list;
EXPECT_TRUE (list.add ({0, 0, 10, 10}));
EXPECT_TRUE (list.add ({20, 20, 30, 30}));
EXPECT_EQ (list.data ().size (), 2u);
}
} // VSTGUI
@@ -0,0 +1,113 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/clinestyle.h"
#include "../unittests.h"
namespace VSTGUI {
TEST_CASE (CLineStyleTest, DefaultConstructor)
{
CLineStyle style;
EXPECT (style.getLineCap () == CLineStyle::kLineCapButt);
EXPECT (style.getLineJoin () == CLineStyle::kLineJoinMiter);
EXPECT (style.getDashPhase () == 0.);
EXPECT (style.getDashCount () == 0);
EXPECT (style.getDashLengths ().size () == 0);
}
TEST_CASE (CLineStyleTest, SolidLine)
{
CLineStyle style;
EXPECT (style == kLineSolid);
}
TEST_CASE (CLineStyleTest, OnOffDashLine)
{
CLineStyle style (CLineStyle::kLineCapButt, CLineStyle::kLineJoinMiter, 0., {1., 1.});
EXPECT (kLineOnOffDash == style);
}
TEST_CASE (CLineStyleTest, DashLengths)
{
CLineStyle style (CLineStyle::kLineCapButt, CLineStyle::kLineJoinMiter, 0., {1., 3., 2.});
EXPECT (style.getDashCount () == 3);
const auto& dashLengths = style.getDashLengths ();
EXPECT (dashLengths[0] == 1.);
EXPECT (dashLengths[1] == 3.);
EXPECT (dashLengths[2] == 2.);
style.getDashLengths ().push_back (6.);
EXPECT (style.getDashCount () == 4);
EXPECT (style.getDashLengths ()[3] == 6.);
}
TEST_CASE (CLineStyleTest, LineCap)
{
CLineStyle style;
style.setLineCap (CLineStyle::kLineCapButt);
EXPECT (style.getLineCap () == CLineStyle::kLineCapButt);
style.setLineCap (CLineStyle::kLineCapRound);
EXPECT (style.getLineCap () == CLineStyle::kLineCapRound);
style.setLineCap (CLineStyle::kLineCapSquare);
EXPECT (style.getLineCap () == CLineStyle::kLineCapSquare);
}
TEST_CASE (CLineStyleTest, LineJoin)
{
CLineStyle style;
style.setLineJoin (CLineStyle::kLineJoinMiter);
EXPECT (style.getLineJoin () == CLineStyle::kLineJoinMiter);
style.setLineJoin (CLineStyle::kLineJoinRound);
EXPECT (style.getLineJoin () == CLineStyle::kLineJoinRound);
style.setLineJoin (CLineStyle::kLineJoinBevel);
EXPECT (style.getLineJoin () == CLineStyle::kLineJoinBevel);
}
TEST_CASE (CLineStyleTest, DashPhase)
{
CLineStyle style;
style.setDashPhase (1.5);
EXPECT (style.getDashPhase () == 1.5);
style.setDashPhase (2.5);
EXPECT (style.getDashPhase () == 2.5);
}
TEST_CASE (CLineStyleTest, CopyConstructor)
{
CLineStyle style;
style.setDashPhase (2.);
style.getDashLengths ().push_back (1.);
style.getDashLengths ().push_back (2.);
CLineStyle s2 (style);
EXPECT (style.getLineCap () == CLineStyle::kLineCapButt);
EXPECT (style.getLineJoin () == CLineStyle::kLineJoinMiter);
EXPECT (style.getDashPhase () == 2.);
EXPECT (style.getDashCount () == 2);
EXPECT (style.getDashLengths ()[0] == 1.);
EXPECT (style.getDashLengths ()[1] == 2.);
}
TEST_CASE (CLineStyleTest, MoveConstructor)
{
CLineStyle style;
style.getDashLengths ().push_back (1.);
style.getDashLengths ().push_back (2.);
CLineStyle s2 (std::move (style));
EXPECT (style.getDashCount () == 0);
EXPECT (s2.getDashCount () == 2);
}
TEST_CASE (CLineStyleTest, VectorConstructor)
{
CLineStyle::CoordVector dashLengths ({2., 4.});
CLineStyle style (CLineStyle::kLineCapButt, CLineStyle::kLineJoinMiter, 0., dashLengths);
EXPECT (dashLengths == style.getDashLengths ());
}
TEST_CASE (CLineStyleTest, UnequalOperator)
{
EXPECT (kLineSolid != kLineOnOffDash);
}
} // VSTGUI
@@ -0,0 +1,77 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cbuttons.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
namespace VSTGUI {
TEST_CASE (CCheckboxTest, MouseEvents)
{
auto b = owned (new CCheckBox (CRect (10, 10, 50, 20)));
b->setValue (b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Right),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {0., 0.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
MouseCancelEvent cancelEvent;
b->dispatchEvent (cancelEvent);
EXPECT_TRUE (cancelEvent.consumed);
EXPECT (b->isEditing () == false);
EXPECT_EQ (b->getValue (), b->getMin ());
}
TEST_CASE (CCheckboxTest, KeyEvents)
{
auto b = owned (new CCheckBox (CRect (10, 10, 50, 20)));
b->setValue (b->getMin ());
KeyboardEvent event;
event.virt = VirtualKey::Return;
b->onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b->getValue () == b->getMax ());
event.consumed.reset ();
b->onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b->getValue () == b->getMin ());
event.virt = VirtualKey::None;
event.character = 't';
event.consumed.reset ();
b->onKeyboardEvent (event);
EXPECT_FALSE (event.consumed);
}
} // VSTGUI
@@ -0,0 +1,153 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/ccontrol.h"
#include "../../../../lib/controls/icontrollistener.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
namespace VSTGUI {
namespace {
class Control : public CControl
{
public:
Control () : CControl (CRect (0, 0, 10, 10)) {}
void draw (CDrawContext* pContext) override {}
#if VSTGUI_ENABLE_DEPRECATED_METHODS
static int32_t mapVstKeyModifier (int32_t vstModifier)
{
#include "../../../../lib/private/disabledeprecatedmessage.h"
return CControl::mapVstKeyModifier (vstModifier);
#include "../../../../lib/private/enabledeprecatedmessage.h"
}
#endif
CLASS_METHODS (Control, CControl)
};
struct Listener : IControlListener
{
bool valueChangedCalled {false};
bool beginEditCalled {false};
bool endEditCalled {false};
void valueChanged (CControl* pControl) override { valueChangedCalled = true; }
void controlBeginEdit (CControl* pControl) override { beginEditCalled = true; }
void controlEndEdit (CControl* pControl) override { endEditCalled = true; }
};
}
TEST_CASE (CControlTest, Editing)
{
Control c;
c.beginEdit ();
EXPECT (c.isEditing ());
c.setValue (0.5f);
c.endEdit ();
EXPECT (c.isEditing () == false);
}
TEST_CASE (CControlTest, Listener)
{
Control c;
Listener l;
c.setListener (&l);
c.beginEdit ();
EXPECT (l.beginEditCalled);
c.setValue (0.5f);
c.valueChanged ();
EXPECT (l.valueChangedCalled);
c.endEdit ();
EXPECT (l.endEditCalled);
}
TEST_CASE (CControlTest, SubListener)
{
Control c;
Listener l;
c.registerControlListener (&l);
c.beginEdit ();
EXPECT (l.beginEditCalled);
c.setValue (0.5f);
c.valueChanged ();
EXPECT (l.valueChangedCalled);
c.endEdit ();
EXPECT (l.endEditCalled);
c.unregisterControlListener (&l);
}
TEST_CASE (CControlTest, SetValueOutOfRange)
{
Control c;
EXPECT (c.getMin () == 0.f);
EXPECT (c.getMax () == 1.f);
c.setValue (0.5f);
EXPECT (c.getValue () == 0.5f);
c.setValue (-0.5f);
EXPECT (c.getValue () == 0.f);
c.setValue (1.5f);
EXPECT (c.getValue () == 1.f);
}
TEST_CASE (CControlTest, SetValueNormalized)
{
Control c;
c.setMin (1.f);
c.setMax (2.f);
c.setValueNormalized (0.f);
EXPECT (c.getValue () == 1.f);
c.setValueNormalized (1.f);
EXPECT (c.getValue () == 2.f);
c.setValueNormalized (0.5f);
EXPECT (c.getValue () == 1.5f);
c.setValueNormalized (-1.f);
EXPECT (c.getValue () == 1.f);
c.setValueNormalized (2.f);
EXPECT (c.getValue () == 2.f);
}
TEST_CASE (CControlTest, CheckDefaultValue)
{
Control c;
c.setValue (c.getDefaultValue () + 0.1f);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (&c, {0., 0.}, MouseButton::Left,
Modifiers (ModifierKey::Control)),
EventConsumeState::Handled + MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT (c.getValue () == c.getDefaultValue ());
c.setValue (c.getDefaultValue () + 0.1f);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (&c, {0., 0.}, MouseButton::Right,
Modifiers (ModifierKey::Control)),
0);
EXPECT (c.getValue () == c.getDefaultValue () + 0.1f);
auto oldCheckDefaultValueFunc = CControl::CheckDefaultValueEventFunc;
CControl::CheckDefaultValueEventFunc = [] (CControl*, MouseDownEvent& event) {
return (event.buttonState.isMiddle () && event.modifiers.is (ModifierKey::Shift));
};
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (&c, {0., 0.}, MouseButton::Left,
Modifiers (ModifierKey::Control)),
0);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (&c, {0., 0.}, MouseButton::Middle,
Modifiers (ModifierKey::Shift)),
EventConsumeState::Handled + MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
CControl::CheckDefaultValueEventFunc = oldCheckDefaultValueFunc;
}
#if VSTGUI_ENABLE_DEPRECATED_METHODS
TEST_CASE (CControlTest, mapVstKeyModifier)
{
EXPECT (Control::mapVstKeyModifier (MODIFIER_SHIFT) == kShift);
EXPECT (Control::mapVstKeyModifier (MODIFIER_ALTERNATE) == kAlt);
EXPECT (Control::mapVstKeyModifier (MODIFIER_COMMAND) == kApple);
EXPECT (Control::mapVstKeyModifier (MODIFIER_CONTROL) == kControl);
}
#endif
} // VSTGUI
@@ -0,0 +1,74 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cbuttons.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
namespace VSTGUI {
TEST_CASE (CKickButtonTest, MouseEvents)
{
auto b = owned (new CKickButton (CRect (10, 10, 50, 20), nullptr, 0, nullptr));
b->setValue (b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Right),
EventConsumeState::NotHandled);
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::NotHandled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {0., 0.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseCancelEvent (b), EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
}
TEST_CASE (CKickButtonTest, KeyEvents)
{
auto b = owned (new CKickButton (CRect (10, 10, 50, 20), nullptr, 0, nullptr));
b->setValue (b->getMin ());
KeyboardEvent event;
event.virt = VirtualKey::Return;
b->onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT_EQ (b->getValue (), b->getMax ());
event.consumed.reset ();
b->onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT_EQ (b->getValue (), b->getMax ());
event.consumed.reset ();
event.type = EventType::KeyUp;
b->onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT_EQ (b->getValue (), b->getMin ());
KeyboardEvent event2;
event2.character = 't';
b->onKeyboardEvent (event2);
EXPECT_FALSE (event2.consumed);
event2.type = EventType::KeyUp;
b->onKeyboardEvent (event2);
EXPECT_FALSE (event2.consumed);
}
} // VSTGUI
@@ -0,0 +1,304 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/clistcontrol.h"
#include "../../../../lib/cscrollview.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
//------------------------------------------------------------------------
namespace VSTGUI {
//------------------------------------------------------------------------
static SharedPointer<CListControl>
createTestListControl (CCoord rowHeight, int32_t numRows = 10,
CListControlRowDesc::Flags rowFlags = CListControlRowDesc::Flags {
CListControlRowDesc::Selectable | CListControlRowDesc::Hoverable})
{
auto listControl = makeOwned<CListControl> (CRect (0, 0, 100, 100));
auto config = makeOwned<StaticListControlConfigurator> (rowHeight, rowFlags);
listControl->setMin (0.f);
listControl->setMax (static_cast<float> (numRows));
listControl->setConfigurator (config);
listControl->recalculateLayout ();
listControl->setValue (0.f);
return listControl;
}
//------------------------------------------------------------------------
static SharedPointer<CScrollView> createScrollViewAndEmbedListControl (CViewContainer* parent,
CListControl* listControl)
{
auto scrollView =
makeOwned<CScrollView> (CRect (0, 0, 100, listControl->getHeight () / 2),
listControl->getViewSize (), CScrollView::kVerticalScrollbar);
scrollView->addView (listControl);
listControl->remember ();
parent->addView (scrollView);
scrollView->attached (parent);
return scrollView;
}
//------------------------------------------------------------------------
static KeyboardEvent makeKeyboardEvent (int32_t c, VirtualKey virt,
ModifierKey modifier = ModifierKey::None)
{
KeyboardEvent event;
event.type = EventType::KeyDown;
event.character = c;
event.virt = virt;
event.modifiers.add (modifier);
return event;
}
TEST_CASE (CListControlTest, minMax)
{
constexpr auto rowHeight = 20;
auto listControl = createTestListControl (rowHeight);
listControl->setMin (-5.f);
listControl->setMax (5.f);
auto row = listControl->getRowAtPoint (CPoint (0, 0));
EXPECT (row);
if (row)
{
EXPECT (*row == -5);
}
row = listControl->getRowAtPoint (CPoint (0, listControl->getHeight () - 1));
EXPECT (row);
if (row)
{
EXPECT (*row == 5);
}
}
TEST_CASE (CListControlTest, MouseRowSelection)
{
constexpr auto rowHeight = 20;
auto listControl = createTestListControl (rowHeight);
dispatchMouseEvent<MouseDownEvent> (listControl, {0., rowHeight}, MouseButton::Left);
dispatchMouseEvent<MouseUpEvent> (listControl, {0., rowHeight}, MouseButton::Left);
EXPECT_EQ (listControl->getValue (), 1.f);
dispatchMouseEvent<MouseDownEvent> (listControl, {0., rowHeight * 3.}, MouseButton::Left);
dispatchMouseEvent<MouseUpEvent> (listControl, {0., rowHeight * 3.}, MouseButton::Left);
EXPECT_EQ (listControl->getValue (), 3.f);
}
TEST_CASE (CListControlTest, Hovering)
{
constexpr auto rowHeight = 20;
constexpr auto numRows = 5;
auto listControl = createTestListControl (rowHeight, numRows);
EXPECT_FALSE (listControl->getHoveredRow ());
dispatchMouseEvent<MouseMoveEvent>(listControl, {10., 5.});
EXPECT_TRUE (listControl->getHoveredRow ());
EXPECT_EQ (*listControl->getHoveredRow (), 0);
dispatchMouseEvent<MouseMoveEvent>(listControl, {10., 5. + rowHeight});
EXPECT_TRUE (listControl->getHoveredRow ());
EXPECT_EQ (*listControl->getHoveredRow (), 1);
dispatchMouseEvent<MouseExitEvent>(listControl, {10., 5. + rowHeight});
EXPECT_FALSE (listControl->getHoveredRow ());
}
TEST_CASE (CListControlTest, RowRect)
{
constexpr auto rowHeight = 20;
auto listControl = createTestListControl (rowHeight);
auto rr = listControl->getRowRect (1);
EXPECT (rr);
if (rr)
{
EXPECT (*rr == CRect (0, rowHeight, 100, rowHeight * 2.));
}
}
TEST_CASE (CListControlTest, KeyDownOnUnselectableRows)
{
constexpr auto rowHeight = 20;
constexpr auto numRows = 20;
auto listControl = createTestListControl (rowHeight, numRows, {});
listControl->setValue (2.f);
EXPECT (listControl->getValue () == 2.f);
auto event = makeKeyboardEvent (0, VirtualKey::Down);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == false);
EXPECT (listControl->getValue () == 2.f);
}
TEST_CASE (CListControlTest, KeyWithModifier)
{
constexpr auto rowHeight = 20;
constexpr auto numRows = 20;
auto listControl = createTestListControl (rowHeight, numRows, {});
listControl->setValue (1.f);
auto event = makeKeyboardEvent (0, VirtualKey::Down, ModifierKey::Shift);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == false);
EXPECT (listControl->getValue () == 1.f);
event = makeKeyboardEvent (0, VirtualKey::Up, ModifierKey::Shift);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == false);
EXPECT (listControl->getValue () == 1.f);
event = makeKeyboardEvent (0, VirtualKey::Home, ModifierKey::Shift);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == false);
EXPECT (listControl->getValue () == 1.f);
event = makeKeyboardEvent (0, VirtualKey::End, ModifierKey::Shift);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == false);
EXPECT (listControl->getValue () == 1.f);
event = makeKeyboardEvent (0, VirtualKey::PageUp, ModifierKey::Shift);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == false);
EXPECT (listControl->getValue () == 1.f);
event = makeKeyboardEvent (0, VirtualKey::PageDown, ModifierKey::Shift);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == false);
EXPECT (listControl->getValue () == 1.f);
}
TEST_CASE (CListControlTest, KeyHome)
{
constexpr auto rowHeight = 20;
auto listControl = createTestListControl (rowHeight);
listControl->setValue (5.f);
EXPECT (listControl->getValue () == 5.f);
auto event = makeKeyboardEvent (0, VirtualKey::Home);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 0.f);
}
TEST_CASE (CListControlTest, KeyEnd)
{
constexpr auto rowHeight = 20;
constexpr auto numRows = 20;
auto listControl = createTestListControl (rowHeight, numRows);
listControl->setValue (0.f);
EXPECT (listControl->getValue () == 0.f);
auto event = makeKeyboardEvent (0, VirtualKey::End);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == numRows);
}
TEST_CASE (CListControlTest, KeyUp)
{
constexpr auto rowHeight = 20;
constexpr auto numRows = 20;
auto listControl = createTestListControl (rowHeight, numRows);
listControl->setValue (2.f);
EXPECT (listControl->getValue () == 2.f);
auto event = makeKeyboardEvent (0, VirtualKey::Up);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 1.f);
event.consumed.reset ();
listControl->setValue (0.f);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == numRows);
}
TEST_CASE (CListControlTest, KeyDown)
{
constexpr auto rowHeight = 20;
constexpr auto numRows = 20;
auto listControl = createTestListControl (rowHeight, numRows);
listControl->setValue (2.f);
EXPECT (listControl->getValue () == 2.f);
auto event = makeKeyboardEvent (0, VirtualKey::Down);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 3.f);
event.consumed.reset ();
listControl->setValue (numRows);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 0.f);
}
TEST_CASE (CListControlTest, PageUp)
{
constexpr auto rowHeight = 20;
constexpr auto numRows = 30;
auto parent = makeOwned<CViewContainer> (CRect (0, 0, 1000, 1000));
auto listControl = createTestListControl (rowHeight, numRows);
auto scrollView = createScrollViewAndEmbedListControl (parent, listControl);
listControl->setValue (numRows);
auto rect = listControl->getRowRect (0);
scrollView->makeRectVisible (*rect);
auto event = makeKeyboardEvent (0, VirtualKey::PageUp);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 15.f);
event.consumed.reset ();
listControl->setValue (16);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 15.f);
event.consumed.reset ();
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 0.f);
scrollView->removed (parent);
parent->removeAll (false);
}
TEST_CASE (CListControlTest, PageDown)
{
constexpr auto rowHeight = 20;
constexpr auto numRows = 30;
auto parent = makeOwned<CViewContainer> (CRect (0, 0, 1000, 1000));
auto listControl = createTestListControl (rowHeight, numRows);
auto scrollView = createScrollViewAndEmbedListControl (parent, listControl);
listControl->setValue (0.f);
auto rect = listControl->getRowRect (numRows);
scrollView->makeRectVisible (*rect);
auto event = makeKeyboardEvent (0, VirtualKey::PageDown);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 15.f);
event.consumed.reset ();
listControl->setValue (14);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 15.f);
event.consumed.reset ();
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 30.f);
scrollView->removed (parent);
parent->removeAll (false);
}
//------------------------------------------------------------------------
} // VSTGUI
@@ -0,0 +1,68 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cbuttons.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
namespace VSTGUI {
TEST_CASE (COnOffButtonTest, MouseEvents)
{
auto b = owned (new COnOffButton (CRect (10, 10, 50, 20)));
b->setValue (b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Right),
EventConsumeState::NotHandled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {0., 0.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseCancelEvent (b), EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
}
TEST_CASE (COnOffButtonTest, KeyEvents)
{
auto b = owned (new COnOffButton (CRect (10, 10, 50, 20)));
b->setValue (b->getMin ());
KeyboardEvent event;
event.virt = VirtualKey::Return;
b->onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT_EQ (b->getValue (), b->getMax ());
event.consumed.reset ();
b->onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT_EQ (b->getValue (), b->getMin ());
event.consumed.reset ();
event.virt = VirtualKey::None;
event.character = 't';
b->onKeyboardEvent (event);
EXPECT_FALSE (event.consumed);
}
} // VSTGUI
@@ -0,0 +1,58 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/coptionmenu.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
namespace VSTGUI {
//------------------------------------------------------------------------
class TestCommandMenuItemTarget
: public CommandMenuItemTargetAdapter
, public NonAtomicReferenceCounted
{
};
TEST_CASE (CCommandMenuItemTest, DescConstructor1)
{
auto target = makeOwned<TestCommandMenuItemTarget> ();
CCommandMenuItem item (
{"Title", "k", 0, nullptr, CMenuItem::kNoFlags, target, "CommandCategory", "CommandName"});
EXPECT_EQ (item.getTitle (), "Title");
EXPECT_EQ (item.getKeycode (), "k");
EXPECT_EQ (item.getIcon (), nullptr);
EXPECT_EQ (item.getItemTarget (), target);
EXPECT_EQ (item.getCommandCategory (), "CommandCategory");
EXPECT_EQ (item.getCommandName (), "CommandName");
}
TEST_CASE (CCommandMenuItemTest, DescConstructor2)
{
auto target = makeOwned<TestCommandMenuItemTarget> ();
CCommandMenuItem item ({"Title", 100, target, "CommandCat", "CmdName"});
EXPECT_EQ (item.getTitle (), "Title");
EXPECT_EQ (item.getItemTarget (), target);
EXPECT_EQ (item.getCommandCategory (), "CommandCat");
EXPECT_EQ (item.getCommandName (), "CmdName");
EXPECT_EQ (item.getTag (), 100);
}
TEST_CASE (CCommandMenuItemTest, DescConstructor3)
{
auto target = makeOwned<TestCommandMenuItemTarget> ();
CCommandMenuItem item ({"MenuItem", target, "CmdCat", "CommandNme"});
EXPECT_EQ (item.getTitle (), "MenuItem");
EXPECT_EQ (item.getItemTarget (), target);
EXPECT_EQ (item.getCommandCategory (), "CmdCat");
EXPECT_EQ (item.getCommandName (), "CommandNme");
}
TEST_CASE (COptionMenuTest, GetMaxWhenEmpty)
{
COptionMenu menu;
EXPECT_EQ (menu.getMax (), 0.f);
}
} // VSTGUI
@@ -0,0 +1,446 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/csegmentbutton.h"
#include "../../../../lib/cviewcontainer.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
namespace VSTGUI {
TEST_CASE (CSegmentButtonTest, AddSegment)
{
CSegmentButton b (CRect (0, 0, 10, 10));
EXPECT (b.getSegments ().size () == 0);
CSegmentButton::Segment s;
s.name = "1";
b.addSegment (s);
EXPECT (b.getSegments ().size () == 1);
s.name = "2";
b.addSegment (s);
EXPECT (b.getSegments ().size () == 2);
EXPECT (b.getSegments ()[1].name == "2");
s.name = "3";
b.addSegment (s, 0);
EXPECT (b.getSegments ().size () == 3);
EXPECT (b.getSegments ()[0].name == "3");
EXPECT (b.getSegments ()[1].name == "1");
EXPECT (b.getSegments ()[2].name == "2");
}
TEST_CASE (CSegmentButtonTest, InsertSegment)
{
CSegmentButton b (CRect (0, 0, 10, 10));
CSegmentButton::Segment s;
s.name = "0";
b.addSegment (std::move (s));
s.name = "1";
b.addSegment (std::move (s), 0);
EXPECT (b.getSegments ()[0].name == "1");
EXPECT (b.getSegments ()[1].name == "0");
}
TEST_CASE (CSegmentButtonTest, RemoveSegment)
{
CSegmentButton b (CRect (0, 0, 10, 10));
CSegmentButton::Segment s;
s.name = "0";
b.addSegment (s);
s.name = "1";
b.addSegment (s);
s.name = "2";
b.addSegment (s);
s.name = "3";
b.addSegment (s);
EXPECT (b.getSegments ().size () == 4);
b.removeSegment (0);
EXPECT (b.getSegments ().size () == 3);
EXPECT (b.getSegments ()[0].name == "1");
EXPECT (b.getSegments ()[1].name == "2");
EXPECT (b.getSegments ()[2].name == "3");
}
TEST_CASE (CSegmentButtonTest, SelectedSegment)
{
CSegmentButton b (CRect (0, 0, 10, 10));
CSegmentButton::Segment s;
s.name = "0";
b.addSegment (s);
s.name = "1";
b.addSegment (s);
s.name = "2";
b.addSegment (s);
s.name = "3";
b.addSegment (s);
b.setSelectedSegment (1);
EXPECT (b.getSelectedSegment () == 1);
b.setSelectedSegment (2);
EXPECT (b.getSelectedSegment () == 2);
b.setSelectedSegment (3);
EXPECT (b.getSelectedSegment () == 3);
b.setSelectedSegment (4);
EXPECT (b.getSelectedSegment () == 3);
b.setSelectedSegment (0);
EXPECT (b.getSelectedSegment () == 0);
}
TEST_CASE (CSegmentButtonTest, RightKeyEvent)
{
CSegmentButton b (CRect (0, 0, 10, 10));
CSegmentButton::Segment s;
s.name = "0";
b.addSegment (s);
s.name = "1";
b.addSegment (s);
s.name = "2";
b.addSegment (s);
b.setStyle (CSegmentButton::Style::kHorizontal);
b.setSelectedSegment (0);
KeyboardEvent event;
event.virt = VirtualKey::Right;
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 2);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 2);
b.setSelectedSegment (1);
b.setStyle (CSegmentButton::Style::kVertical);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
}
TEST_CASE (CSegmentButtonTest, LeftKeyEvent)
{
CSegmentButton b (CRect (0, 0, 10, 10));
CSegmentButton::Segment s;
s.name = "0";
b.addSegment (s);
s.name = "1";
b.addSegment (s);
s.name = "2";
b.addSegment (s);
b.setStyle (CSegmentButton::Style::kHorizontal);
b.setSelectedSegment (2);
KeyboardEvent event;
event.virt = VirtualKey::Left;
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 0);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 0);
b.setSelectedSegment (1);
b.setStyle (CSegmentButton::Style::kVertical);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
}
TEST_CASE (CSegmentButtonTest, DownKeyEvent)
{
CSegmentButton b (CRect (0, 0, 10, 10));
CSegmentButton::Segment s;
s.name = "0";
b.addSegment (s);
s.name = "1";
b.addSegment (s);
s.name = "2";
b.addSegment (s);
b.setStyle (CSegmentButton::Style::kVertical);
b.setSelectedSegment (0);
KeyboardEvent event;
event.virt = VirtualKey::Down;
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 2);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 2);
b.setSelectedSegment (1);
b.setStyle (CSegmentButton::Style::kHorizontal);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
}
TEST_CASE (CSegmentButtonTest, UpKeyEvent)
{
CSegmentButton b (CRect (0, 0, 10, 10));
CSegmentButton::Segment s;
s.name = "0";
b.addSegment (s);
s.name = "1";
b.addSegment (s);
s.name = "2";
b.addSegment (s);
b.setStyle (CSegmentButton::Style::kVertical);
b.setSelectedSegment (2);
KeyboardEvent event;
event.virt = VirtualKey::Up;
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 0);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 0);
b.setSelectedSegment (1);
b.setStyle (CSegmentButton::Style::kHorizontal);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
}
TEST_CASE (CSegmentButtonTest, HorizontalSegmentSizeCalculation)
{
const auto numSegments = 5;
CRect r (0, 0, 100, 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);
EXPECT (b->getSegments ()[0].rect == CRect (0, 0, 20, 100));
EXPECT (b->getSegments ()[1].rect == CRect (20, 0, 40, 100));
EXPECT (b->getSegments ()[2].rect == CRect (40, 0, 60, 100));
EXPECT (b->getSegments ()[3].rect == CRect (60, 0, 80, 100));
EXPECT (b->getSegments ()[4].rect == CRect (80, 0, 100, 100));
parent->removed (root);
}
TEST_CASE (CSegmentButtonTest, VerticalSegmentSizeCalculation)
{
const auto numSegments = 5;
CRect r (0, 0, 100, 100);
auto b = new CSegmentButton (r);
b->setStyle (CSegmentButton::Style::kVertical);
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);
EXPECT (b->getSegments ()[0].rect == CRect (0, 0, 100, 20));
EXPECT (b->getSegments ()[1].rect == CRect (0, 20, 100, 40));
EXPECT (b->getSegments ()[2].rect == CRect (0, 40, 100, 60));
EXPECT (b->getSegments ()[3].rect == CRect (0, 60, 100, 80));
EXPECT (b->getSegments ()[4].rect == CRect (0, 80, 100, 100));
parent->removed (root);
}
TEST_CASE (CSegmentButtonTest, UpdateViewSize)
{
const auto numSegments = 5;
auto b = new CSegmentButton (CRect (0, 0, 50, 100));
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));
CRect r (0, 0, 100, 100);
auto root = owned (new CViewContainer (r));
auto parent = new CViewContainer (r);
root->addView (parent);
parent->addView (b);
parent->attached (root);
EXPECT (b->getSegments ()[0].rect == CRect (0, 0, 10, 100));
EXPECT (b->getSegments ()[1].rect == CRect (10, 0, 20, 100));
EXPECT (b->getSegments ()[2].rect == CRect (20, 0, 30, 100));
EXPECT (b->getSegments ()[3].rect == CRect (30, 0, 40, 100));
EXPECT (b->getSegments ()[4].rect == CRect (40, 0, 50, 100));
b->setViewSize (r);
EXPECT (b->getSegments ()[0].rect == CRect (0, 0, 20, 100));
EXPECT (b->getSegments ()[1].rect == CRect (20, 0, 40, 100));
EXPECT (b->getSegments ()[2].rect == CRect (40, 0, 60, 100));
EXPECT (b->getSegments ()[3].rect == CRect (60, 0, 80, 100));
EXPECT (b->getSegments ()[4].rect == CRect (80, 0, 100, 100));
parent->removed (root);
}
TEST_CASE (CSegmentButtonTest, MouseDownEvent)
{
const auto numSegments = 5;
CRect r (0, 0, 100, 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);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {0., 0.}, MouseButton::Left),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_EQ (b->getSelectedSegment (), 0);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {25., 0.}, MouseButton::Left),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_EQ (b->getSelectedSegment (), 1);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {45., 0.}, MouseButton::Left),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_EQ (b->getSelectedSegment (), 2);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {65., 0.}, MouseButton::Left),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_EQ (b->getSelectedSegment (), 3);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {85., 0.}, MouseButton::Left),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_EQ (b->getSelectedSegment (), 4);
parent->removed (root);
}
TEST_CASE (CSegmentButtonTest, 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_EQ (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 (20 * kSelectedSegment + 5, 0);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, p, MouseButton::Left),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_EQ (b->getSelectedSegment (), kSelectedSegment);
parent->removed (root);
}
TEST_CASE (CSegmentButtonTest, 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_EQ (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_EQ (dispatchMouseEvent<MouseDownEvent> (b, p, MouseButton::Left),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_EQ (b->getSelectedSegment (), kSelectedSegment);
parent->removed (root);
}
TEST_CASE (CSegmentButtonTest, FocusPathSetting)
{
CSegmentButton b (CRect (0, 0, 10, 10));
EXPECT (b.drawFocusOnTop () == false);
}
TEST_CASE (CSegmentButtonTest, MultiSelection)
{
CSegmentButton b (CRect (0, 0, 10, 10));
b.setSelectionMode (CSegmentButton::SelectionMode::kMultiple);
b.addSegment ({});
b.addSegment ({});
b.addSegment ({});
b.selectSegment (0, true);
b.selectSegment (1, false);
b.selectSegment (2, true);
EXPECT (b.isSegmentSelected (0) == true);
EXPECT (b.isSegmentSelected (1) == false);
EXPECT (b.isSegmentSelected (2) == true);
}
TEST_CASE (CSegmentButtonTest, MultiSelectionMaxEntries)
{
CSegmentButton b (CRect (0, 0, 10, 10));
b.setSelectionMode (CSegmentButton::SelectionMode::kMultiple);
CSegmentButton::Segment s;
for (auto i = 0; i < 32; ++i)
{
EXPECT (b.addSegment (s) == true);
}
EXPECT (b.addSegment (s) == false);
EXPECT (b.addSegment (std::move (s)) == false);
}
} // VSTGUI
@@ -0,0 +1,151 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cbuttons.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
namespace VSTGUI {
TEST_CASE (CTextButtonTest, MouseEventsKickStyle)
{
auto b = owned (new CTextButton (CRect (10, 10, 50, 20)));
b->setStyle (CTextButton::kKickStyle);
b->setValue (b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Right),
EventConsumeState::NotHandled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {0., 0.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseCancelEvent (b), EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::NotHandled);
}
TEST_CASE (CTextButtonTest, MouseEventsOnOffStyle)
{
auto b = owned (new CTextButton (CRect (10, 10, 50, 20)));
b->setStyle (CTextButton::kOnOffStyle);
b->setValue (b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Right),
EventConsumeState::NotHandled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {0., 0.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {0., 0.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseCancelEvent (b), EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::NotHandled);
}
TEST_CASE (CTextButtonTest, KeyEvents)
{
auto b = owned (new CTextButton (CRect (10, 10, 50, 20)));
b->setStyle (CTextButton::kOnOffStyle);
b->setValue (b->getMin ());
KeyboardEvent retEvent;
retEvent.virt = VirtualKey::Return;
b->onKeyboardEvent (retEvent);
EXPECT_TRUE (retEvent.consumed);
EXPECT_EQ (b->getValue (), b->getMax ());
retEvent.consumed.reset ();
b->onKeyboardEvent (retEvent);
EXPECT_TRUE (retEvent.consumed);
EXPECT_EQ (b->getValue (), b->getMin ());
KeyboardEvent charEvent;
charEvent.character = 't';
b->onKeyboardEvent (charEvent);
EXPECT_FALSE (charEvent.consumed);
b->setStyle (CTextButton::kKickStyle);
retEvent.consumed.reset ();
b->onKeyboardEvent (retEvent);
EXPECT_TRUE (retEvent.consumed);
EXPECT_EQ (b->getValue (), b->getMin ());
retEvent.consumed.reset ();
b->onKeyboardEvent (retEvent);
EXPECT_TRUE (retEvent.consumed);
EXPECT_EQ (b->getValue (), b->getMin ());
KeyboardEvent upEvent;
upEvent.type = EventType::KeyUp;
upEvent.virt = VirtualKey::Return;
b->onKeyboardEvent (upEvent);
EXPECT_FALSE (upEvent.consumed);
}
TEST_CASE (CTextButtonTest, FocusPathSetting)
{
auto b = owned (new CTextButton (CRect (10, 10, 50, 20)));
EXPECT_FALSE (b->drawFocusOnTop ());
}
} // VSTGUI
@@ -0,0 +1,125 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cxypad.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
namespace VSTGUI {
TEST_CASE (CXYPadTest, valueCalculation)
{
auto value = CXYPad::calculateValue (0.f, 0.f);
float x = 1.f;
float y = 1.f;
CXYPad::calculateXY (value, x, y);
EXPECT (x == 0.f);
EXPECT (y == 0.f);
value = CXYPad::calculateValue (1.f, 0.f);
CXYPad::calculateXY (value, x, y);
EXPECT (x == 1.f);
EXPECT (y == 0.f);
value = CXYPad::calculateValue (0.f, 1.f);
CXYPad::calculateXY (value, x, y);
EXPECT (x == 0.f);
EXPECT (y == 1.f);
value = CXYPad::calculateValue (0.5f, 0.5f);
CXYPad::calculateXY (value, x, y);
EXPECT (x == 0.5f);
EXPECT (y == 0.5f);
value = CXYPad::calculateValue (0.25f, 0.25f);
CXYPad::calculateXY (value, x, y);
EXPECT (x == 0.25f);
EXPECT (y == 0.25f);
}
TEST_CASE (CXYPadTest, MouseLeftDownInteraction)
{
CXYPad pad (CRect (0, 0, 100, 100));
pad.setRoundRectRadius (0.f);
dispatchMouseEvent<MouseDownEvent> (&pad, {0., 0.}, MouseButton::Left);
dispatchMouseEvent<MouseMoveEvent> (&pad, {10., 10.}, MouseButton::Left);
float x = 1.f;
float y = 1.f;
pad.calculateXY (pad.getValue (), x, y);
EXPECT (x == 0.1f);
EXPECT (y == 0.1f);
dispatchMouseEvent<MouseMoveEvent> (&pad, {110., 110.}, MouseButton::Left);
pad.calculateXY (pad.getValue (), x, y);
EXPECT (x == 1.f);
EXPECT (y == 1.f);
dispatchMouseEvent<MouseMoveEvent> (&pad, {-10., -10.}, MouseButton::Left);
pad.calculateXY (pad.getValue (), x, y);
EXPECT (x == 0.f);
EXPECT (y == 0.f);
dispatchMouseEvent<MouseUpEvent> (&pad, {-10., -10.}, MouseButton::Left);
EXPECT_FALSE(pad.isEditing ());
}
TEST_CASE (CXYPadTest, CancelMouseInteraction)
{
CXYPad pad (CRect (0, 0, 100, 100));
float startX {-1.f};
float startY {-1.f};
pad.calculateXY (pad.getValue (), startX, startY);
dispatchMouseEvent<MouseDownEvent> (&pad, {0., 0.}, MouseButton::Left);
dispatchMouseEvent<MouseMoveEvent> (&pad, {10., 10.}, MouseButton::Left);
float x {-1.f};
float y {-1.f};
pad.calculateXY (pad.getValue (), x, y);
EXPECT (startX != x);
EXPECT (startY != y);
dispatchMouseCancelEvent (&pad);
pad.calculateXY (pad.getValue (), x, y);
EXPECT (startX == x);
EXPECT (startY == y);
}
TEST_CASE (CXYPadTest, OtherMouseInteraction)
{
CXYPad pad (CRect (0, 0, 100, 100));
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (&pad, {0., 0.}, MouseButton::Right),
EventConsumeState::NotHandled);
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (&pad, {0., 0.}, MouseButton::Right),
EventConsumeState::NotHandled);
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (&pad, {0., 0.}, MouseButton::Right),
EventConsumeState::NotHandled);
}
TEST_CASE (CXYPadTest, StopTrackingOnMouseExit)
{
CXYPad pad (CRect (0, 0, 100, 100));
pad.setStopTrackingOnMouseExit (true);
pad.setRoundRectRadius (0.f);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (&pad, {0., 0.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (pad.isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (&pad, {50., 50.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (pad.isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (&pad, {150., 150.}, MouseButton::Left),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_FALSE (pad.isEditing ());
}
TEST_CASE (CXYPadTest, MouseWheel)
{
CXYPad pad (CRect (0, 0, 100, 100));
float x = 1.f;
float y = 1.f;
CXYPad::calculateXY (pad.getValue (), x, y);
EXPECT (x == 0.f && y == 0.f);
dispatchMouseWheelEvent (&pad, {1., 1.}, 1., 0.);
CXYPad::calculateXY (pad.getValue (), x, y);
EXPECT (x == pad.getWheelInc () && y == 0.f);
dispatchMouseWheelEvent (&pad, {1., 1.}, 0., 1.);
CXYPad::calculateXY (pad.getValue (), x, y);
EXPECT (x == pad.getWheelInc () && y == pad.getWheelInc ());
}
} // VSTGUI
@@ -0,0 +1,97 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cpoint.h"
#include "../unittests.h"
namespace VSTGUI {
TEST_CASE (CPointTest, Unequal)
{
EXPECT (CPoint (0, 0) != CPoint (1, 1));
EXPECT (CPoint (0, 0) != CPoint (0, 1));
EXPECT (CPoint (0, 0) != CPoint (1, 0));
}
TEST_CASE (CPointTest, Equal)
{
EXPECT (CPoint (0, 0) == CPoint (0, 0));
}
TEST_CASE (CPointTest, OperatorAddAssign)
{
CPoint p (1, 1);
p += CPoint (1, 1);
EXPECT (p == CPoint (2, 2));
}
TEST_CASE (CPointTest, OperatorSubtractAssign)
{
CPoint p (2, 2);
p -= CPoint (1, 1);
EXPECT (p == CPoint (1, 1));
}
TEST_CASE (CPointTest, OperatorAdd)
{
CPoint p (2, 2);
auto p2 = p + CPoint (1, 1);
EXPECT (p2 == CPoint (3, 3));
EXPECT (p == CPoint (2, 2));
}
TEST_CASE (CPointTest, OperatorSubtract)
{
CPoint p (2, 2);
auto p2 = p - CPoint (1, 1);
EXPECT (p2 == CPoint (1, 1));
EXPECT (p == CPoint (2, 2));
}
TEST_CASE (CPointTest, OperatorInverse)
{
CPoint p (2, 2);
auto p2 = -p;
EXPECT (p2 == CPoint (-2, -2));
EXPECT (p == CPoint (2, 2));
}
TEST_CASE (CPointTest, OffsetCoords)
{
CPoint p (1, 2);
p.offset (1, 2);
EXPECT (p == CPoint (2, 4));
}
TEST_CASE (CPointTest, OffsetPoint)
{
CPoint p (1, 2);
p.offset (CPoint (2, 3));
EXPECT (p == CPoint (3, 5));
}
TEST_CASE (CPointTest, OffsetInverse)
{
CPoint p (5, 3);
p.offsetInverse (CPoint (2, 1));
EXPECT (p == CPoint (3, 2));
}
TEST_CASE (CPointTest, MakeIntegral)
{
CPoint p (5.3, 4.2);
p.makeIntegral ();
EXPECT (p == CPoint (5, 4));
p (5.5, 4.5);
p.makeIntegral ();
EXPECT (p == CPoint (6, 5));
p (5.9, 4.1);
p.makeIntegral ();
EXPECT (p == CPoint (6, 4));
p (5.1, 4.501);
p.makeIntegral ();
EXPECT (p == CPoint (5, 5));
}
} // VSTGUI
@@ -0,0 +1,225 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/crect.h"
#include "../unittests.h"
namespace VSTGUI {
TEST_CASE (CRectTest, MakeIntegral)
{
CRect r (0.2, 0.5, 10.8, 12.1);
r.makeIntegral ();
EXPECT (r.left == 0.0)
EXPECT (r.top == 0.0)
EXPECT (r.right == 11.0)
EXPECT (r.bottom == 13.0)
}
TEST_CASE (CRectTest, GetCenter)
{
CRect r (0, 0, 50, 50);
CPoint p = r.getCenter ();
EXPECT (p.x == 25 && p.y == 25)
}
TEST_CASE (CRectTest, CenterInside)
{
CRect r (0, 0, 500, 500);
CRect r2 (0, 0, 10, 10);
r2.centerInside (r);
EXPECT (r2.left == 245 && r2.top == 245 && r2.getWidth () == 10 && r2.getHeight () == 10)
}
TEST_CASE (CRectTest, PointInside)
{
CRect r (0, 0, 250, 250);
CPoint p (50, 50);
EXPECT (r.pointInside (p))
}
TEST_CASE (CRectTest, PointNotInside)
{
CRect r (0, 0, 250, 250);
CPoint p (250, 50);
EXPECT (r.pointInside (p) == false)
}
TEST_CASE (CRectTest, RectOverlap)
{
CRect r (50, 50, 100, 100);
CRect r2 (90, 90, 120, 120);
EXPECT (r.rectOverlap (r2))
}
TEST_CASE (CRectTest, RectNotOverlap)
{
CRect r (50, 50, 100, 100);
CRect r2 (100, 101, 120, 120);
CRect r3 (101, 100, 120, 120);
CRect r4 (0, 0, 40, 40);
CRect r5 (51, 51, 100, 40);
EXPECT (r.rectOverlap (r2) == false)
EXPECT (r.rectOverlap (r3) == false)
EXPECT (r.rectOverlap (r4) == false)
EXPECT (r.rectOverlap (r5) == false)
}
TEST_CASE (CRectTest, Bound)
{
CRect r (50, 50, 100, 100);
CRect r2 (90, 90, 200, 200);
r.bound (r2);
EXPECT (r.left == 90 && r.top == 90 && r.right == 100 && r.bottom == 100)
r (0, 0, 80, 80);
r.bound (r2);
EXPECT (r.left == 90 && r.top == 90 && r.right == 90 && r.bottom == 90)
r (0, 0, 280, 280);
r.bound (r2);
EXPECT (r.left == 90 && r.top == 90 && r.right == 200 && r.bottom == 200)
}
TEST_CASE (CRectTest, Unite)
{
CRect r (20, 20, 40, 40);
CRect r2 (40, 40, 80, 80);
r.unite (r2);
EXPECT (r.left == 20 && r.top == 20 && r.right == 80 && r.bottom == 80)
r (50, 50, 120, 120);
r.unite (r2);
EXPECT (r.left == 40 && r.top == 40 && r.right == 120 && r.bottom == 120)
}
TEST_CASE (CRectTest, SetWidth)
{
CRect r (0., 0., 0., 0.);
EXPECT (r.getWidth () == 0.);
r.setWidth (100.);
EXPECT (r.getWidth () == 100.);
}
TEST_CASE (CRectTest, setHeight)
{
CRect r (0., 0., 0., 0.);
EXPECT (r.getHeight () == 0.);
r.setHeight (100.);
EXPECT (r.getHeight () == 100.);
}
TEST_CASE (CRectTest, Offset)
{
CRect r (0, 0, 10, 10);
r.offset (CPoint (5, 5));
EXPECT (r.left == 5 && r.top == 5 && r.right == 15 && r.bottom == 15);
}
TEST_CASE (CRectTest, OffsetInverse)
{
CRect r (10, 10, 20, 20);
r.offsetInverse (CPoint (5, 5));
EXPECT (r.left == 5 && r.top == 5 && r.right == 15 && r.bottom == 15);
}
TEST_CASE (CRectTest, Extend)
{
CRect r (5, 5, 10, 10);
r.extend (CPoint (5, 5));
EXPECT (r.left == 0 && r.top == 0 && r.right == 15 && r.bottom == 15);
}
TEST_CASE (CRectTest, Assign4CoordOperator)
{
CRect r;
r (0, 0, 15, 15);
EXPECT (r.left == 0 && r.top == 0 && r.right == 15 && r.bottom == 15);
r (15, 15, 0, 0);
EXPECT (r.left == 0 && r.top == 0 && r.right == 15 && r.bottom == 15);
}
TEST_CASE (CRectTest, OriginSizeConstructor)
{
CRect r (CPoint (10, 10), CPoint (10, 10));
EXPECT (r.left == 10 && r.top == 10 && r.right == 20 && r.bottom == 20);
}
TEST_CASE (CRectTest, Inset)
{
CRect r (0., 0., 100., 100.);
r.inset (CPoint (5, 5));
EXPECT (r.left == 5.);
EXPECT (r.top == 5.);
EXPECT (r.right == 95.);
EXPECT (r.bottom == 95.);
}
TEST_CASE (CRectTest, Normalize)
{
CRect r (50, 50, 0, 0);
r.normalize ();
EXPECT (r.left == 0 && r.top == 0 && r.right == 50 && r.bottom == 50);
}
TEST_CASE (CRectTest, Originize)
{
CRect r (50, 50, 150, 150);
r.originize ();
EXPECT (r.left == 0 && r.top == 0 && r.right == 100 && r.bottom == 100);
}
TEST_CASE (CRectTest, MoveTo)
{
CRect r (0, 0, 20, 20);
r.moveTo (CPoint (20, 20));
EXPECT (r.left == 20 && r.top == 20 && r.right == 40 && r.bottom == 40);
}
TEST_CASE (CRectTest, Corners)
{
CRect r (10, 10, 20, 20);
auto topLeft = r.getTopLeft ();
EXPECT (topLeft.x == 10 && topLeft.y == 10);
auto topRight = r.getTopRight ();
EXPECT (topRight.x == 20 && topRight.y == 10);
auto bottomLeft = r.getBottomLeft ();
EXPECT (bottomLeft.x == 10 && bottomLeft.y == 20);
auto bottomRight = r.getBottomRight ();
EXPECT (bottomRight.x == 20 && bottomRight.y == 20);
}
TEST_CASE (CRectTest, SetCorners)
{
CRect r (0, 0, 0, 0);
r.setTopLeft (CPoint (10, 10));
EXPECT (r.left == 10 && r.top == 10);
r.setTopRight (CPoint (10, 10));
EXPECT (r.right == 10 && r.top == 10);
r.setBottomLeft (CPoint (10, 10));
EXPECT (r.left == 10 && r.bottom == 10);
r.setBottomRight (CPoint (10, 10));
EXPECT (r.right == 10 && r.bottom == 10);
}
TEST_CASE (CRectTest, GetSize)
{
CRect r (20, 20, 22, 22);
auto s = r.getSize ();
EXPECT (s.x == 2 && s.y == 2);
}
TEST_CASE (CRectTest, IsEmpty)
{
CRect r (1, 1, 1, 2);
EXPECT (r.isEmpty ());
r (1, 1, 2, 1);
EXPECT (r.isEmpty ());
}
TEST_CASE (CRectTest, OperatorEqual)
{
CRect r1 (0, 1, 2, 3);
CRect r2 (0, 1, 2, 3);
EXPECT (r1 == r2);
}
} // VSTGUI
@@ -0,0 +1,315 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/crowcolumnview.h"
#include "../unittests.h"
#include <vector>
#include <map>
namespace VSTGUI {
using Rects = std::vector<CRect>;
static const CRect templateSize (0., 0., 100., 100.);
static const CRect layoutSize (0., 0., 80., 80.);
// clang-format off
static const Rects childrenDefaultSizes = {
{0., 0., 10., 10.},
{0., 0., 20., 20.},
{0., 0., 30., 30.}
};
using ExpectedResults = std::map<CRowColumnView::LayoutStyle, Rects>;
static const ExpectedResults kRowLayoutChildrenResultSizes = {
{
CRowColumnView::kTopLeft, {
{0., 0., 10., 10.},
{0., 10., 20., 30.},
{0., 30., 30., 60.}
}
},
{
CRowColumnView::kTopCenter, {
{35., 0., 45., 10.},
{30., 10., 50., 30.},
{25., 30., 55., 60.}
}
},
{
CRowColumnView::kTopRight, {
{70., 0., 80., 10.},
{60., 10., 80., 30.},
{50., 30., 80., 60.}
}
},
{
CRowColumnView::kMiddleLeft, {
{0., 10., 10., 20.},
{0., 20., 20., 40.},
{0., 40., 30., 70.}
}
},
{
CRowColumnView::kMiddleCenter, {
{35., 10., 45., 20.},
{30., 20., 50., 40.},
{25., 40., 55., 70.}
}
},
{
CRowColumnView::kMiddleRight, {
{70., 10., 80., 20.},
{60., 20., 80., 40.},
{50., 40., 80., 70.}
}
},
{
CRowColumnView::kBottomLeft, {
{0., 20., 10., 30.},
{0., 30., 20., 50.},
{0., 50., 30., 80.}
}
},
{
CRowColumnView::kBottomCenter, {
{35., 20., 45., 30.},
{30., 30., 50., 50.},
{25., 50., 55., 80.}
}
},
{
CRowColumnView::kBottomRight, {
{70., 20., 80., 30.},
{60., 30., 80., 50.},
{50., 50., 80., 80.}
}
}
};
static const ExpectedResults kColumnLayoutChildrenResultSizes = {
{
CRowColumnView::kTopLeft, {
{0., 0., 10., 10.},
{10., 0., 30., 20.},
{30., 0., 60., 30.}
}
},
{
CRowColumnView::kTopCenter, {
{10., 0., 20., 10.},
{20., 0., 40., 20.},
{40., 0., 70., 30.}
}
},
{
CRowColumnView::kTopRight, {
{20., 0., 30., 10.},
{30., 0., 50., 20.},
{50., 0., 80., 30.}
}
},
{
CRowColumnView::kMiddleLeft, {
{0., 35., 10., 45.},
{10., 30., 30., 50.},
{30., 25., 60., 55.}
}
},
{
CRowColumnView::kMiddleCenter, {
{10., 35., 20., 45.},
{20., 30., 40., 50.},
{40., 25., 70., 55.}
}
},
{
CRowColumnView::kMiddleRight, {
{20., 35., 30., 45.},
{30., 30., 50., 50.},
{50., 25., 80., 55.}
}
},
{
CRowColumnView::kBottomLeft, {
{0., 70., 10., 80.},
{10., 60., 30., 80.},
{30., 50., 60., 80.}
}
},
{
CRowColumnView::kBottomCenter, {
{10., 70., 20., 80.},
{20., 60., 40., 80.},
{40., 50., 70., 80.}
}
},
{
CRowColumnView::kBottomRight, {
{20., 70., 30., 80.},
{30., 60., 50., 80.},
{50., 50., 80., 80.}
}
}
};
static const ExpectedResults kRowLayoutChildrenResultSizesWithSpacing = {
{
CRowColumnView::kMiddleCenter, {
{35., 6., 45., 16.},
{30., 20., 50., 40.},
{25., 44., 55., 74.}
}
}
};
// clang-format on
struct TestData
{
CRowColumnView::LayoutStyle layoutStyle = CRowColumnView::LayoutStyle::kTopLeft;
CRowColumnView::Style style = CRowColumnView::Style::kRowStyle;
double spacing = 0.;
ExpectedResults expected;
};
auto testWithLayoutStyle (const TestData& testData) -> void
{
const auto& expected = testData.expected.find (testData.layoutStyle)->second;
auto rowColumnView = owned (new CRowColumnView (layoutSize));
rowColumnView->setStyle (testData.style);
rowColumnView->setLayoutStyle (testData.layoutStyle);
rowColumnView->setSpacing (testData.spacing);
for (auto& rect : childrenDefaultSizes)
{
auto child = new CView (rect);
rowColumnView->CViewContainer::addView (child);
rowColumnView->layoutViews ();
}
size_t i = 0;
rowColumnView->forEachChild ([&] (CView* child) {
const auto& childrenResults = testData.expected.find (testData.layoutStyle);
auto viewSize = child->getViewSize ();
EXPECT (viewSize == expected.at (i))
i++;
});
}
TEST_CASE (CRowColumnViewTest, RowLayoutTopLeftStyle)
{
testWithLayoutStyle (
{CRowColumnView::kTopLeft, CRowColumnView::kRowStyle, 0., kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutTopCenterStyle)
{
testWithLayoutStyle (
{CRowColumnView::kTopCenter, CRowColumnView::kRowStyle, 0., kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutTopRightStyle)
{
testWithLayoutStyle (
{CRowColumnView::kTopRight, CRowColumnView::kRowStyle, 0., kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutMiddleLeftStyle)
{
testWithLayoutStyle ({CRowColumnView::kMiddleLeft, CRowColumnView::kRowStyle, 0.,
kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutMiddleCenterStyle)
{
testWithLayoutStyle ({CRowColumnView::kMiddleCenter, CRowColumnView::kRowStyle, 0.,
kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutMiddleRightStyle)
{
testWithLayoutStyle ({CRowColumnView::kMiddleRight, CRowColumnView::kRowStyle, 0.,
kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutBottomLeftStyle)
{
testWithLayoutStyle ({CRowColumnView::kBottomLeft, CRowColumnView::kRowStyle, 0.,
kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutBottomCenterStyle)
{
testWithLayoutStyle ({CRowColumnView::kBottomCenter, CRowColumnView::kRowStyle, 0.,
kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutBottomRightStyle)
{
testWithLayoutStyle ({CRowColumnView::kBottomRight, CRowColumnView::kRowStyle, 0.,
kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutTopLeftStyle)
{
testWithLayoutStyle ({CRowColumnView::kTopLeft, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutTopCenterStyle)
{
testWithLayoutStyle ({CRowColumnView::kTopCenter, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutTopRightStyle)
{
testWithLayoutStyle ({CRowColumnView::kTopRight, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutMiddleLeftStyle)
{
testWithLayoutStyle ({CRowColumnView::kMiddleLeft, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutMiddleCenterStyle)
{
testWithLayoutStyle ({CRowColumnView::kMiddleCenter, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutMiddleRightStyle)
{
testWithLayoutStyle ({CRowColumnView::kMiddleRight, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutBottomLeftStyle)
{
testWithLayoutStyle ({CRowColumnView::kBottomLeft, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutBottomCenterStyle)
{
testWithLayoutStyle ({CRowColumnView::kBottomCenter, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutBottomRightStyle)
{
testWithLayoutStyle ({CRowColumnView::kBottomRight, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutMiddleCenterStyleWithSpacing)
{
testWithLayoutStyle ({CRowColumnView::kMiddleCenter, CRowColumnView::kRowStyle, 4.,
kRowLayoutChildrenResultSizesWithSpacing});
}
} // VSTGUI
@@ -0,0 +1,378 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/csplitview.h"
#include "../../../uidescription/icontroller.h"
#include "../unittests.h"
#include "eventhelpers.h"
#include <array>
namespace VSTGUI {
namespace {
class SplitViewController : public IController, public ISplitViewController
{
public:
void valueChanged (CControl* pControl) override {}
bool getSplitViewSizeConstraint (int32_t index, CCoord& minSize, CCoord& maxSize,
CSplitView* splitView) override
{
if (index == 0)
{
minSize = 10;
maxSize = 50;
}
else
{
minSize = 10;
maxSize = 100;
}
return true;
}
ISplitViewSeparatorDrawer* getSplitViewSeparatorDrawer (CSplitView* splitView) override
{
return nullptr;
}
bool storeViewSize (int32_t index, const CCoord& size, CSplitView* splitView) override
{
sizes[static_cast<size_t> (index)] = size;
return true;
}
bool restoreViewSize (int32_t index, CCoord& size, CSplitView* splitView) override
{
if (index == 0)
size = 20;
else if (index == 1)
size = 70;
return true;
}
std::array<CCoord, 2> sizes;
};
class SeparatorSubView : public CView
{
public:
SeparatorSubView () : CView (CRect (0, 0, 0, 0)) {}
bool mouseDownCalled {false};
bool mouseMovedCalled {false};
bool mouseUpCalled {false};
bool mouseCancelCalled {false};
CMouseEventResult onMouseDown (CPoint& where, const CButtonState& buttons) override
{
mouseDownCalled = true;
return kMouseEventHandled;
}
CMouseEventResult onMouseMoved (CPoint& where, const CButtonState& buttons) override
{
mouseMovedCalled = true;
return kMouseEventHandled;
}
CMouseEventResult onMouseUp (CPoint& where, const CButtonState& buttons) override
{
mouseUpCalled = true;
return kMouseEventHandled;
}
CMouseEventResult onMouseCancel () override
{
mouseCancelCalled = true;
return kMouseEventHandled;
}
};
} // anonymous
TEST_CASE (CSplitViewTest, AddViewsHorizontal)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kHorizontal);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 50, 100));
auto view2 = new CView (CRect (0, 0, 40, 100));
sv->addView (view1);
EXPECT (sv->getNbViews () == 1);
sv->addView (view2);
EXPECT (sv->getNbViews () == 3);
EXPECT (view1->getViewSize () == CRect (0, 0, 50, 100));
EXPECT (view2->getViewSize () == CRect (60, 0, 100, 100));
sv->removeView (view1);
EXPECT (sv->getNbViews () == 1);
EXPECT (view2->getViewSize () == CRect (60, 0, 100, 100));
}
TEST_CASE (CSplitViewTest, AddViewsVertical)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kVertical);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 100, 50));
auto view2 = new CView (CRect (0, 0, 100, 40));
sv->addView (view1);
EXPECT (sv->getNbViews () == 1);
sv->addView (view2);
EXPECT (sv->getNbViews () == 3);
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 50));
EXPECT (view2->getViewSize () == CRect (0, 60, 100, 100));
sv->removeView (view2);
EXPECT (sv->getNbViews () == 1);
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 50));
}
TEST_CASE (CSplitViewTest, ResizeAllViewsHorizontal)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kHorizontal);
sv->setResizeMethod (CSplitView::kResizeAllViews);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 50, 100));
auto view2 = new CView (CRect (0, 0, 40, 100));
sv->addView (view1);
sv->addView (view2);
sv->setViewSize (CRect (0, 0, 120, 100));
EXPECT (view1->getViewSize () == CRect (0, 0, 60, 100));
EXPECT (view2->getViewSize () == CRect (70, 0, 120, 100));
}
TEST_CASE (CSplitViewTest, ResizeAllViewsVertical)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kVertical);
sv->setResizeMethod (CSplitView::kResizeAllViews);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 100, 50));
auto view2 = new CView (CRect (0, 0, 100, 40));
sv->addView (view1);
sv->addView (view2);
sv->setViewSize (CRect (0, 0, 100, 120));
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 60));
EXPECT (view2->getViewSize () == CRect (0, 70, 100, 120));
}
TEST_CASE (CSplitViewTest, ResizeFirstViewHorizontal)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kHorizontal);
sv->setResizeMethod (CSplitView::kResizeFirstView);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 50, 100));
auto view2 = new CView (CRect (0, 0, 40, 100));
sv->addView (view1);
sv->addView (view2);
sv->setViewSize (CRect (0, 0, 120, 100));
EXPECT (view1->getViewSize () == CRect (0, 0, 70, 100));
EXPECT (view2->getViewSize () == CRect (80, 0, 120, 100));
}
TEST_CASE (CSplitViewTest, ResizeFirstViewVertical)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kVertical);
sv->setResizeMethod (CSplitView::kResizeFirstView);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 100, 50));
auto view2 = new CView (CRect (0, 0, 100, 40));
sv->addView (view1);
sv->addView (view2);
sv->setViewSize (CRect (0, 0, 100, 120));
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 70));
EXPECT (view2->getViewSize () == CRect (0, 80, 100, 120));
}
TEST_CASE (CSplitViewTest, ResizeLastViewHorizontal)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kHorizontal);
sv->setResizeMethod (CSplitView::kResizeLastView);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 50, 100));
auto view2 = new CView (CRect (0, 0, 40, 100));
sv->addView (view1);
sv->addView (view2);
sv->setViewSize (CRect (0, 0, 120, 100));
EXPECT (view1->getViewSize () == CRect (0, 0, 50, 100));
EXPECT (view2->getViewSize () == CRect (60, 0, 120, 100));
}
TEST_CASE (CSplitViewTest, resizeLastViewVertical)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kVertical);
sv->setResizeMethod (CSplitView::kResizeLastView);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 100, 50));
auto view2 = new CView (CRect (0, 0, 100, 40));
sv->addView (view1);
sv->addView (view2);
sv->setViewSize (CRect (0, 0, 100, 120));
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 50));
EXPECT (view2->getViewSize () == CRect (0, 60, 100, 120));
}
TEST_CASE (CSplitViewTest, ResizeSecondViewHorizontal)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kHorizontal);
sv->setResizeMethod (CSplitView::kResizeSecondView);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 50, 100));
auto view2 = new CView (CRect (0, 0, 20, 100));
auto view3 = new CView (CRect (0, 0, 10, 100));
sv->addView (view1);
sv->addView (view2);
sv->addView (view3);
sv->setViewSize (CRect (0, 0, 120, 100));
EXPECT (view1->getViewSize () == CRect (0, 0, 50, 100));
EXPECT (view2->getViewSize () == CRect (60, 0, 100, 100));
EXPECT (view3->getViewSize () == CRect (110, 0, 120, 100));
}
TEST_CASE (CSplitViewTest, ResizeSecondViewVertical)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kVertical);
sv->setResizeMethod (CSplitView::kResizeSecondView);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 100, 50));
auto view2 = new CView (CRect (0, 0, 100, 20));
auto view3 = new CView (CRect (0, 0, 100, 10));
sv->addView (view1);
sv->addView (view2);
sv->addView (view3);
sv->setViewSize (CRect (0, 0, 100, 120));
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 50));
EXPECT (view2->getViewSize () == CRect (0, 60, 100, 100));
EXPECT (view3->getViewSize () == CRect (0, 110, 100, 120));
}
TEST_CASE (CSplitViewTest, SetSeparatorWidth)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kHorizontal);
sv->setResizeMethod (CSplitView::kResizeFirstView);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 40, 100));
auto view2 = new CView (CRect (0, 0, 20, 100));
auto view3 = new CView (CRect (0, 0, 20, 100));
sv->addView (view1);
sv->addView (view2);
sv->addView (view3);
EXPECT (view1->getViewSize () == CRect (0, 0, 40, 100));
EXPECT (view2->getViewSize () == CRect (50, 0, 70, 100));
EXPECT (view3->getViewSize () == CRect (80, 0, 100, 100));
sv->setSeparatorWidth (20);
EXPECT (view1->getViewSize () == CRect (0, 0, 40, 100));
EXPECT (view2->getViewSize () == CRect (60, 0, 70, 100));
EXPECT (view3->getViewSize () == CRect (90, 0, 100, 100));
}
TEST_CASE (CSplitViewTest, ControllerHorizontal)
{
auto controller = new SplitViewController ();
auto container = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setAttribute (kCViewControllerAttribute, controller);
sv->setStyle (CSplitView::kHorizontal);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 40, 100));
auto view2 = new CView (CRect (0, 0, 50, 100));
sv->addView (view1);
sv->addView (view2);
sv->attached (container);
EXPECT (view1->getViewSize () == CRect (0, 0, 20, 100));
EXPECT (view2->getViewSize () == CRect (30, 0, 100, 100));
dispatchMouseEvent<MouseDownEvent> (sv, {25., 1.}, MouseButton::Left);
dispatchMouseEvent<MouseMoveEvent> (sv, {55., 1.}, MouseButton::Left);
EXPECT (view1->getViewSize () == CRect (0, 0, 50, 100));
EXPECT (view2->getViewSize () == CRect (60, 0, 100, 100));
dispatchMouseEvent<MouseMoveEvent> (sv, {65., 1.}, MouseButton::Left);
EXPECT (view1->getViewSize () == CRect (0, 0, 50, 100));
EXPECT (view2->getViewSize () == CRect (60, 0, 100, 100));
dispatchMouseEvent<MouseMoveEvent> (sv, {15., 1.}, MouseButton::Left);
EXPECT (view1->getViewSize () == CRect (0, 0, 10, 100));
EXPECT (view2->getViewSize () == CRect (20, 0, 100, 100));
dispatchMouseEvent<MouseMoveEvent> (sv, {1., 1.}, MouseButton::Left);
EXPECT (view1->getViewSize () == CRect (0, 0, 10, 100));
EXPECT (view2->getViewSize () == CRect (20, 0, 100, 100));
dispatchMouseEvent<MouseUpEvent> (sv, {1., 1.}, MouseButton::Left);
sv->removed (container);
EXPECT (controller->sizes[0] == 10);
EXPECT (controller->sizes[1] == 80);
}
TEST_CASE (CSplitViewTest, ControllerVertical)
{
auto controller = new SplitViewController ();
auto container = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setAttribute (kCViewControllerAttribute, controller);
sv->setStyle (CSplitView::kVertical);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 100, 40));
auto view2 = new CView (CRect (0, 0, 100, 50));
sv->addView (view1);
sv->addView (view2);
sv->attached (container);
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 20));
EXPECT (view2->getViewSize () == CRect (0, 30, 100, 100));
dispatchMouseEvent<MouseDownEvent> (sv, {1., 25.}, MouseButton::Left);
dispatchMouseEvent<MouseMoveEvent> (sv, {1., 55.}, MouseButton::Left);
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 50));
EXPECT (view2->getViewSize () == CRect (0, 60, 100, 100));
dispatchMouseEvent<MouseMoveEvent> (sv, {1., 65.}, MouseButton::Left);
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 50));
EXPECT (view2->getViewSize () == CRect (0, 60, 100, 100));
dispatchMouseEvent<MouseMoveEvent> (sv, {1., 15.}, MouseButton::Left);
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 10));
EXPECT (view2->getViewSize () == CRect (00, 20, 100, 100));
dispatchMouseEvent<MouseMoveEvent> (sv, {1., 1.}, MouseButton::Left);
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 10));
EXPECT (view2->getViewSize () == CRect (0, 20, 100, 100));
dispatchMouseEvent<MouseUpEvent> (sv, {1., 1.}, MouseButton::Left);
sv->removed (container);
EXPECT (controller->sizes[0] == 10);
EXPECT (controller->sizes[1] == 80);
}
TEST_CASE (CSplitViewTest, SeparatorSubView)
{
auto container = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kHorizontal);
sv->setResizeMethod (CSplitView::kResizeFirstView);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 40, 100));
auto view2 = new CView (CRect (0, 0, 20, 100));
sv->addView (view1);
sv->addView (view2);
auto sepView = new SeparatorSubView ();
sepView->setViewSize (CRect (0, 0, 10, 10));
sepView->setMouseableArea (CRect (0, 0, 10, 10));
sv->addViewToSeparator (0, sepView);
sv->attached (container);
dispatchMouseEvent<MouseDownEvent> (sv, {41., 25.}, MouseButton::Left);
EXPECT (sepView->mouseDownCalled == false);
dispatchMouseEvent<MouseDownEvent> (sv, {41., 1.}, MouseButton::Left);
EXPECT (sepView->mouseDownCalled);
dispatchMouseEvent<MouseMoveEvent> (sv, {41., 3.}, MouseButton::Left);
EXPECT (sepView->mouseMovedCalled);
dispatchMouseEvent<MouseUpEvent> (sv, {41., 3.}, MouseButton::Left);
EXPECT (sepView->mouseUpCalled);
dispatchMouseEvent<MouseDownEvent> (sv, {41., 1.}, MouseButton::Left);
dispatchMouseCancelEvent (sv);
EXPECT (sepView->mouseCancelCalled);
sv->removed (container);
}
} // VSTGUI
@@ -0,0 +1,617 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cstring.h"
#include "../../../lib/cgraphicspath.h"
#include "../../../lib/coffscreencontext.h"
#include "../../../lib/cview.h"
#include "../../../lib/cviewcontainer.h"
#include "../../../lib/dragging.h"
#include "../../../lib/events.h"
#include "../../../lib/idatapackage.h"
#include "../../../lib/iviewlistener.h"
#include "../unittests.h"
#if MAC
#include <CoreFoundation/CoreFoundation.h>
#endif
#include <array>
namespace VSTGUI {
namespace {
class View : public CView
{
public:
View () : CView (CRect (0, 0, 10, 10)) {}
void onIdle () override { onIdleCalled = true; }
bool onIdleCalled {false};
};
struct ViewListener : public IViewListener
{
void viewSizeChanged (CView* view, const CRect& oldSize) override { sizeChangedCalled = true; }
void viewAttached (CView* view) override { attachedCalled = true; }
void viewRemoved (CView* view) override { removedCalled = true; }
void viewLostFocus (CView* view) override { lostFocusCalled = true; }
void viewTookFocus (CView* view) override { tookFocusCalled = true; }
void viewWillDelete (CView* view) override
{
view->unregisterViewListener (this);
willDeleteCalled = true;
}
void viewOnMouseEnabled (CView* view, bool state) override {}
bool sizeChangedCalled {false};
bool attachedCalled {false};
bool removedCalled {false};
bool lostFocusCalled {false};
bool tookFocusCalled {false};
bool willDeleteCalled {false};
};
} // anonymous
TEST_CASE (CViewTest, VisibleState)
{
auto v = owned (new View ());
EXPECT (v->isVisible () == true);
v->setVisible (false);
EXPECT (v->isVisible () == false);
v->setVisible (true);
EXPECT (v->isVisible () == true);
v->setAlphaValue (0.f);
EXPECT (v->isVisible () == false);
}
TEST_CASE (CViewTest, TransparencyState)
{
auto v = owned (new View ());
EXPECT (v->getTransparency () == false);
v->setTransparency (true);
EXPECT (v->getTransparency () == true);
v->setTransparency (false);
EXPECT (v->getTransparency () == false);
}
TEST_CASE (CViewTest, FocusState)
{
auto v = owned (new View ());
EXPECT (v->wantsFocus () == false);
v->setWantsFocus (true);
EXPECT (v->wantsFocus () == true);
v->setWantsFocus (false);
EXPECT (v->wantsFocus () == false);
}
TEST_CASE (CViewTest, IdleState)
{
auto v = owned (new View ());
EXPECT (v->wantsIdle () == false);
v->setWantsIdle (true);
EXPECT (v->wantsIdle () == true);
v->setWantsIdle (false);
EXPECT (v->wantsIdle () == false);
}
TEST_CASE (CViewTest, MouseEnabledState)
{
auto v = owned (new View ());
EXPECT (v->getMouseEnabled () == true);
v->setMouseEnabled (false);
EXPECT (v->getMouseEnabled () == false);
v->setMouseEnabled (true);
EXPECT (v->getMouseEnabled () == true);
}
TEST_CASE (CViewTest, AutosizeFlags)
{
auto v = owned (new View ());
EXPECT (v->getAutosizeFlags () == kAutosizeNone);
v->setAutosizeFlags (kAutosizeLeft);
EXPECT (v->getAutosizeFlags () == kAutosizeLeft);
v->setAutosizeFlags (kAutosizeLeft | kAutosizeTop);
EXPECT (v->getAutosizeFlags () == (kAutosizeLeft | kAutosizeTop));
}
TEST_CASE (CViewTest, Attributes)
{
auto v = owned (new View ());
uint32_t outSize;
void* outData = nullptr;
EXPECT (v->getAttribute (0, 10, outData, outSize) == false);
EXPECT (v->removeAttribute (0) == false);
uint64_t myAttr = 500;
EXPECT (v->setAttribute (0, 0, &myAttr) == false);
EXPECT (v->setAttribute (0, sizeof (myAttr), nullptr) == false);
EXPECT (v->setAttribute ('myAt', sizeof (myAttr), &myAttr) == true);
myAttr = 10;
EXPECT (v->getAttributeSize ('myAt', outSize) == true);
EXPECT (outSize == sizeof (myAttr));
EXPECT (v->getAttribute ('myAt', sizeof (myAttr), &myAttr, outSize) == true);
EXPECT (myAttr == 500);
myAttr = 100;
EXPECT (v->setAttribute ('myAt', sizeof (myAttr), &myAttr) == true);
myAttr = 102;
EXPECT (v->getAttribute ('myAt', sizeof (myAttr), &myAttr, outSize) == true);
EXPECT (myAttr == 100);
EXPECT (v->removeAttribute ('myAt') == true);
EXPECT (v->getAttribute ('myAt', sizeof (myAttr), &myAttr, outSize) == false);
}
TEST_CASE (CViewTest, ResizeAttribute)
{
auto v = owned (new View ());
uint32_t outSize;
uint8_t firstData = 8;
EXPECT (v->setAttribute (0, sizeof (firstData), &firstData));
firstData = 0;
EXPECT (v->getAttribute (0, sizeof (firstData), &firstData, outSize));
EXPECT (firstData == 8);
uint32_t secondData = 32;
EXPECT (v->setAttribute (0, sizeof (secondData), &secondData));
secondData = 0;
EXPECT (v->getAttribute (0, sizeof (firstData), &firstData, outSize) == false);
EXPECT (v->getAttribute (0, sizeof (secondData), &secondData, outSize));
EXPECT (secondData == 32);
}
TEST_CASE (CViewTest, ViewListener)
{
ViewListener listener;
{
auto v = new View ();
v->registerViewListener (&listener);
v->setViewSize (CRect (1, 2, 3, 4));
auto container1 = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto container2 = owned (new CViewContainer (CRect (0, 0, 100, 100)));
container2->addView (v);
container2->attached (container1);
v->takeFocus ();
v->looseFocus ();
container2->removeView (v);
container2->removed (container1);
}
EXPECT (listener.sizeChangedCalled);
EXPECT (listener.attachedCalled);
EXPECT (listener.removedCalled);
EXPECT (listener.tookFocusCalled);
EXPECT (listener.lostFocusCalled);
EXPECT (listener.willDeleteCalled);
}
TEST_CASE (CViewTest, CoordCalculations)
{
auto parent = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto container = owned (new CViewContainer (CRect (50, 50, 100, 100)));
container->attached (parent);
auto v = new View ();
container->addView (v);
CPoint p (0, 0);
v->localToFrame (p);
EXPECT (p.x == 50 && p.y == 50);
p (52, 53);
v->frameToLocal (p);
EXPECT (p.x == 2 && p.y == 3);
container->removed (parent);
}
TEST_CASE (CViewTest, VisibleViewSize)
{
auto parent = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto container = owned (new CViewContainer (CRect (50, 50, 100, 100)));
container->attached (parent);
auto v = new View ();
v->setViewSize (CRect (20, 20, 150, 150));
container->addView (v);
auto visible = v->getVisibleViewSize ();
EXPECT (visible == CRect (20, 20, 50, 50));
container->removeView (v);
container->removed (parent);
}
TEST_CASE (CViewTest, GlobalTransform)
{
auto container1 = owned (new CViewContainer (CRect (0, 0, 10, 10)));
auto container2 = new CViewContainer (CRect (0, 0, 10, 10));
container1->setTransform (CGraphicsTransform ().translate (10, 20));
container2->setTransform (CGraphicsTransform ().translate (15, 35));
container1->addView (container2);
auto v = new View ();
container2->addView (v);
container2->attached (container1);
auto transform = v->getGlobalTransform ();
EXPECT (transform.dx == 25 && transform.dy == 55);
CPoint p (0, 0);
v->translateToGlobal (p);
EXPECT (p.x == 25 && p.y == 55);
v->translateToLocal (p);
EXPECT (p.x == 0 && p.y == 0);
auto p2 = v->translateToGlobal (CRect (0, 0, 1, 1));
EXPECT (p2 == CRect (25, 55, 26, 56));
p2 = v->translateToLocal (CRect (25, 55, 26, 56));
EXPECT (p2 == CRect (0, 0, 1, 1));
container2->removed (container1);
}
TEST_CASE (CViewTest, HitTest)
{
auto v = owned (new View ());
v->setMouseableArea (CRect (20, 20, 40, 40));
EXPECT (v->hitTest (CPoint (5, 5)) == false);
EXPECT (v->hitTest (CPoint (20, 20)) == true);
EXPECT (v->hitTest (CPoint (40, 40)) == false);
}
TEST_CASE (CViewTest, DefaultHandling)
{
auto v = makeOwned<View> ();
KeyboardEvent keyEvent;
v->dispatchEvent (keyEvent);
EXPECT (keyEvent.consumed == false);
keyEvent.type = EventType::KeyUp;
v->dispatchEvent (keyEvent);
EXPECT (keyEvent.consumed == false);
MouseWheelEvent event;
v->onMouseWheelEvent (event);
EXPECT (event.consumed == false);
CPoint p (0, 0);
EXPECT (v->onMouseDown (p, kLButton) == kMouseEventNotImplemented);
EXPECT (v->onMouseUp (p, kLButton) == kMouseEventNotImplemented);
EXPECT (v->onMouseMoved (p, kLButton) == kMouseEventNotImplemented);
EXPECT (v->onMouseCancel () == kMouseEventNotImplemented);
EXPECT (v->onMouseEntered (p, kLButton) == kMouseEventNotImplemented);
EXPECT (v->onMouseExited (p, kLButton) == kMouseEventNotImplemented);
EXPECT (v->notify (nullptr, nullptr) == kMessageUnknown);
EXPECT (v->doDrag (DragDescription (nullptr)) == false);
EXPECT (v->getDropTarget () == nullptr);
EXPECT (v->getEditor () == nullptr);
EXPECT (v->isDirty () == false);
EXPECT (v->sizeToFit () == false);
EXPECT (v->getBackground () == nullptr);
EXPECT (v->getDisabledBackground () == nullptr);
EXPECT (v->getDrawBackground () == nullptr);
EXPECT (v->checkUpdate (CRect (0, 0, 5, 5)) == true);
EXPECT (v->getWidth () == 10);
EXPECT (v->getHeight () == 10);
EXPECT (v->getViewSize () == v->getMouseableArea ());
}
TEST_CASE (CViewTest, PathHitTest)
{
auto v = makeOwned<View> ();
v->setViewSize ({0., 0., 100., 100.});
{
auto drawContext = COffscreenContext::create ({100., 100.});
auto path = owned (drawContext->createGraphicsPath ());
path->addRect ({10., 10., 80., 80.});
v->setHitTestPath (path);
}
EXPECT_FALSE (v->hitTest ({5., 5.}, noEvent ()));
EXPECT_TRUE (v->hitTest ({15., 15.}, noEvent ()));
}
namespace {
class TestView : public CView
{
public:
TestView () : CView (CRect (0, 0, 10, 10))
{
std::fill (called.begin (), called.end (), false);
}
void onMouseDownEvent (MouseDownEvent& event) override
{
called[e2p (EventType::MouseDown)] = true;
}
void onMouseMoveEvent (MouseMoveEvent& event) override
{
called[e2p (EventType::MouseMove)] = true;
}
void onMouseUpEvent (MouseUpEvent& event) override { called[e2p (EventType::MouseUp)] = true; }
void onMouseCancelEvent (MouseCancelEvent& event) override
{
called[e2p (EventType::MouseCancel)] = true;
}
void onMouseEnterEvent (MouseEnterEvent& event) override
{
called[e2p (EventType::MouseEnter)] = true;
}
void onMouseExitEvent (MouseExitEvent& event) override
{
called[e2p (EventType::MouseExit)] = true;
}
void onMouseWheelEvent (MouseWheelEvent& event) override
{
called[e2p (EventType::MouseWheel)] = true;
}
void onZoomGestureEvent (ZoomGestureEvent& event) override
{
called[e2p (EventType::ZoomGesture)] = true;
}
void onKeyboardEvent (KeyboardEvent& event) override { called[e2p (EventType::KeyUp)] = true; }
bool eventCalled (EventType t) const { return called[e2p (t)]; }
private:
static constexpr size_t e2p (EventType t) { return static_cast<size_t> (t); }
std::array<bool, static_cast<size_t> (EventType::KeyDown)> called;
};
struct TestViewEventHandler : IViewEventListener
{
using Func = std::function<void (CView*, Event&)>;
TestViewEventHandler (Func&& func) : func (std::move (func)) {}
void viewOnEvent (CView* view, Event& event) override { func (view, event); }
Func func;
};
} // anonymous
TEST_CASE (CViewTest, ViewEventListenerMouseDownEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
MouseDownEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::MouseDown));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::MouseDown));
}
TEST_CASE (CViewTest, ViewEventListenerMouseMoveEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
MouseMoveEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::MouseMove));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::MouseMove));
}
TEST_CASE (CViewTest, ViewEventListenerMouseUpEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
MouseUpEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::MouseUp));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::MouseUp));
}
TEST_CASE (CViewTest, ViewEventListenerMouseCancelEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
MouseCancelEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::MouseCancel));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::MouseCancel));
}
TEST_CASE (CViewTest, ViewEventListenerMouseEnterEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
MouseEnterEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::MouseEnter));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::MouseEnter));
}
TEST_CASE (CViewTest, ViewEventListenerMouseExitEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
MouseExitEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::MouseExit));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::MouseExit));
}
TEST_CASE (CViewTest, ViewEventListenerMouseWheelEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
MouseWheelEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::MouseWheel));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::MouseWheel));
}
TEST_CASE (CViewTest, ViewEventListenerZoomGestureEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
ZoomGestureEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::ZoomGesture));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::ZoomGesture));
}
TEST_CASE (CViewTest, ViewEventListenerKeyEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
KeyboardEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::KeyUp));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::KeyUp));
}
#if MAC // TODO: Make test work on other platforms too.
TEST_CASE (CViewTest, IdleAfterAttached)
{
auto parent = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto container = owned (new CViewContainer (CRect (50, 50, 100, 100)));
container->attached (parent);
auto v = new View ();
container->addView (v);
v->setWantsIdle (true);
CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.2, false);
EXPECT (v->onIdleCalled == true);
v->setWantsIdle (false);
v->onIdleCalled = false;
CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.2, false);
EXPECT (v->onIdleCalled == false);
container->removeView (v);
container->removed (parent);
}
TEST_CASE (CViewTest, IdleBeforeAttached)
{
auto parent = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto container = owned (new CViewContainer (CRect (50, 50, 100, 100)));
auto v = new View ();
container->addView (v);
v->setWantsIdle (true);
container->attached (parent);
CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.2, true);
EXPECT (v->onIdleCalled == true);
container->removeView (v);
container->removed (parent);
}
#endif
struct DataPackage : IDataPackage
{
UTF8String str;
UTF8String path;
int8_t binary[3];
uint32_t getCount () const override { return 3; }
uint32_t getDataSize (uint32_t index) const override
{
if (index == 0)
return static_cast<uint32_t> (str.length ());
else if (index == 1)
return static_cast<uint32_t> (path.length ());
else if (index == 2)
return 3;
return 0;
}
Type getDataType (uint32_t index) const override
{
if (index == 0)
return kText;
else if (index == 1)
return kFilePath;
else if (index == 2)
return kBinary;
return kError;
}
uint32_t getData (uint32_t index, const void*& buffer, Type& type) const override
{
type = kError;
if (index == 0)
{
buffer = str.data ();
type = kText;
}
else if (index == 1)
{
buffer = path.data ();
type = kFilePath;
}
else if (index == 2)
{
buffer = binary;
type = kBinary;
}
return getDataSize (index);
}
};
TEST_CASE (CDragContainerHelperTest, Count)
{
DataPackage package;
CDragContainerHelper helper (&package);
EXPECT (helper.getCount () == 3);
}
TEST_CASE (CDragContainerHelper, GetType)
{
DataPackage package;
CDragContainerHelper helper (&package);
EXPECT (helper.getType (0) == CDragContainerHelper::kUnicodeText);
EXPECT (helper.getType (1) == CDragContainerHelper::kFile);
EXPECT (helper.getType (2) == CDragContainerHelper::kUnknown);
EXPECT (helper.getType (3) == CDragContainerHelper::kError);
}
TEST_CASE (CDragContainerHelper, Iteration)
{
DataPackage package;
package.str = "Test";
package.path = "/var/tmp/test";
CDragContainerHelper helper (&package);
int32_t size;
int32_t type;
auto res = helper.first (size, type);
EXPECT (res == package.str.data ());
EXPECT (size == static_cast<int32_t> (package.str.length ()));
EXPECT (type == CDragContainerHelper::kUnicodeText);
res = helper.next (size, type);
EXPECT (res == package.path.data ());
EXPECT (size == static_cast<int32_t> (package.path.length ()));
EXPECT (type == CDragContainerHelper::kFile);
res = helper.next (size, type);
EXPECT (res == package.binary);
EXPECT (size == 3);
EXPECT (type == CDragContainerHelper::kUnknown);
res = helper.next (size, type);
EXPECT (res == nullptr);
EXPECT (size == 0);
EXPECT (type == CDragContainerHelper::kError);
}
} // VSTGUI
@@ -0,0 +1,641 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cframe.h"
#include "../../../lib/iviewlistener.h"
#include "../../../lib/ccolor.h"
#include "../../../lib/dragging.h"
#include "../../../lib/events.h"
#include "../unittests.h"
#include "eventhelpers.h"
#include <vector>
namespace VSTGUI {
namespace {
class TestViewContainerListener : public IViewContainerListener
{
public:
void viewContainerViewAdded (CViewContainer* container, CView* view) override
{ viewAddedCalled = true; }
void viewContainerViewRemoved (CViewContainer* container, CView* view) override
{ viewRemovedCalled = true; }
void viewContainerViewZOrderChanged (CViewContainer* container, CView* view) override
{ viewZOrderChangedCalled = true; }
void viewContainerTransformChanged (CViewContainer* container) override
{ transformChangedCalled = true; }
bool viewAddedCalled {false};
bool viewRemovedCalled {false};
bool viewZOrderChangedCalled {false};
bool transformChangedCalled {false};
};
class TestView1 : public CView
{
public:
TestView1 () : CView (CRect (0, 0, 10, 10)) {}
};
class TestView2 : public CView
{
public:
TestView2 () : CView (CRect (10, 10, 20, 20)) {}
};
class MouseEventCheckView : public CView, public DropTargetAdapter
{
public:
MouseEventCheckView () : CView (CRect ()) {}
bool mouseDownCalled {false};
bool mouseMovedCalled {false};
bool mouseUpCalled {false};
bool mouseCancelCalled {false};
bool onDragEnterCalled {false};
bool onDragLeaveCalled {false};
bool onDragMoveCalled {false};
bool onWheelCalled {false};
CMouseEventResult onMouseDown (CPoint& where, const CButtonState& buttons) override
{
mouseDownCalled = true;
return kMouseEventHandled;
}
CMouseEventResult onMouseMoved (CPoint& where, const CButtonState& buttons) override
{
mouseMovedCalled = true;
return kMouseEventHandled;
}
CMouseEventResult onMouseUp (CPoint& where, const CButtonState& buttons) override
{
mouseUpCalled = true;
return kMouseEventHandled;
}
CMouseEventResult onMouseCancel () override
{
mouseCancelCalled = true;
return kMouseEventHandled;
}
SharedPointer<IDropTarget> getDropTarget () override { return this; }
DragOperation onDragEnter (DragEventData data) override
{
onDragEnterCalled = true;
return DragOperation::None;
}
void onDragLeave (DragEventData data) override
{
onDragLeaveCalled = true;
}
DragOperation onDragMove (DragEventData data) override
{
onDragMoveCalled = true;
return DragOperation::None;
}
void onMouseWheelEvent (MouseWheelEvent& event) override
{
onWheelCalled = true;
event.consumed = true;
}
};
} // anonymous
TEST_SUITE_SETUP (CViewContainerTest)
{
SharedPointer<CViewContainer> container = makeOwned<CViewContainer> (CRect (0, 0, 200, 200));
TEST_SUITE_SET_STORAGE (SharedPointer<CViewContainer>, container);
}
TEST_SUITE_TEARDOWN (CViewContainerTest)
{
TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>) = nullptr;
}
TEST_CASE (CViewContainerTest, ChangeViewZOrder)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CView* view1 = new CView (CRect (0, 0, 10, 10));
CView* view2 = new CView (CRect (0, 0, 10, 10));
CView* view3 = new CView (CRect (0, 0, 10, 10));
container->addView (view1);
container->addView (view2);
container->addView (view3);
EXPECT(container->changeViewZOrder (view3, 0));
EXPECT(container->getView (0) == view3);
EXPECT(container->getView (1) == view1);
EXPECT(container->getView (2) == view2);
EXPECT(container->getView (3) == nullptr);
EXPECT(container->changeViewZOrder (view3, 4) == false);
EXPECT(container->changeViewZOrder (view3, 0));
EXPECT(container->changeViewZOrder (view3, 1));
EXPECT(container->getView (0) == view1);
EXPECT(container->getView (1) == view3);
EXPECT(container->getView (2) == view2);
}
TEST_CASE (CViewContainerTest, AddView)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CView* view = new CView (CRect (0, 0, 10, 10));
CView* view2 = new CView (CRect (0, 0, 10, 10));
EXPECT(container->addView (view));
EXPECT(container->addView (view2));
EXPECT(container->isChild (view));
EXPECT(container->isChild (view2));
}
TEST_CASE (CViewContainerTest, AddView2)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto v = new TestView1 ();
CRect r (30, 40, 50, 60);
EXPECT(container->addView (v, r, false));
EXPECT(v->getMouseEnabled () == false);
EXPECT(v->getMouseableArea () == r);
}
TEST_CASE (CViewContainerTest, AddViewTwice)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CView* view = new CView (CRect (0, 0, 10, 10));
EXPECT (container->addView (view));
EXPECT_EXCEPTION (container->addView (view), "view is already added to a container view");
}
TEST_CASE (CViewContainerTest, AddViewToTwoContainer)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CView* view = new CView (CRect (0, 0, 10, 10));
EXPECT (container->addView (view));
auto c2 = owned (new CViewContainer (CRect ()));
EXPECT_EXCEPTION (c2->addView (view), "view is already added to a container view");
}
TEST_CASE (CViewContainerTest, AddViewBeforeOtherView)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CView* view = new CView (CRect (0, 0, 10, 10));
CView* view2 = new CView (CRect (0, 0, 10, 10));
EXPECT (container->addView (view));
EXPECT (container->addView (view2, view));
EXPECT (container->getView (0) == view2)
EXPECT (container->getView (1) == view)
}
TEST_CASE (CViewContainerTest, RemoveView)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto view = makeOwned<CView> (CRect (0, 0, 10, 10));
CView* view2 = new CView (CRect (0, 0, 10, 10));
container->addView (view);
container->addView (view2);
container->removeView (view, false);
EXPECT (container->isChild (view) == false)
EXPECT (container->isChild (view2))
}
TEST_CASE (CViewContainerTest, RemoveAllViews)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto view = makeOwned<CView> (CRect (0, 0, 10, 10));
auto view2 = makeOwned<CView> (CRect (0, 0, 10, 10));
container->addView (view);
container->addView (view2);
container->removeAll (false);
EXPECT (container->isChild (view) == false)
EXPECT (container->isChild (view2) == false)
EXPECT (container->hasChildren () == false)
}
TEST_CASE (CViewContainerTest, AdvanceNextFocusView)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CFrame* frame = new CFrame (CRect (0, 0, 10, 10), nullptr);
frame->onActivate (true);
CView* view1 = new CView (CRect (0, 0, 10, 10));
CView* view2 = new CView (CRect (0, 0, 10, 10));
CView* view3 = new CView (CRect (0, 0, 10, 10));
view1->setWantsFocus (true);
view2->setWantsFocus (true);
view3->setWantsFocus (true);
container->addView (view1);
container->addView (view2);
container->addView (view3);
frame->addView (container);
container->remember ();
frame->attached (frame);
EXPECT (container->advanceNextFocusView (nullptr, true) == true)
EXPECT (frame->getFocusView () == view3)
EXPECT (container->advanceNextFocusView (view3) == false)
frame->setFocusView (nullptr);
EXPECT (container->advanceNextFocusView (nullptr) == true)
EXPECT (frame->getFocusView () == view1)
frame->close ();
}
TEST_CASE (CViewContainerTest, AutoSizeAll)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CView* view = new CView (container->getViewSize ());
view->setAutosizeFlags (kAutosizeAll);
container->addView (view);
container->setAutosizingEnabled (true);
EXPECT (container->getAutosizingEnabled ());
container->setViewSize (CRect (0, 0, 500, 500));
EXPECT (view->getViewSize ().left == 0)
EXPECT (view->getViewSize ().top == 0)
EXPECT (view->getViewSize ().right == 500)
EXPECT (view->getViewSize ().bottom == 500)
container->setAutosizingEnabled (false);
EXPECT (container->getAutosizingEnabled () == false);
}
TEST_CASE (CViewContainerTest, SizeToFit)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CRect r (10, 10, 20, 20);
CView* view = new CView (r);
container->addView (view);
container->sizeToFit ();
EXPECT (container->getViewSize ().right == 30)
EXPECT (container->getViewSize ().bottom == 30)
}
TEST_CASE (CViewContainerTest, GetViewAt)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CRect r (10, 10, 20, 20);
CView* view = new CView (r);
container->addView (view);
EXPECT (view == container->getViewAt (r.getTopLeft ()));
EXPECT (nullptr == container->getViewAt (CPoint (0, 0)));
}
TEST_CASE (CViewContainerTest, GetViewAtDeep)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CRect r (10, 10, 20, 20);
CViewContainer* container2 = new CViewContainer (r);
container->addView (container2);
CRect r2 (2, 2, 4, 4);
CView* view = new CView (r2);
container2->addView (view);
EXPECT (container->getViewAt (CPoint (12, 12)) == nullptr);
EXPECT (container->getViewAt (CPoint (12, 12), GetViewOptions (GetViewOptions::kDeep)) == view);
EXPECT (container->getViewAt (CPoint (11, 11), GetViewOptions (GetViewOptions::kDeep)) ==
nullptr);
EXPECT (container->getViewAt (
CPoint (11, 11),
GetViewOptions (GetViewOptions::kDeep | GetViewOptions::kIncludeViewContainer)) ==
container2);
}
TEST_CASE (CViewContainerTest, Listener)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
TestViewContainerListener listener;
container->registerViewContainerListener (&listener);
auto view = new CView (CRect (0, 0, 0, 0));
container->addView (view);
EXPECT (listener.viewAddedCalled == true);
container->removeView (view, false);
EXPECT (listener.viewRemovedCalled == true);
auto view2 = new CView (CRect (0, 0, 0, 0));
container->addView (view);
container->addView (view2);
container->changeViewZOrder (view2, 0);
EXPECT (listener.viewZOrderChangedCalled == true);
container->setTransform (CGraphicsTransform ().translate (1., 1.));
EXPECT (listener.transformChangedCalled == true);
container->unregisterViewContainerListener (&listener);
}
TEST_CASE (CViewContainerTest, BackgroundColor)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
container->setBackgroundColor (kGreenCColor);
EXPECT (container->getBackgroundColor () == kGreenCColor);
container->setBackgroundColorDrawStyle (kDrawFilledAndStroked);
EXPECT (container->getBackgroundColorDrawStyle () == kDrawFilledAndStroked);
container->setBackgroundColorDrawStyle (kDrawFilled);
EXPECT (container->getBackgroundColorDrawStyle () == kDrawFilled);
container->setBackgroundColorDrawStyle (kDrawStroked);
EXPECT (container->getBackgroundColorDrawStyle () == kDrawStroked);
}
TEST_CASE (CViewContainerTest, BackgroundOffset)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
container->setBackgroundOffset (CPoint (10, 10));
EXPECT (container->getBackgroundOffset () == CPoint (10, 10));
}
TEST_CASE (CViewContainerTest, GetChildViewsOfType)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
container->addView (new TestView1 ());
container->addView (new TestView2 ());
std::vector<TestView1*> r;
container->getChildViewsOfType<TestView1> (r);
EXPECT (r.size () == 1);
EXPECT (r[0] == container->getView (0));
std::vector<TestView2*> r2;
container->getChildViewsOfType<TestView2> (r2);
EXPECT (r2.size () == 1);
EXPECT (r2[0] == container->getView (1));
auto c2 = owned (new CViewContainer (CRect (0, 0, 100, 100)));
c2->addView (container);
r.clear ();
c2->getChildViewsOfType<TestView1> (r);
EXPECT (r.size () == 0);
c2->getChildViewsOfType<TestView1> (r, true);
EXPECT (r.size () == 1);
c2->removeView (container, false);
}
TEST_CASE (CViewContainerTest, Iterator)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto v1 = new TestView1 ();
auto v2 = new TestView2 ();
container->addView (v1);
container->addView (v2);
ViewIterator it (container);
EXPECT (*it == v1);
++it;
EXPECT (*it == v2);
--it;
EXPECT (*it == v1);
auto it2 = it++;
EXPECT (*it2 == v1);
EXPECT (*it == v2);
}
TEST_CASE (CViewContainerTest, ReverseIterator)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto v1 = new TestView1 ();
auto v2 = new TestView2 ();
container->addView (v1);
container->addView (v2);
ReverseViewIterator it (container);
EXPECT (*it == v2);
++it;
EXPECT (*it == v1);
--it;
EXPECT (*it == v2);
auto it2 = it++;
EXPECT (*it2 == v2);
EXPECT (*it == v1);
++it;
EXPECT (*it == nullptr);
}
TEST_CASE (CViewContainerTest, MouseEventsInEmptyContainer)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (container, {}), EventConsumeState::NotHandled);
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (container, {}), EventConsumeState::NotHandled);
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (container, {}), EventConsumeState::NotHandled);
EXPECT_EQ (dispatchMouseCancelEvent (container), EventConsumeState::NotHandled);
EXPECT_EQ (dispatchMouseWheelEvent (container, {}, 1., 0.), EventConsumeState::NotHandled);
}
TEST_CASE (CViewContainerTest, MouseEvents)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto v1 = new MouseEventCheckView ();
auto v2 = new MouseEventCheckView ();
CRect r1 (0, 0, 50, 50);
CRect r2 (50, 0, 100, 50);
v1->setViewSize (r1);
v1->setMouseableArea (r1);
v2->setViewSize (r2);
v2->setMouseableArea (r2);
container->addView (v1);
container->addView (v2);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (container, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (v1->mouseDownCalled);
EXPECT_FALSE (v2->mouseDownCalled);
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (container, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (v1->mouseMovedCalled);
EXPECT_FALSE (v2->mouseMovedCalled);
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (container, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (v1->mouseUpCalled);
EXPECT_FALSE (v2->mouseUpCalled);
EXPECT_EQ (dispatchMouseWheelEvent (container, {60., 10.}, 0.5, 0.),
EventConsumeState::Handled);
EXPECT_FALSE (v1->onWheelCalled);
EXPECT_TRUE (v2->onWheelCalled);
}
TEST_CASE (CViewContainerTest, MouseCancel)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto v1 = new MouseEventCheckView ();
CRect r1 (0, 0, 50, 50);
v1->setViewSize (r1);
v1->setMouseableArea (r1);
container->addView (v1);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (container, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (v1->mouseDownCalled);
EXPECT_EQ (dispatchMouseCancelEvent (container), EventConsumeState::Handled);
EXPECT_TRUE (v1->mouseCancelCalled);
}
TEST_CASE (CViewContainerTest, DragEvents)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto v1 = new MouseEventCheckView ();
auto v2 = new MouseEventCheckView ();
CRect r1 (0, 0, 50, 50);
CRect r2 (50, 0, 100, 50);
v1->setViewSize (r1);
v1->setMouseableArea (r1);
v2->setViewSize (r2);
v2->setMouseableArea (r2);
container->addView (v1);
container->addView (v2);
DragEventData data;
data.drag = nullptr;
data.pos = CPoint (10, 10);
data.modifiers.clear ();
auto dropTarget = container->getDropTarget ();
dropTarget->onDragEnter (data);
EXPECT (v1->onDragEnterCalled);
EXPECT (v2->onDragEnterCalled == false);
dropTarget->onDragMove (data);
EXPECT (v1->onDragMoveCalled);
EXPECT (v2->onDragMoveCalled == false);
dropTarget->onDragLeave (data);
EXPECT (v1->onDragLeaveCalled);
EXPECT (v2->onDragLeaveCalled == false);
}
TEST_CASE (CViewContainerTest, DragMoveBetweenTwoViews)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto v1 = new MouseEventCheckView ();
auto v2 = new MouseEventCheckView ();
CRect r1 (0, 0, 50, 50);
CRect r2 (50, 0, 100, 50);
v1->setViewSize (r1);
v1->setMouseableArea (r1);
v2->setViewSize (r2);
v2->setMouseableArea (r2);
container->addView (v1);
container->addView (v2);
DragEventData data;
data.drag = nullptr;
data.pos = CPoint (10, 10);
data.modifiers.clear ();
auto dropTarget = container->getDropTarget ();
dropTarget->onDragEnter (data);
EXPECT (v1->onDragEnterCalled);
EXPECT (v2->onDragEnterCalled == false);
data.pos (60, 10);
dropTarget->onDragMove (data);
EXPECT (v1->onDragLeaveCalled);
EXPECT (v2->onDragEnterCalled);
}
TEST_CASE (CViewContainerTest,
MouseDownOnTransparentViewWithoutMouseSupportHidingSubviewWithMouseSupport)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CRect r1 (0, 0, 50, 50);
auto v1 = new MouseEventCheckView ();
auto v2 = new CView (r1);
v2->setTransparency (false);
v1->setViewSize (r1);
v1->setMouseableArea (r1);
container->addView (v1);
container->addView (v2);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (container, {10., 10.}, MouseButton::Left),
EventConsumeState::NotHandled);
EXPECT_FALSE (v1->mouseDownCalled);
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (container, {10., 10.}, MouseButton::Left),
EventConsumeState::NotHandled);
EXPECT_FALSE (v1->mouseMovedCalled);
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (container, {10., 10.}, MouseButton::Left),
EventConsumeState::NotHandled);
EXPECT_FALSE (v1->mouseUpCalled);
}
TEST_CASE (CViewContainerTest, GetViewsAt)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto v1 = new TestView1 ();
auto v2 = new TestView1 ();
auto c1 = new CViewContainer (CRect (0, 0, 10, 10));
auto v1c1 = new TestView1 ();
v1c1->setVisible (false);
auto v2c1 = new TestView1 ();
c1->addView (v1c1);
c1->addView (v2c1);
v2->setMouseEnabled (false);
container->addView (v1);
container->addView (v2);
container->addView (c1);
CViewContainer::ViewList views;
container->getViewsAt (CPoint (0, 0), views, GetViewOptions (GetViewOptions::kNone));
EXPECT (views.size () == 2);
views.clear ();
container->getViewsAt (CPoint (0, 0), views, GetViewOptions (GetViewOptions::kMouseEnabled));
EXPECT (views.size () == 1);
views.clear ();
container->getViewsAt (CPoint (0, 0), views,
GetViewOptions (GetViewOptions::kIncludeViewContainer));
EXPECT (views.size () == 3);
views.clear ();
container->getViewsAt (CPoint (0, 0), views, GetViewOptions (GetViewOptions::kDeep));
EXPECT (views.size () == 3);
views.clear ();
container->getViewsAt (
CPoint (0, 0), views,
GetViewOptions (GetViewOptions::kDeep | GetViewOptions::kIncludeInvisible));
EXPECT (views.size () == 4);
}
TEST_CASE (CViewContainerTest, GetContainerAt)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto c1 = new CViewContainer (CRect (0, 0, 10, 10));
auto c2 = new CViewContainer (CRect (0, 0, 10, 10));
auto c3 = new CViewContainer (CRect (0, 0, 10, 10));
c2->setMouseEnabled (false);
c3->setVisible (false);
c2->addView (c3);
container->addView (c1);
container->addView (c2);
auto res = container->getContainerAt (CPoint (0, 0), GetViewOptions (GetViewOptions::kNone));
EXPECT (res == container);
res = container->getContainerAt (CPoint (0, 0), GetViewOptions (GetViewOptions::kDeep));
EXPECT (res == c2);
res = container->getContainerAt (
CPoint (0, 0), GetViewOptions (GetViewOptions::kDeep | GetViewOptions::kIncludeInvisible));
EXPECT (res == c3);
res = container->getContainerAt (
CPoint (0, 0), GetViewOptions (GetViewOptions::kDeep | GetViewOptions::kMouseEnabled));
EXPECT (res == c1);
}
} // namespaces
@@ -0,0 +1,205 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/enumbitset.h"
#include "../unittests.h"
//------------------------------------------------------------------------
namespace VSTGUI {
//------------------------------------------------------------------------
enum class Flag
{
One,
Two,
Three,
};
using Flags = EnumBitset<Flag>;
//------------------------------------------------------------------------
enum class FlagMask : uint8_t
{
One = 1 << 0,
Two = 1 << 1,
Three = 1 << 2,
};
using FlagMasks = EnumBitset<FlagMask, true>;
//------------------------------------------------------------------------
TEST_CASE (EnumBitsetTest, InitTest)
{
{
Flags f;
EXPECT_EQ (f.value (), 0);
}
{
Flags f (Flag::Two);
EXPECT_EQ (f.value (), 2);
}
{
Flags f ({Flag::One, Flag::Two});
EXPECT_EQ (f.value (), 3);
}
{
FlagMasks f;
EXPECT_EQ (f.value (), 0);
}
{
FlagMasks f (FlagMask::Two);
EXPECT_EQ (f.value (), 2);
}
{
FlagMasks f ({FlagMask::One, FlagMask::Two});
EXPECT_EQ (f.value (), 3);
}
}
//------------------------------------------------------------------------
TEST_CASE (EnumBitsetTest, AssignmentTest)
{
{
Flags f;
f = Flag::One;
EXPECT_EQ (f.value (), 1);
Flags f2 = Flag::Two;
EXPECT_EQ (f2.value (), 2);
f = f2;
EXPECT_EQ (f.value (), f2.value ());
f2.exlusive (Flag::Three);
EXPECT_EQ (f2.value (), 4);
}
{
FlagMasks f;
f = FlagMask::One;
EXPECT_EQ (f.value (), 1);
FlagMasks f2 = FlagMask::Two;
EXPECT_EQ (f2.value (), 2);
f = f2;
EXPECT_EQ (f.value (), f2.value ());
f2.exlusive (FlagMask::Three);
EXPECT_EQ (f2.value (), 4);
}
}
//------------------------------------------------------------------------
TEST_CASE (EnumBitsetTest, AddRemoveTest)
{
{
Flags f;
f.add (Flag::One);
EXPECT_EQ (f.value (), 1);
f.add (Flag::Two);
EXPECT_EQ (f.value (), 3);
f.remove (Flag::One);
EXPECT_EQ (f.value (), 2);
f.clear ();
f |= Flag::One;
EXPECT_EQ (f.value (), 1);
f |= Flag::Two;
EXPECT_EQ (f.value (), 3);
f ^= Flag::One;
EXPECT_EQ (f.value (), 2);
f.clear ();
f << Flag::One;
EXPECT_EQ (f.value (), 1);
f << Flag::Two;
EXPECT_EQ (f.value (), 3);
f >> Flag::One;
EXPECT_EQ (f.value (), 2);
}
{
FlagMasks f;
f.add (FlagMask::One);
EXPECT_EQ (f.value (), 1);
f.add (FlagMask::Two);
EXPECT_EQ (f.value (), 3);
f.remove (FlagMask::One);
EXPECT_EQ (f.value (), 2);
f.clear ();
f |= FlagMask::One;
EXPECT_EQ (f.value (), 1);
f |= FlagMask::Two;
EXPECT_EQ (f.value (), 3);
f ^= FlagMask::One;
EXPECT_EQ (f.value (), 2);
f.clear ();
f << FlagMask::One;
EXPECT_EQ (f.value (), 1);
f << FlagMask::Two;
EXPECT_EQ (f.value (), 3);
f >> FlagMask::One;
EXPECT_EQ (f.value (), 2);
}
}
//------------------------------------------------------------------------
TEST_CASE (EnumBitsetTest, OperatorTest)
{
{
Flags f1 = Flag::One;
Flags f2 ({Flag::Two, Flag::Three});
auto f3 = f1 | Flag::Two;
EXPECT_EQ (f3.value (), 3);
EXPECT_TRUE (f3 & Flag::One);
EXPECT_TRUE (f3 & Flag::Two);
}
{
FlagMasks f1 = FlagMask::One;
FlagMasks f2 ({FlagMask::Two, FlagMask::Three});
auto f3 = f1 | FlagMask::Two;
EXPECT_EQ (f3.value (), 3);
EXPECT_TRUE (f3 & FlagMask::One);
EXPECT_TRUE (f3 & FlagMask::Two);
}
}
//------------------------------------------------------------------------
TEST_CASE (EnumBitsetTest, EqualityTest)
{
{
Flags f1 ({Flag::One, Flag::Three});
Flags f2 ({Flag::Two, Flag::Three});
Flags f3 ({Flag::Three, Flag::One});
EXPECT_TRUE (f1 != f2);
EXPECT_TRUE (f1 == f3);
EXPECT_TRUE (f1.test (Flag::One));
EXPECT_FALSE (f1.test (Flag::Two));
}
{
FlagMasks f1 ({FlagMask::One, FlagMask::Three});
FlagMasks f2 ({FlagMask::Two, FlagMask::Three});
FlagMasks f3 ({FlagMask::Three, FlagMask::One});
EXPECT_TRUE (f1 != f2);
EXPECT_TRUE (f1 == f3);
EXPECT_TRUE (f1.test (FlagMask::One));
EXPECT_FALSE (f1.test (FlagMask::Two));
}
}
//------------------------------------------------------------------------
} // VSTGUI
@@ -0,0 +1,213 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/events.h"
#include "../unittests.h"
//------------------------------------------------------------------------
namespace VSTGUI {
TEST_CASE (EventTest, UniqueIDTest)
{
Event e1;
Event e2;
EXPECT_NE (e1.id, e2.id);
}
TEST_CASE (EventTest, DefaultConstructorTypeTest)
{
MouseEnterEvent enterEvent;
EXPECT_EQ (enterEvent.type, EventType::MouseEnter);
MouseExitEvent exitEvent;
EXPECT_EQ (exitEvent.type, EventType::MouseExit);
MouseDownEvent downEvent;
EXPECT_EQ (downEvent.type, EventType::MouseDown);
MouseMoveEvent moveEvent;
EXPECT_EQ (moveEvent.type, EventType::MouseMove);
MouseUpEvent upEvent;
EXPECT_EQ (upEvent.type, EventType::MouseUp);
MouseCancelEvent cancelEvent;
EXPECT_EQ (cancelEvent.type, EventType::MouseCancel);
MouseWheelEvent wheelEvent;
EXPECT_EQ (wheelEvent.type, EventType::MouseWheel);
ZoomGestureEvent zoomGestureEvent;
EXPECT_EQ (zoomGestureEvent.type, EventType::ZoomGesture);
KeyboardEvent keyEvent;
EXPECT_EQ (keyEvent.type, EventType::KeyDown);
}
TEST_CASE (EventTest, NoEventTest)
{
auto& event = noEvent ();
EXPECT_EQ (event.type, EventType::Unknown);
}
TEST_CASE (EventTest, ConsumedTest)
{
EventConsumeState consumed;
EXPECT_FALSE (consumed);
consumed = true;
EXPECT_TRUE (consumed);
consumed = false;
EXPECT_FALSE (consumed);
consumed = true;
EXPECT_TRUE (consumed);
consumed.reset ();
EXPECT_FALSE (consumed);
}
TEST_CASE (EventTest, CastMouseEnterEventTest)
{
MouseEnterEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), &e);
EXPECT_EQ (asMouseEvent (e), &e);
EXPECT_EQ (asMouseDownEvent (e), nullptr);
EXPECT_EQ (asModifierEvent (e), &e);
EXPECT_EQ (asKeyboardEvent (e), nullptr);
}
TEST_CASE (EventTest, CastMouseExitEventTest)
{
MouseExitEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), &e);
EXPECT_EQ (asMouseEvent (e), &e);
EXPECT_EQ (asMouseDownEvent (e), nullptr);
EXPECT_EQ (asModifierEvent (e), &e);
EXPECT_EQ (asKeyboardEvent (e), nullptr);
}
TEST_CASE (EventTest, CastMouseDownEventTest)
{
MouseDownEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), &e);
EXPECT_EQ (asMouseEvent (e), &e);
EXPECT_EQ (asMouseDownEvent (e), &e);
EXPECT_EQ (asModifierEvent (e), &e);
EXPECT_EQ (asKeyboardEvent (e), nullptr);
}
TEST_CASE (EventTest, CastMouseMoveEventTest)
{
MouseMoveEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), &e);
EXPECT_EQ (asMouseEvent (e), &e);
EXPECT_EQ (asMouseDownEvent (e), &e);
EXPECT_EQ (asModifierEvent (e), &e);
EXPECT_EQ (asKeyboardEvent (e), nullptr);
}
TEST_CASE (EventTest, CastMouseUpEventTest)
{
MouseUpEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), &e);
EXPECT_EQ (asMouseEvent (e), &e);
EXPECT_EQ (asMouseDownEvent (e), &e);
EXPECT_EQ (asModifierEvent (e), &e);
EXPECT_EQ (asKeyboardEvent (e), nullptr);
}
TEST_CASE (EventTest, CastMouseCancelEventTest)
{
MouseCancelEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), nullptr);
EXPECT_EQ (asMouseEvent (e), nullptr);
EXPECT_EQ (asMouseDownEvent (e), nullptr);
EXPECT_EQ (asModifierEvent (e), nullptr);
EXPECT_EQ (asKeyboardEvent (e), nullptr);
}
TEST_CASE (EventTest, CastMouseWheelEventTest)
{
MouseWheelEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), &e);
EXPECT_EQ (asMouseEvent (e), nullptr);
EXPECT_EQ (asMouseDownEvent (e), nullptr);
EXPECT_EQ (asModifierEvent (e), &e);
EXPECT_EQ (asKeyboardEvent (e), nullptr);
}
TEST_CASE (EventTest, CastZoomGestureEventTest)
{
ZoomGestureEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), &e);
EXPECT_EQ (asMouseEvent (e), nullptr);
EXPECT_EQ (asMouseDownEvent (e), nullptr);
EXPECT_EQ (asModifierEvent (e), nullptr);
EXPECT_EQ (asKeyboardEvent (e), nullptr);
}
TEST_CASE (EventTest, CastKeyboardEventTest)
{
KeyboardEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), nullptr);
EXPECT_EQ (asMouseEvent (e), nullptr);
EXPECT_EQ (asMouseDownEvent (e), nullptr);
EXPECT_EQ (asModifierEvent (e), &e);
EXPECT_EQ (asKeyboardEvent (e), &e);
}
TEST_CASE (EventTest, ButtonStateFromEventModifierTest)
{
Modifiers mods;
EXPECT_EQ (buttonStateFromEventModifiers (mods), 0);
mods.add (ModifierKey::Control);
EXPECT_EQ (buttonStateFromEventModifiers (mods), kControl);
mods.add (ModifierKey::Shift);
EXPECT_EQ (buttonStateFromEventModifiers (mods), kControl | kShift);
mods.add (ModifierKey::Alt);
EXPECT_EQ (buttonStateFromEventModifiers (mods), kControl | kShift | kAlt);
}
TEST_CASE (EventTest, ButtonStateFromMouseEventTest)
{
MouseDownEvent event;
EXPECT_EQ (buttonStateFromMouseEvent (event), 0);
event.buttonState.set (MouseButton::Left);
EXPECT_EQ (buttonStateFromMouseEvent (event), kLButton);
event.buttonState.set (MouseButton::Right);
EXPECT_EQ (buttonStateFromMouseEvent (event), kRButton);
event.buttonState.set (MouseButton::Middle);
EXPECT_EQ (buttonStateFromMouseEvent (event), kMButton);
event.buttonState.set (MouseButton::Fourth);
EXPECT_EQ (buttonStateFromMouseEvent (event), kButton4);
event.buttonState.set (MouseButton::Fifth);
EXPECT_EQ (buttonStateFromMouseEvent (event), kButton5);
event.clickCount = 2;
event.buttonState.set (MouseButton::Left);
EXPECT_EQ (buttonStateFromMouseEvent (event), kLButton | kDoubleClick);
event.modifiers.add (ModifierKey::Shift);
EXPECT_EQ (buttonStateFromMouseEvent (event), kLButton | kDoubleClick | kShift);
}
TEST_CASE (EventTest, IgnoreFollowUpEvent)
{
MouseDownEvent e;
EXPECT_FALSE (e.ignoreFollowUpMoveAndUpEvents ());
e.ignoreFollowUpMoveAndUpEvents (true);
EXPECT_TRUE (e.ignoreFollowUpMoveAndUpEvents ());
EXPECT_FALSE (e.consumed);
e.consumed = true;
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
@@ -0,0 +1,45 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/events.h"
//------------------------------------------------------------------------
namespace VSTGUI {
//------------------------------------------------------------------------
template <typename EventType>
inline uint32_t dispatchMouseEvent (CView* view, CPoint pos, MouseEventButtonState buttons = {},
Modifiers mods = {})
{
EventType event;
event.mousePosition = pos;
event.buttonState = buttons;
event.modifiers = mods;
view->dispatchEvent (event);
return event.consumed.data;
}
//------------------------------------------------------------------------
inline uint32_t dispatchMouseCancelEvent (CView* view)
{
MouseCancelEvent event;
view->dispatchEvent (event);
return event.consumed.data;
}
//------------------------------------------------------------------------
inline uint32_t dispatchMouseWheelEvent (CView* view, CPoint pos, double deltaX, double deltaY,
Modifiers mods = {})
{
MouseWheelEvent event;
event.mousePosition = pos;
event.deltaX = deltaX;
event.deltaY = deltaY;
event.modifiers = mods;
view->dispatchEvent (event);
return event.consumed.data;
}
//------------------------------------------------------------------------
} // VSTGUI
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,76 @@
// 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 VSTGUI_ENABLE_DEPRECATED_METHODS
#include "../../../lib/private/disabledeprecatedmessage.h"
#include "../../../lib/idependency.h"
namespace VSTGUI {
class DependentObject : public CBaseObject, public IDependency
{
public:
DependentObject () : notifyCalledCount (0) {}
CMessageResult notify (CBaseObject* sender, IdStringPtr message) override
{
notifyCalledCount++;
return kMessageNotified;
}
int32_t notifyCalledCount;
};
class TestObject : public CBaseObject, public IDependency
{
public:
TestObject () {}
};
TEST_CASE (IDependencyTest, SimpleDependency)
{
DependentObject dObj;
TestObject tObj;
tObj.addDependency (&dObj);
tObj.changed ("Test");
EXPECT (dObj.notifyCalledCount == 1)
tObj.removeDependency (&dObj);
}
TEST_CASE (IDependencyTest, SimpleDeferedDependency)
{
DependentObject dObj;
TestObject tObj;
tObj.addDependency (&dObj);
tObj.deferChanges (true);
tObj.changed ("Test");
EXPECT (dObj.notifyCalledCount == 0)
tObj.deferChanges (false);
EXPECT (dObj.notifyCalledCount == 1)
tObj.removeDependency (&dObj);
}
TEST_CASE (IDependencyTest, SimpleDeferChanges)
{
DependentObject dObj;
TestObject tObj;
tObj.addDependency (&dObj);
{
IDependency::DeferChanges df (&tObj);
IdStringPtr messageID = "Test";
tObj.changed (messageID);
tObj.changed (messageID);
EXPECT (dObj.notifyCalledCount == 0)
}
EXPECT (dObj.notifyCalledCount == 1)
tObj.removeDependency (&dObj);
}
} // VSTGUI
#include "../../../lib/private/enabledeprecatedmessage.h"
#endif // VSTGUI_ENABLE_DEPRECATED_METHODS
@@ -0,0 +1,95 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/pixelbuffer.h"
#include "../unittests.h"
namespace VSTGUI {
using namespace PixelBuffer;
TEST_CASE (PixelBufferTest, ARGB_2_RGBA)
{
uint32_t pixel = 0x11223344;
convert (Format::ARGB, Format::RGBA, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x22334411);
}
TEST_CASE (PixelBufferTest, ARGB_2_BGRA)
{
uint32_t pixel = 0x11223344;
convert (Format::ARGB, Format::BGRA, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x44332211);
}
TEST_CASE (PixelBufferTest, ARGB_2_ABGR)
{
uint32_t pixel = 0x11223344;
convert (Format::ARGB, Format::ABGR, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x11443322);
}
TEST_CASE (PixelBufferTest, ABGR_2_ARGB)
{
uint32_t pixel = 0x11223344;
convert (Format::ABGR, Format::ARGB, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x11443322);
}
TEST_CASE (PixelBufferTest, ABGR_2_RGBA)
{
uint32_t pixel = 0x11223344;
convert (Format::ABGR, Format::RGBA, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x44332211);
}
TEST_CASE (PixelBufferTest, ABGR_2_BGRA)
{
uint32_t pixel = 0x11223344;
convert (Format::ABGR, Format::BGRA, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x22334411);
}
TEST_CASE (PixelBufferTest, RGBA_2_ARGB)
{
uint32_t pixel = 0x11223344;
convert (Format::RGBA, Format::ARGB, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x22334411);
}
TEST_CASE (PixelBufferTest, RGBA_2_ABGR)
{
uint32_t pixel = 0x11223344;
convert (Format::RGBA, Format::ABGR, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x44332211);
}
TEST_CASE (PixelBufferTest, RGBA_2_BGRA)
{
uint32_t pixel = 0x11223344;
convert (Format::RGBA, Format::BGRA, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x11443322);
}
TEST_CASE (PixelBufferTest, BGRA_2_RGBA)
{
uint32_t pixel = 0x11223344;
convert (Format::BGRA, Format::RGBA, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x33221144);
}
TEST_CASE (PixelBufferTest, BGRA_2_ABGR)
{
uint32_t pixel = 0x11223344;
convert (Format::BGRA, Format::ABGR, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x22334411);
}
TEST_CASE (PixelBufferTest, BGRA_2_ARGB)
{
uint32_t pixel = 0x11223344;
convert (Format::BGRA, Format::ARGB, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x44332211);
}
} // namespace VSTGUI
@@ -0,0 +1,22 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/vstguibase.h"
#include "../../../lib/platform/iplatformframe.h"
namespace VSTGUI {
namespace UnitTest {
struct PlatformParentHandle : public CBaseObject
{
static SharedPointer<PlatformParentHandle> create ();
virtual PlatformType getType () const = 0;
virtual void* getHandle () const = 0;
virtual void forceRedraw () = 0;
};
} // UnitTest
} // VSTGUI
@@ -0,0 +1,32 @@
// 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 "platform_helper.h"
namespace VSTGUI {
namespace UnitTest {
SharedPointer<PlatformParentHandle> PlatformParentHandle::create ()
{
return nullptr;
}
PlatformType PlatformParentHandle::getType () const
{
return PlatformType::kX11EmbedWindowID;
}
void* PlatformParentHandle::getHandle () const
{
return nullptr;
}
void PlatformParentHandle::forceRedraw ()
{
}
} // UnitTest
} // VSTGUI
@@ -0,0 +1,58 @@
// 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 "platform_helper.h"
#import <Cocoa/Cocoa.h>
namespace VSTGUI {
namespace UnitTest {
struct MacParentHandle : PlatformParentHandle
{
NSWindow* window {nil};
MacParentHandle ()
{
NSWindowStyleMask style;
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
style = NSWindowStyleMaskTitled;
#else
style = NSTitledWindowMask;
#endif
window = [[NSWindow alloc] initWithContentRect:NSMakeRect (0, 0, 100, 100)
styleMask:style
backing:NSBackingStoreBuffered
defer:NO];
}
~MacParentHandle () override
{
[window release];
}
PlatformType getType () const override
{
return PlatformType::kNSView;
}
void* getHandle () const override
{
return window.contentView;
}
void forceRedraw () override
{
[window displayIfNeeded];
}
};
SharedPointer<PlatformParentHandle> PlatformParentHandle::create ()
{
return owned (dynamic_cast<PlatformParentHandle*> (new MacParentHandle ()));
}
} // UnitTest
} // VSTGUI
@@ -0,0 +1,85 @@
// 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 "platform_helper.h"
#include "../../../lib/platform/win32/win32support.h"
#include <windows.h>
namespace VSTGUI {
namespace UnitTest {
static LRESULT CALLBACK MainWndProc (HWND h, UINT m , WPARAM w, LPARAM l)
{
return DefWindowProc (h, m, w, l);
}
BOOL InitApplication(HINSTANCE hinstance)
{
WNDCLASSEX wcx;
// Fill in the window class structure with parameters
// that describe the main window.
wcx.cbSize = sizeof(wcx); // size of structure
wcx.style = CS_HREDRAW |
CS_VREDRAW; // redraw if size changes
wcx.lpfnWndProc = MainWndProc; // points to window procedure
wcx.cbClsExtra = 0; // no extra class memory
wcx.cbWndExtra = 0; // no extra window memory
wcx.hInstance = hinstance; // handle to instance
wcx.hIcon = LoadIcon(NULL,
IDI_APPLICATION); // predefined app. icon
wcx.hCursor = LoadCursor(NULL,
IDC_ARROW); // predefined arrow
wcx.hbrBackground = nullptr; // white background brush
wcx.lpszMenuName = nullptr; // name of menu resource
wcx.lpszClassName = L"MainWClass"; // name of window class
wcx.hIconSm = nullptr;
// Register the window class.
return RegisterClassEx(&wcx);
}
struct Initializer
{
static Initializer& instance ()
{
static Initializer gInstance;
return gInstance;
}
Initializer ()
{
InitApplication (GetInstance ());
}
};
struct WinPlatformHandle : PlatformParentHandle
{
HWND window{ nullptr };
WinPlatformHandle ()
{
Initializer::instance ();
window = CreateWindow (L"MainWClass", L"Test", WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, nullptr, nullptr, GetInstance (), 0);
}
~WinPlatformHandle ()
{
DestroyWindow (window);
}
PlatformType getType () const override { return PlatformType::kHWND; }
void* getHandle () const override { return window; };
void forceRedraw () override {};
};
SharedPointer<PlatformParentHandle> PlatformParentHandle::create()
{
return owned (dynamic_cast<PlatformParentHandle*> (new WinPlatformHandle ()));
}
} // UnitTest
} // VSTGUI
@@ -0,0 +1,68 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/tasks.h"
#include "../unittests.h"
#include <atomic>
#include <thread>
//------------------------------------------------------------------------
namespace VSTGUI {
//------------------------------------------------------------------------
TEST_SUITE_SETUP (SerialQueueTest)
{
TEST_SUITE_SET_STORAGE (Tasks::Queue, Tasks::makeSerialQueue ("Test Serial Queue"));
}
//------------------------------------------------------------------------
TEST_SUITE_TEARDOWN (SerialQueueTest)
{
Tasks::releaseSerialQueue (TEST_SUITE_GET_STORAGE (Tasks::Queue));
}
//------------------------------------------------------------------------
TEST_CASE (SerialQueueTest, Validation)
{
const auto& serialQueue = TEST_SUITE_GET_STORAGE (Tasks::Queue);
EXPECT_NE (serialQueue, Tasks::InvalidQueue);
}
//------------------------------------------------------------------------
TEST_CASE (SerialQueueTest, SimpleTasks)
{
uint32_t numIterations = 1000u;
uint32_t counter {0u};
const auto& serialQueue = TEST_SUITE_GET_STORAGE (Tasks::Queue);
auto increaseCounterFunc = [&] () {
++counter;
std::this_thread::yield ();
};
for (auto i = 0u; i < numIterations; ++i)
Tasks::schedule (serialQueue, increaseCounterFunc);
Tasks::waitAllTasksExecuted (serialQueue);
EXPECT_EQ (counter, numIterations)
}
//------------------------------------------------------------------------
TEST_CASE (SerialQueueTest, scheduleSerialTasksOnBackgroundQueue)
{
uint32_t numIterations = 1000u;
uint32_t counter {0u};
const auto& serialQueue = TEST_SUITE_GET_STORAGE (Tasks::Queue);
auto increaseCounterFunc = [&] () {
++counter;
};
for (auto i = 0u; i < numIterations; ++i)
{
Tasks::schedule (Tasks::backgroundQueue (),
[&] () { Tasks::schedule (serialQueue, increaseCounterFunc); });
}
Tasks::waitAllTasksExecuted (Tasks::backgroundQueue ());
Tasks::waitAllTasksExecuted (serialQueue);
EXPECT_EQ (counter, numIterations)
}
//------------------------------------------------------------------------
} // VSTGUI
@@ -0,0 +1,124 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cstring.h"
#include "../unittests.h"
#if MAC
#include "../../../lib/platform/mac/macstring.h"
#endif
namespace VSTGUI {
TEST_CASE (UTF8StringTest, Empty)
{
UTF8String str;
EXPECT (str.empty ());
EXPECT (str.length () == 0);
}
TEST_CASE (UTF8StringTest, Set)
{
UTF8String str;
EXPECT (str.empty ());
str.assign ("Test");
EXPECT (str.empty () == false);
EXPECT (str.data () == std::string ("Test"));
}
TEST_CASE (UTF8StringTest, EqualOperator)
{
EXPECT (UTF8String ("bla") == "bla");
EXPECT (UTF8String ("bla") != "uhh");
std::string str ("bla");
std::string str2 ("uhh");
EXPECT (UTF8String ("bla") == str);
EXPECT (UTF8String ("bla") != str2);
}
TEST_CASE (UTF8StringTest, SetOperator)
{
UTF8String str;
str = "Test";
EXPECT (str == "Test");
}
TEST_CASE (UTF8StringTest, GetOperator)
{
UTF8String str ("Test");
UTF8StringPtr cstr = str;
EXPECT (cstr == std::string ("Test"));
}
TEST_CASE (UTF8StringTest, CopyOperator)
{
UTF8String str1 ("str");
UTF8String str2 (str1);
EXPECT (str1 == str2);
}
TEST_CASE (UTF8StringTest, MoveOperator)
{
UTF8String str1 ("str");
UTF8String str2 (std::move (str1));
EXPECT (str1 != str2);
}
TEST_CASE (UTF8StringTest, AddOperator)
{
UTF8String str1 ("str");
str1 += "ing";
EXPECT (str1 == "string");
auto str2 = str1 + "1";
EXPECT (str2 == "string1");
EXPECT (str1 == "string");
}
TEST_CASE (UTF8StringTest, Clear)
{
UTF8String str1 ("string");
EXPECT (str1 == "string");
str1.clear ();
EXPECT (str1 == "");
}
TEST_CASE (UTF8StringTest, Copy)
{
UTF8String str1 ("string");
char buffer[3] {1};
str1.copy (buffer, sizeof (buffer));
EXPECT (buffer[0] == 's');
EXPECT (buffer[1] == 't');
EXPECT (buffer[2] == 0);
}
TEST_CASE (UTF8StringTest, CodePointIterator)
{
UTF8String str ("\xc3\x84\xe0\xa5\xb4\xf0\xaa\x80\x9a\0"); // u8"Äॴ𪀚"
auto charCount = 0;
for (auto it = str.begin (); it != str.end (); ++it)
{
charCount++;
}
EXPECT (charCount == 3);
}
#if MAC
TEST_CASE (UTF8StringTest, MacPlatformString)
{
UTF8String str1 ("Test");
auto platformStr = str1.getPlatformString ();
auto macStr = dynamic_cast<MacString*> (platformStr);
EXPECT (macStr);
auto cfStr = macStr->getCFString ();
auto cfStr2 = CFStringCreateWithCString (kCFAllocatorDefault, "Test", kCFStringEncodingUTF8);
EXPECT (CFStringCompare (cfStr, cfStr2, 0) == kCFCompareEqualTo);
CFRelease (cfStr2);
}
#endif
} // VSTGUI
@@ -0,0 +1,128 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cstring.h"
#include "../unittests.h"
namespace VSTGUI {
static UTF8StringPtr asciiStr = "This is a simple ASCII String";
static UTF8StringPtr utf8Str =
"\xe3\x82\xa4\xe3\x83\xb3\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\x8d\xe3\x83\x83\xe3\x83\x88\xe3\x82\x92\xe3\x82\x82\xe3\x81\xa3\xe3\x81\xa8\xe5\xbf\xab\xe9\x81\xa9\xe3\x81\xab\xe3\x80\x82\0"; // u8"インターネットをもっと快適に。";
TEST_CASE (UTF8StringViewTest, CalculateASCIICharacterCount)
{
UTF8StringView str (asciiStr);
EXPECT (str.calculateCharacterCount () == 29);
}
TEST_CASE (UTF8StringViewTest, CalculateUTF8CharacterCount)
{
UTF8StringView str (utf8Str);
EXPECT (str.calculateCharacterCount () == 15);
UTF8StringView str2 ("\xc3\x84\xe0\xa5\xb4\xf0\xaa\x80\x9a\0"); // u8"Äॴ𪀚"
EXPECT (str2.calculateCharacterCount () == 3);
EXPECT (str2.calculateByteCount () == 10);
}
TEST_CASE (UTF8StringViewTest, CalculateEmptyCharacterCount)
{
UTF8StringView str (nullptr);
EXPECT (str.calculateCharacterCount () == 0);
}
TEST_CASE (UTF8StringViewTest, calculateASCIIByteCount)
{
UTF8StringView str (asciiStr);
EXPECT (str.calculateByteCount () == 30);
}
TEST_CASE (UTF8StringViewTest, calculateUTF8ByteCount)
{
UTF8StringView str (utf8Str);
EXPECT (str.calculateByteCount () == 46);
}
TEST_CASE (UTF8StringViewTest, Contains)
{
UTF8StringView str (asciiStr);
EXPECT (str.contains ("simple") == true);
EXPECT (str.contains ("not") == false);
}
TEST_CASE (UTF8StringViewTest, EndsWith)
{
UTF8StringView str (asciiStr);
EXPECT (str.endsWith ("String") == true);
EXPECT (str.endsWith ("This") == false);
EXPECT (str.endsWith ("This is a simple ASCII String which is longer") == false);
}
TEST_CASE (UTF8StringViewTest, DoubleConversion)
{
UTF8StringView str ("32.56789");
double value = str.toDouble ();
EXPECT (value == 32.56789);
}
TEST_CASE (UTF8StringViewTest, FloatConversion)
{
UTF8StringView str ("32.56789");
float value = str.toFloat ();
EXPECT (value == 32.56789f);
}
TEST_CASE (UTF8StringViewTest, Compare)
{
std::string test ("This is a simple ASCII String");
UTF8StringView str1 (test.data ());
UTF8StringView str2 (asciiStr);
EXPECT (str1 == str2);
UTF8StringView str3 (utf8Str);
EXPECT (str1 != str3);
}
TEST_CASE (UTF8StringViewTest, ContainsCheckCase)
{
UTF8StringView str (asciiStr);
EXPECT (str.contains ("simple"));
EXPECT (str.contains ("Simple") == false);
EXPECT (str.contains ("SiMpLe", true));
}
TEST_CASE (UTF8StringViewTest, StartsWith)
{
UTF8StringView str (asciiStr);
EXPECT (str.startsWith ("This"));
}
TEST_CASE (UTF8StringViewTest, ToDouble)
{
UTF8StringView str ("5.1");
EXPECT (str.toDouble () == 5.1);
}
TEST_CASE (UTF8StringViewTest, ToFloat)
{
UTF8StringView str ("5.1");
EXPECT (str.toFloat () == 5.1f);
}
TEST_CASE (UTF8StringViewTest, toInteger)
{
UTF8StringView str ("5");
EXPECT (str.toInteger () == 5);
}
TEST_CASE (UTF8StringViewTest, toNumber)
{
UTF8StringView str ("300");
auto res = str.toNumber<int32_t> ();
EXPECT (res);
EXPECT (*res == 300);
auto res2 = str.toNumber<uint8_t> ();
EXPECT(!res2);
}
} // VSTGUI