Can't select multiple Clips (SelectionManager)

I’m trying to use SelectionManager, but when I add another item to selection it throws jassertfalse here:

No matter which selection method I try, it throws this assertion. Am I missing something?
Here’s how I’m selecting:

void ClipComponent::mouseDown (const MouseEvent& e)
	if (ModifierKeys::currentModifiers.isCtrlDown() || ModifierKeys::currentModifiers.isShiftDown())
		editViewState.selectionManager.selectOnly (clip.get());

Is it just the assertion that’s causing problems? If you continue past it, does the SelectionManager actually add the item for you?

It does add the item. But then I have to click back on the app window and I have it set to deselect when clicked anywhere else. Therefore it’s impossible to do anything with this.

Do I have to create SelectableClass or something? I’d rather do anything to make it work properly without assertions. At this point this is the biggest stopping point in development that I have.

Okay, I’m looking at your answer in this thread Jassertfalse at line 255 in traction_SelectionManager.cpp

What I’m getting at is that we should probably just remove that assertion if you don’t have any SelectableClasses registered. It’s really there to catch the cases where we add a new type of Selectable but don’t implement a SelectableClass for it.

If you just comment out that assertion locally for now it should ok?

Okay, I commented it out. I hope it won’t break anything internally.

I just not fully understand the purpose of SelectableClasses. What If I want to do the same action on all selected clips, is it possible without SelectableClass? E. g. change their position or fades?

You can write a function that does that to an Array<Clip*> if you need. Or you could write a SelectableClass subclass that has some kind of method to do that (in Waveform we have that).
That’s all very app specific though which is why it’s not in the Engine.

So would it be right to inherit my ClipComponent from SelectableClass? Or does it have to be a separate object that handles all the ClipComponents?

It would be separate.

When I have my SlectableClass:

class SelectableClipClass : public te::SelectableClass


And I click on myClipComponent (not the SelectableClipClass) to select its te::Clip* (not the component):
How do I use my SelectableClass here?

P.S. Sorry if I’m asking too much basic questions, I’m just struggling to figure out how it all works.

You need to register it first by adding the following line after you class definition:

then the static instance of your class should be returned by the SelectableClass::findClassFor methods.

A bit of an issue with the macro:

Does my ClipComponent or whatever I’m going to perform group actions on have to inherit from Selectable. How does SelectableClass::findClassFor() knows what to retrieve SelectableClipClass. Is this where Selectable comes in place?

Oh, you might need to be using the tracktion_engine namespace for that macro to work.
Can you try adding using namespace tracktion_engine above it?
If that does compile, you might want to create your own macro that has the namespace in it explicitly to avoid polluting your own.

This is all done with template magic. There was actually an error in the macro I mentioned earlier, if your naming scheme is different from WaveAudioClip -> WaveAudioClipClass you’ll need to use this macro:

DECLARE_SELECTABLE_OBJECT_AND_CLASS(tracktion_engine::Clip, SelectableClipClass)

Then once you select an object of type tracktion_engine::Clip it SelectableClass::findClassFor will return the SelectableClipClass instance you registered with it.

This would be great, if it works:

Compilers throws a bunch of errors like:
error C2653: 'SelectableClass': is not a class or namespace name (compiling source file ..\..\Source\Main.cpp)
error C2143: syntax error: missing ';' before '<' (compiling source file ..\..\Source\Main.cpp)

Works for me:

class SelectableClipClass : public tracktion_engine::SelectableClass
    SelectableClipClass() {}

DECLARE_SELECTABLE_OBJECT_AND_CLASS (tracktion_engine::Clip, SelectableClipClass)

to test:

        SelectionManager sm (engine);
        auto edit = Edit::createSingleTrackEdit (engine);
        auto clip = getAudioTracks (*edit)[0]->insertNewClip (TrackItem::Type::midi, { 0.0, 10.0 }, &sm);
        auto selectableClass = sm.getFirstSelectableClass();

If I break in the debugger after that, selectableClass is of type SelectableClipClass

It doesn’t even compile for me

Maybe I should just type it all out instead of using macro? How would that look?

I don’t think there’s enough context here.
How this should be written will depend a lot on your current name visibility.

Does this work if you add it at the top of the RecordingDemo.h file?

#pragma once

#include "common/Utilities.h"
#include "common/Components.h"

class SelectableClipClass : public tracktion_engine::SelectableClass
    SelectableClipClass() {}

using namespace tracktion_engine;
DECLARE_SELECTABLE_OBJECT_AND_CLASS (tracktion_engine::Clip, SelectableClipClass)

void testSelectableClass (tracktion_engine::Engine& engine)
    tracktion_engine::SelectionManager sm (engine);
    auto edit = tracktion_engine::Edit::createSingleTrackEdit (engine);
    auto clip = getAudioTracks (*edit)[0]->insertNewClip (tracktion_engine::TrackItem::Type::midi, { 0.0, 10.0 }, &sm);
    auto selectableClass = sm.getFirstSelectableClass();
    jassert (dynamic_cast<SelectableClipClass*> (selectableClass) != nullptr);

class RecordingDemo  : public Component,
                       private ChangeListener
        testSelectableClass (engine);