mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Replaced some old juce-style sort operations with std::sort and lambdas
This commit is contained in:
parent
3659742a3a
commit
d4a7afa73f
17 changed files with 132 additions and 269 deletions
|
|
@ -142,18 +142,12 @@ const ModuleDescription* ModuleList::getModuleWithID (const String& moduleID) co
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
struct ModuleSorter
|
||||
{
|
||||
static int compareElements (const ModuleDescription* m1, const ModuleDescription* m2)
|
||||
{
|
||||
return m1->getID().compareIgnoreCase (m2->getID());
|
||||
}
|
||||
};
|
||||
|
||||
void ModuleList::sort()
|
||||
{
|
||||
ModuleSorter sorter;
|
||||
modules.sort (sorter);
|
||||
std::sort (modules.begin(), modules.end(), [] (const ModuleDescription* m1, const ModuleDescription* m2)
|
||||
{
|
||||
return m1->getID().compareIgnoreCase (m2->getID()) < 0;
|
||||
});
|
||||
}
|
||||
|
||||
StringArray ModuleList::getIDs() const
|
||||
|
|
|
|||
|
|
@ -131,23 +131,6 @@ namespace MidiFileHelpers
|
|||
return correctedTime + (time - lastTime) * secsPerTick;
|
||||
}
|
||||
|
||||
// a comparator that puts all the note-offs before note-ons that have the same time
|
||||
struct Sorter
|
||||
{
|
||||
static int compareElements (const MidiMessageSequence::MidiEventHolder* const first,
|
||||
const MidiMessageSequence::MidiEventHolder* const second) noexcept
|
||||
{
|
||||
const double diff = (first->message.getTimeStamp() - second->message.getTimeStamp());
|
||||
|
||||
if (diff > 0) return 1;
|
||||
if (diff < 0) return -1;
|
||||
if (first->message.isNoteOff() && second->message.isNoteOn()) return -1;
|
||||
if (first->message.isNoteOn() && second->message.isNoteOff()) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename MethodType>
|
||||
static void findAllMatchingEvents (const OwnedArray<MidiMessageSequence>& tracks,
|
||||
MidiMessageSequence& results,
|
||||
|
|
@ -335,9 +318,19 @@ void MidiFile::readNextTrack (const uint8* data, int size)
|
|||
lastStatusByte = firstByte;
|
||||
}
|
||||
|
||||
// use a sort that puts all the note-offs before note-ons that have the same time
|
||||
MidiFileHelpers::Sorter sorter;
|
||||
result.list.sort (sorter, true);
|
||||
// sort so that we put all the note-offs before note-ons that have the same time
|
||||
std::stable_sort (result.list.begin(), result.list.end(),
|
||||
[] (const MidiMessageSequence::MidiEventHolder* a,
|
||||
const MidiMessageSequence::MidiEventHolder* b)
|
||||
{
|
||||
auto t1 = a->message.getTimeStamp();
|
||||
auto t2 = b->message.getTimeStamp();
|
||||
|
||||
if (t1 < t2) return true;
|
||||
if (t2 < t1) return false;
|
||||
|
||||
return a->message.isNoteOff() && b->message.isNoteOn();
|
||||
});
|
||||
|
||||
addTrack (result);
|
||||
tracks.getLast()->updateMatchedPairs();
|
||||
|
|
|
|||
|
|
@ -204,20 +204,10 @@ void MidiMessageSequence::addSequence (const MidiMessageSequence& other,
|
|||
sort();
|
||||
}
|
||||
|
||||
struct MidiMessageSequenceSorter
|
||||
{
|
||||
static int compareElements (const MidiMessageSequence::MidiEventHolder* first,
|
||||
const MidiMessageSequence::MidiEventHolder* second) noexcept
|
||||
{
|
||||
auto diff = first->message.getTimeStamp() - second->message.getTimeStamp();
|
||||
return (diff > 0) - (diff < 0);
|
||||
}
|
||||
};
|
||||
|
||||
void MidiMessageSequence::sort() noexcept
|
||||
{
|
||||
MidiMessageSequenceSorter sorter;
|
||||
list.sort (sorter, true);
|
||||
std::stable_sort (list.begin(), list.end(),
|
||||
[] (const MidiEventHolder* a, const MidiEventHolder* b) { return a->message.getTimeStamp() < b->message.getTimeStamp(); });
|
||||
}
|
||||
|
||||
void MidiMessageSequence::updateMatchedPairs() noexcept
|
||||
|
|
|
|||
|
|
@ -179,14 +179,6 @@ MPESynthesiserVoice* MPESynthesiser::findFreeVoice (MPENote noteToFindVoiceFor,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
struct MPEVoiceAgeSorter
|
||||
{
|
||||
static int compareElements (MPESynthesiserVoice* v1, MPESynthesiserVoice* v2) noexcept
|
||||
{
|
||||
return v1->wasStartedBefore (*v2) ? -1 : (v2->wasStartedBefore (*v1) ? 1 : 0);
|
||||
}
|
||||
};
|
||||
|
||||
MPESynthesiserVoice* MPESynthesiser::findVoiceToSteal (MPENote noteToStealVoiceFor) const
|
||||
{
|
||||
// This voice-stealing algorithm applies the following heuristics:
|
||||
|
|
@ -205,17 +197,17 @@ MPESynthesiserVoice* MPESynthesiser::findVoiceToSteal (MPENote noteToStealVoiceF
|
|||
Array<MPESynthesiserVoice*> usableVoices;
|
||||
usableVoices.ensureStorageAllocated (voices.size());
|
||||
|
||||
for (int i = 0; i < voices.size(); ++i)
|
||||
for (auto* voice : voices)
|
||||
{
|
||||
MPESynthesiserVoice* const voice = voices.getUnchecked (i);
|
||||
jassert (voice->isActive()); // We wouldn't be here otherwise
|
||||
|
||||
MPEVoiceAgeSorter sorter;
|
||||
usableVoices.addSorted (sorter, voice);
|
||||
usableVoices.add (voice);
|
||||
std::sort (usableVoices.begin(), usableVoices.end(),
|
||||
[] (const MPESynthesiserVoice* a, const MPESynthesiserVoice* b) { return a->wasStartedBefore (*b); });
|
||||
|
||||
if (! voice->isPlayingButReleased()) // Don't protect released notes
|
||||
{
|
||||
const int noteNumber = voice->getCurrentlyPlayingNote().initialNote;
|
||||
auto noteNumber = voice->getCurrentlyPlayingNote().initialNote;
|
||||
|
||||
if (low == nullptr || noteNumber < low->getCurrentlyPlayingNote().initialNote)
|
||||
low = voice;
|
||||
|
|
@ -229,49 +221,29 @@ MPESynthesiserVoice* MPESynthesiser::findVoiceToSteal (MPENote noteToStealVoiceF
|
|||
if (top == low)
|
||||
top = nullptr;
|
||||
|
||||
const int numUsableVoices = usableVoices.size();
|
||||
|
||||
// If we want to re-use the voice to trigger a new note,
|
||||
// then The oldest note that's playing the same note number is ideal.
|
||||
if (noteToStealVoiceFor.isValid())
|
||||
{
|
||||
for (int i = 0; i < numUsableVoices; ++i)
|
||||
{
|
||||
MPESynthesiserVoice* const voice = usableVoices.getUnchecked (i);
|
||||
|
||||
for (auto* voice : usableVoices)
|
||||
if (voice->getCurrentlyPlayingNote().initialNote == noteToStealVoiceFor.initialNote)
|
||||
return voice;
|
||||
}
|
||||
}
|
||||
|
||||
// Oldest voice that has been released (no finger on it and not held by sustain pedal)
|
||||
for (int i = 0; i < numUsableVoices; ++i)
|
||||
{
|
||||
MPESynthesiserVoice* const voice = usableVoices.getUnchecked (i);
|
||||
|
||||
for (auto* voice : usableVoices)
|
||||
if (voice != low && voice != top && voice->isPlayingButReleased())
|
||||
return voice;
|
||||
}
|
||||
|
||||
// Oldest voice that doesn't have a finger on it:
|
||||
for (int i = 0; i < numUsableVoices; ++i)
|
||||
{
|
||||
MPESynthesiserVoice* const voice = usableVoices.getUnchecked (i);
|
||||
|
||||
for (auto* voice : usableVoices)
|
||||
if (voice != low && voice != top
|
||||
&& voice->getCurrentlyPlayingNote().keyState != MPENote::keyDown
|
||||
&& voice->getCurrentlyPlayingNote().keyState != MPENote::keyDownAndSustained)
|
||||
return voice;
|
||||
}
|
||||
|
||||
// Oldest voice that isn't protected
|
||||
for (int i = 0; i < numUsableVoices; ++i)
|
||||
{
|
||||
MPESynthesiserVoice* const voice = usableVoices.getUnchecked (i);
|
||||
|
||||
for (auto* voice : usableVoices)
|
||||
if (voice != low && voice != top)
|
||||
return voice;
|
||||
}
|
||||
|
||||
// We've only got "protected" voices now: lowest note takes priority
|
||||
jassert (low != nullptr);
|
||||
|
|
|
|||
|
|
@ -489,14 +489,6 @@ SynthesiserVoice* Synthesiser::findFreeVoice (SynthesiserSound* soundToPlay,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
struct VoiceAgeSorter
|
||||
{
|
||||
static int compareElements (SynthesiserVoice* v1, SynthesiserVoice* v2) noexcept
|
||||
{
|
||||
return v1->wasStartedBefore (*v2) ? -1 : (v2->wasStartedBefore (*v1) ? 1 : 0);
|
||||
}
|
||||
};
|
||||
|
||||
SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
|
||||
int /*midiChannel*/, int midiNoteNumber) const
|
||||
{
|
||||
|
|
@ -521,8 +513,9 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
|
|||
{
|
||||
jassert (voice->isVoiceActive()); // We wouldn't be here otherwise
|
||||
|
||||
VoiceAgeSorter sorter;
|
||||
usableVoices.addSorted (sorter, voice);
|
||||
usableVoices.add (voice);
|
||||
std::sort (usableVoices.begin(), usableVoices.end(),
|
||||
[] (const SynthesiserVoice* a, const SynthesiserVoice* b) { return a->wasStartedBefore (*b); });
|
||||
|
||||
if (! voice->isPlayingButReleased()) // Don't protect released notes
|
||||
{
|
||||
|
|
|
|||
|
|
@ -266,8 +266,7 @@ struct PluginSorter
|
|||
PluginSorter (KnownPluginList::SortMethod sortMethod, bool forwards) noexcept
|
||||
: method (sortMethod), direction (forwards ? 1 : -1) {}
|
||||
|
||||
int compareElements (const PluginDescription* const first,
|
||||
const PluginDescription* const second) const
|
||||
bool operator() (const PluginDescription* first, const PluginDescription* second) const
|
||||
{
|
||||
int diff = 0;
|
||||
|
||||
|
|
@ -284,7 +283,7 @@ struct PluginSorter
|
|||
if (diff == 0)
|
||||
diff = first->name.compareNatural (second->name, true);
|
||||
|
||||
return diff * direction;
|
||||
return diff * direction < 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -301,10 +300,8 @@ private:
|
|||
return 0;
|
||||
}
|
||||
|
||||
const KnownPluginList::SortMethod method;
|
||||
const int direction;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (PluginSorter)
|
||||
KnownPluginList::SortMethod method;
|
||||
int direction;
|
||||
};
|
||||
|
||||
void KnownPluginList::sort (const SortMethod method, bool forwards)
|
||||
|
|
@ -317,10 +314,7 @@ void KnownPluginList::sort (const SortMethod method, bool forwards)
|
|||
ScopedLock lock (typesArrayLock);
|
||||
|
||||
oldOrder.addArray (types);
|
||||
|
||||
PluginSorter sorter (method, forwards);
|
||||
types.sort (sorter, true);
|
||||
|
||||
std::stable_sort (types.begin(), types.end(), PluginSorter (method, forwards));
|
||||
newOrder.addArray (types);
|
||||
}
|
||||
|
||||
|
|
@ -531,12 +525,11 @@ KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortM
|
|||
|
||||
{
|
||||
ScopedLock lock (typesArrayLock);
|
||||
PluginSorter sorter (sortMethod, true);
|
||||
|
||||
for (auto* t : types)
|
||||
sorted.addSorted (sorter, t);
|
||||
sorted.addArray (types);
|
||||
}
|
||||
|
||||
std::stable_sort (sorted.begin(), sorted.end(), PluginSorter (sortMethod, true));
|
||||
|
||||
auto* tree = new PluginTree();
|
||||
|
||||
if (sortMethod == sortByCategory || sortMethod == sortByManufacturer || sortMethod == sortByFormat)
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ void StringArray::clearQuick()
|
|||
strings.clearQuick();
|
||||
}
|
||||
|
||||
const String& StringArray::operator[] (const int index) const noexcept
|
||||
const String& StringArray::operator[] (int index) const noexcept
|
||||
{
|
||||
if (isPositiveAndBelow (index, strings.size()))
|
||||
return strings.getReference (index);
|
||||
|
|
@ -128,7 +128,7 @@ const String& StringArray::operator[] (const int index) const noexcept
|
|||
#endif
|
||||
}
|
||||
|
||||
String& StringArray::getReference (const int index) noexcept
|
||||
String& StringArray::getReference (int index) noexcept
|
||||
{
|
||||
return strings.getReference (index);
|
||||
}
|
||||
|
|
@ -143,12 +143,12 @@ void StringArray::add (String&& stringToAdd)
|
|||
strings.add (static_cast<String&&> (stringToAdd));
|
||||
}
|
||||
|
||||
void StringArray::insert (const int index, const String& newString)
|
||||
void StringArray::insert (int index, const String& newString)
|
||||
{
|
||||
strings.insert (index, newString);
|
||||
}
|
||||
|
||||
bool StringArray::addIfNotAlreadyThere (const String& newString, const bool ignoreCase)
|
||||
bool StringArray::addIfNotAlreadyThere (const String& newString, bool ignoreCase)
|
||||
{
|
||||
if (contains (newString, ignoreCase))
|
||||
return false;
|
||||
|
|
@ -172,23 +172,23 @@ void StringArray::addArray (const StringArray& otherArray, int startIndex, int n
|
|||
strings.add (otherArray.strings.getReference (startIndex++));
|
||||
}
|
||||
|
||||
void StringArray::mergeArray (const StringArray& otherArray, const bool ignoreCase)
|
||||
void StringArray::mergeArray (const StringArray& otherArray, bool ignoreCase)
|
||||
{
|
||||
for (auto& s : otherArray)
|
||||
addIfNotAlreadyThere (s, ignoreCase);
|
||||
}
|
||||
|
||||
void StringArray::set (const int index, const String& newString)
|
||||
void StringArray::set (int index, const String& newString)
|
||||
{
|
||||
strings.set (index, newString);
|
||||
}
|
||||
|
||||
bool StringArray::contains (StringRef stringToLookFor, const bool ignoreCase) const
|
||||
bool StringArray::contains (StringRef stringToLookFor, bool ignoreCase) const
|
||||
{
|
||||
return indexOf (stringToLookFor, ignoreCase) >= 0;
|
||||
}
|
||||
|
||||
int StringArray::indexOf (StringRef stringToLookFor, const bool ignoreCase, int i) const
|
||||
int StringArray::indexOf (StringRef stringToLookFor, bool ignoreCase, int i) const
|
||||
{
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
|
|
@ -211,7 +211,7 @@ int StringArray::indexOf (StringRef stringToLookFor, const bool ignoreCase, int
|
|||
return -1;
|
||||
}
|
||||
|
||||
void StringArray::move (const int currentIndex, const int newIndex) noexcept
|
||||
void StringArray::move (int currentIndex, int newIndex) noexcept
|
||||
{
|
||||
strings.move (currentIndex, newIndex);
|
||||
}
|
||||
|
|
@ -222,7 +222,7 @@ void StringArray::remove (int index)
|
|||
strings.remove (index);
|
||||
}
|
||||
|
||||
void StringArray::removeString (StringRef stringToRemove, const bool ignoreCase)
|
||||
void StringArray::removeString (StringRef stringToRemove, bool ignoreCase)
|
||||
{
|
||||
if (ignoreCase)
|
||||
{
|
||||
|
|
@ -244,7 +244,7 @@ void StringArray::removeRange (int startIndex, int numberToRemove)
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
void StringArray::removeEmptyStrings (const bool removeWhitespaceStrings)
|
||||
void StringArray::removeEmptyStrings (bool removeWhitespaceStrings)
|
||||
{
|
||||
if (removeWhitespaceStrings)
|
||||
{
|
||||
|
|
@ -267,39 +267,19 @@ void StringArray::trim()
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
struct InternalStringArrayComparator_CaseSensitive
|
||||
{
|
||||
static int compareElements (String& s1, String& s2) noexcept { return s1.compare (s2); }
|
||||
};
|
||||
|
||||
struct InternalStringArrayComparator_CaseInsensitive
|
||||
{
|
||||
static int compareElements (String& s1, String& s2) noexcept { return s1.compareIgnoreCase (s2); }
|
||||
};
|
||||
|
||||
struct InternalStringArrayComparator_Natural
|
||||
{
|
||||
static int compareElements (String& s1, String& s2) noexcept { return s1.compareNatural (s2); }
|
||||
};
|
||||
|
||||
void StringArray::sort (const bool ignoreCase)
|
||||
void StringArray::sort (bool ignoreCase)
|
||||
{
|
||||
if (ignoreCase)
|
||||
{
|
||||
InternalStringArrayComparator_CaseInsensitive comp;
|
||||
strings.sort (comp);
|
||||
}
|
||||
std::sort (strings.begin(), strings.end(),
|
||||
[] (const String& a, const String& b) { return a.compareIgnoreCase (b) < 0; });
|
||||
else
|
||||
{
|
||||
InternalStringArrayComparator_CaseSensitive comp;
|
||||
strings.sort (comp);
|
||||
}
|
||||
std::sort (strings.begin(), strings.end());
|
||||
}
|
||||
|
||||
void StringArray::sortNatural()
|
||||
{
|
||||
InternalStringArrayComparator_Natural comp;
|
||||
strings.sort (comp);
|
||||
std::sort (strings.begin(), strings.end(),
|
||||
[] (const String& a, const String& b) { return a.compareNatural (b) < 0; });
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -340,7 +320,6 @@ String StringArray::joinIntoString (StringRef separator, int start, int numberTo
|
|||
}
|
||||
|
||||
dest.writeNull();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -426,7 +405,7 @@ StringArray StringArray::fromLines (StringRef stringToBreakUp)
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
void StringArray::removeDuplicates (const bool ignoreCase)
|
||||
void StringArray::removeDuplicates (bool ignoreCase)
|
||||
{
|
||||
for (int i = 0; i < size() - 1; ++i)
|
||||
{
|
||||
|
|
@ -444,8 +423,8 @@ void StringArray::removeDuplicates (const bool ignoreCase)
|
|||
}
|
||||
}
|
||||
|
||||
void StringArray::appendNumbersToDuplicates (const bool ignoreCase,
|
||||
const bool appendNumberToFirstInstance,
|
||||
void StringArray::appendNumbersToDuplicates (bool ignoreCase,
|
||||
bool appendNumberToFirstInstance,
|
||||
CharPointer_UTF8 preNumberString,
|
||||
CharPointer_UTF8 postNumberString)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -36,14 +36,6 @@ struct ZipFile::ZipEntryHolder
|
|||
entry.filename = String::fromUTF8 (buffer + 46, fileNameLen);
|
||||
}
|
||||
|
||||
struct FileNameComparator
|
||||
{
|
||||
static int compareElements (const ZipEntryHolder* e1, const ZipEntryHolder* e2) noexcept
|
||||
{
|
||||
return e1->entry.filename.compare (e2->entry.filename);
|
||||
}
|
||||
};
|
||||
|
||||
static Time parseFileTime (uint32 time, uint32 date) noexcept
|
||||
{
|
||||
int year = 1980 + (date >> 9);
|
||||
|
|
@ -321,8 +313,8 @@ InputStream* ZipFile::createStreamForEntry (const ZipEntry& entry)
|
|||
|
||||
void ZipFile::sortEntriesByFilename()
|
||||
{
|
||||
ZipEntryHolder::FileNameComparator sorter;
|
||||
entries.sort (sorter);
|
||||
std::sort (entries.begin(), entries.end(),
|
||||
[] (const ZipEntryHolder* e1, const ZipEntryHolder* e2) { return e1->entry.filename < e2->entry.filename; });
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -41,8 +41,9 @@ struct FFT::Engine
|
|||
{
|
||||
Engine (int priorityToUse) : enginePriority (priorityToUse)
|
||||
{
|
||||
EnginePriorityComparator comparator;
|
||||
getEngines().addSorted (comparator, this);
|
||||
auto& list = getEngines();
|
||||
list.add (this);
|
||||
std::sort (list.begin(), list.end(), [] (Engine* a, Engine* b) { return b->enginePriority < a->enginePriority; });
|
||||
}
|
||||
|
||||
virtual ~Engine() {}
|
||||
|
|
@ -61,15 +62,6 @@ struct FFT::Engine
|
|||
}
|
||||
|
||||
private:
|
||||
struct EnginePriorityComparator
|
||||
{
|
||||
static int compareElements (Engine* first, Engine* second) noexcept
|
||||
{
|
||||
// sort in reverse order
|
||||
return DefaultElementComparator<int>::compareElements (second->enginePriority, first->enginePriority);
|
||||
}
|
||||
};
|
||||
|
||||
static Array<Engine*>& getEngines()
|
||||
{
|
||||
static Array<Engine*> engines;
|
||||
|
|
|
|||
|
|
@ -148,6 +148,9 @@ public:
|
|||
*/
|
||||
PositionedGlyph& getGlyph (int index) const noexcept;
|
||||
|
||||
const PositionedGlyph* begin() const { return glyphs.begin(); }
|
||||
const PositionedGlyph* end() const { return glyphs.end(); }
|
||||
|
||||
//==============================================================================
|
||||
/** Clears all text from the arrangement and resets it. */
|
||||
void clear();
|
||||
|
|
|
|||
|
|
@ -217,29 +217,29 @@ private:
|
|||
GlyphArrangement ga;
|
||||
ga.addLineOfText (font, chars, 0, 0);
|
||||
|
||||
Array<float> y;
|
||||
DefaultElementComparator<float> sorter;
|
||||
Array<float> yValues;
|
||||
|
||||
for (int i = 0; i < ga.getNumGlyphs(); ++i)
|
||||
for (auto& glyph : ga)
|
||||
{
|
||||
Path p;
|
||||
ga.getGlyph (i).createPath (p);
|
||||
Rectangle<float> bounds (p.getBounds());
|
||||
glyph.createPath (p);
|
||||
auto bounds = p.getBounds();
|
||||
|
||||
if (! p.isEmpty())
|
||||
y.addSorted (sorter, getTop ? bounds.getY() : bounds.getBottom());
|
||||
yValues.add (getTop ? bounds.getY() : bounds.getBottom());
|
||||
}
|
||||
|
||||
float median = y[y.size() / 2];
|
||||
std::sort (yValues.begin(), yValues.end());
|
||||
|
||||
auto median = yValues[yValues.size() / 2];
|
||||
float total = 0;
|
||||
int num = 0;
|
||||
|
||||
for (int i = 0; i < y.size(); ++i)
|
||||
for (auto y : yValues)
|
||||
{
|
||||
if (std::abs (median - y.getUnchecked(i)) < 0.05f * (float) standardHeight)
|
||||
if (std::abs (median - y) < 0.05f * (float) standardHeight)
|
||||
{
|
||||
total += y.getUnchecked(i);
|
||||
total += y;
|
||||
++num;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -363,15 +363,14 @@ Path DrawableText::getOutlineAsPath() const
|
|||
|
||||
Path pathOfAllGlyphs;
|
||||
|
||||
for (int i = 0; i < arr.getNumGlyphs(); ++i)
|
||||
for (auto& glyph : arr)
|
||||
{
|
||||
Path gylphPath;
|
||||
arr.getGlyph (i).createPath (gylphPath);
|
||||
glyph.createPath (gylphPath);
|
||||
pathOfAllGlyphs.addPath (gylphPath);
|
||||
}
|
||||
|
||||
pathOfAllGlyphs.applyTransform (getTextTransform (w, h)
|
||||
.followedBy (getTransform()));
|
||||
pathOfAllGlyphs.applyTransform (getTextTransform (w, h).followedBy (getTransform()));
|
||||
|
||||
return pathOfAllGlyphs;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -216,20 +216,6 @@ bool DirectoryContentsList::checkNextFile (bool& hasChanged)
|
|||
return false;
|
||||
}
|
||||
|
||||
struct FileInfoComparator
|
||||
{
|
||||
static int compareElements (const DirectoryContentsList::FileInfo* const first,
|
||||
const DirectoryContentsList::FileInfo* const second)
|
||||
{
|
||||
#if JUCE_WINDOWS
|
||||
if (first->isDirectory != second->isDirectory)
|
||||
return first->isDirectory ? -1 : 1;
|
||||
#endif
|
||||
|
||||
return first->filename.compareNatural (second->filename);
|
||||
}
|
||||
};
|
||||
|
||||
bool DirectoryContentsList::addFile (const File& file, const bool isDir,
|
||||
const int64 fileSize,
|
||||
Time modTime, Time creationTime,
|
||||
|
|
@ -254,8 +240,18 @@ bool DirectoryContentsList::addFile (const File& file, const bool isDir,
|
|||
if (files.getUnchecked(i)->filename == info->filename)
|
||||
return false;
|
||||
|
||||
FileInfoComparator comp;
|
||||
files.addSorted (comp, info.release());
|
||||
files.add (info.release());
|
||||
|
||||
std::sort (files.begin(), files.end(), [] (const FileInfo* a, const FileInfo* b)
|
||||
{
|
||||
#if JUCE_WINDOWS
|
||||
if (a->isDirectory != b->isDirectory)
|
||||
return a->isDirectory;
|
||||
#endif
|
||||
|
||||
return a->filename.compareNatural (b->filename) < 0;
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,41 +29,38 @@ namespace juce
|
|||
|
||||
namespace KeyboardFocusHelpers
|
||||
{
|
||||
// This will sort a set of components, so that they are ordered in terms of
|
||||
// left-to-right and then top-to-bottom.
|
||||
struct ScreenPositionComparator
|
||||
static int getOrder (const Component* c)
|
||||
{
|
||||
static int compareElements (const Component* first, const Component* second)
|
||||
{
|
||||
auto explicitOrder1 = getOrder (first);
|
||||
auto explicitOrder2 = getOrder (second);
|
||||
|
||||
if (explicitOrder1 != explicitOrder2)
|
||||
return explicitOrder1 - explicitOrder2;
|
||||
|
||||
auto yDiff = first->getY() - second->getY();
|
||||
|
||||
return yDiff == 0 ? first->getX() - second->getX()
|
||||
: yDiff;
|
||||
}
|
||||
|
||||
static int getOrder (const Component* c)
|
||||
{
|
||||
auto order = c->getExplicitFocusOrder();
|
||||
return order > 0 ? order : (std::numeric_limits<int>::max() / 2);
|
||||
}
|
||||
};
|
||||
auto order = c->getExplicitFocusOrder();
|
||||
return order > 0 ? order : (std::numeric_limits<int>::max() / 2);
|
||||
}
|
||||
|
||||
static void findAllFocusableComponents (Component* parent, Array<Component*>& comps)
|
||||
{
|
||||
if (parent->getNumChildComponents() != 0)
|
||||
{
|
||||
Array<Component*> localComps;
|
||||
ScreenPositionComparator comparator;
|
||||
|
||||
for (auto* c : parent->getChildren())
|
||||
if (c->isVisible() && c->isEnabled())
|
||||
localComps.addSorted (comparator, c);
|
||||
localComps.add (c);
|
||||
|
||||
// This will sort so that they are ordered in terms of left-to-right
|
||||
// and then top-to-bottom.
|
||||
std::stable_sort (localComps.begin(), localComps.end(),
|
||||
[] (const Component* a, const Component* b)
|
||||
{
|
||||
auto explicitOrder1 = getOrder (a);
|
||||
auto explicitOrder2 = getOrder (b);
|
||||
|
||||
if (explicitOrder1 != explicitOrder2)
|
||||
return explicitOrder1 < explicitOrder2;
|
||||
|
||||
if (a->getY() != b->getY())
|
||||
return a->getY() < b->getY();
|
||||
|
||||
return a->getX() < b->getX();
|
||||
});
|
||||
|
||||
for (auto* c : localComps)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -111,7 +111,8 @@ struct FlexBoxLayoutCalculation
|
|||
for (auto& item : owner.items)
|
||||
itemStates.add (item);
|
||||
|
||||
itemStates.sort (*this, true);
|
||||
std::stable_sort (itemStates.begin(), itemStates.end(),
|
||||
[] (const ItemWithState& i1, const ItemWithState& i2) { return i1.item->order < i2.item->order; });
|
||||
|
||||
for (auto& item : itemStates)
|
||||
{
|
||||
|
|
@ -531,11 +532,6 @@ struct FlexBoxLayoutCalculation
|
|||
reverseWrap();
|
||||
}
|
||||
|
||||
static int compareElements (const ItemWithState& i1, const ItemWithState& i2) noexcept
|
||||
{
|
||||
return i1.item->order < i2.item->order ? -1 : (i2.item->order < i1.item->order ? 1 : 0);
|
||||
}
|
||||
|
||||
private:
|
||||
void resetRowItems (const int row) noexcept
|
||||
{
|
||||
|
|
|
|||
|
|
@ -737,7 +737,8 @@ struct Grid::AutoPlacement
|
|||
for (auto& item : grid.items)
|
||||
sortedItems.add (&item);
|
||||
|
||||
sortedItems.sort (*this, true);
|
||||
std::stable_sort (sortedItems.begin(), sortedItems.end(),
|
||||
[] (const GridItem* i1, const GridItem* i2) { return i1->order < i2->order; });
|
||||
|
||||
// place fixed items first
|
||||
for (auto* item : sortedItems)
|
||||
|
|
@ -843,12 +844,6 @@ struct Grid::AutoPlacement
|
|||
return { implicitColumnTracks, implicitRowTracks };
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static int compareElements (const GridItem* i1, const GridItem* i2) noexcept
|
||||
{
|
||||
return i1->order < i2->order ? -1 : (i2->order < i1->order ? 1 : 0);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static void applySizeForAutoTracks (juce::Array<Grid::TrackInfo>& columns,
|
||||
juce::Array<Grid::TrackInfo>& rows,
|
||||
|
|
|
|||
|
|
@ -1302,34 +1302,6 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct SortByCoordinate
|
||||
{
|
||||
bool sortByYCoordinate;
|
||||
|
||||
SortByCoordinate (bool byYCoordinate) : sortByYCoordinate (byYCoordinate)
|
||||
{
|
||||
}
|
||||
|
||||
int compareElements (const ExtendedInfo* a, const ExtendedInfo* b)
|
||||
{
|
||||
int coordinateA, coordinateB;
|
||||
|
||||
if (sortByYCoordinate)
|
||||
{
|
||||
coordinateA = a->totalBounds.getY();
|
||||
coordinateB = b->totalBounds.getY();
|
||||
}
|
||||
else
|
||||
{
|
||||
coordinateA = a->totalBounds.getX();
|
||||
coordinateB = b->totalBounds.getX();
|
||||
}
|
||||
|
||||
return coordinateA - coordinateB;
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
void updateScaledDisplayCoordinate (bool updateYCoordinates)
|
||||
{
|
||||
|
|
@ -1337,11 +1309,17 @@ private:
|
|||
return;
|
||||
|
||||
Array<ExtendedInfo*> copy;
|
||||
|
||||
for (auto& i : infos)
|
||||
copy.add (&i);
|
||||
|
||||
std::sort (copy.begin(), copy.end(), [updateYCoordinates] (const ExtendedInfo* a, const ExtendedInfo* b)
|
||||
{
|
||||
SortByCoordinate sorter (updateYCoordinates);
|
||||
for (int i = 0; i < infos.size(); ++i)
|
||||
copy.addSorted (sorter, &infos.getReference (i));
|
||||
}
|
||||
if (updateYCoordinates)
|
||||
return a->totalBounds.getY() < b->totalBounds.getY();
|
||||
|
||||
return a->totalBounds.getX() < b->totalBounds.getX();
|
||||
});
|
||||
|
||||
for (int i = 1; i < copy.size(); ++i)
|
||||
{
|
||||
|
|
@ -1351,13 +1329,14 @@ private:
|
|||
for (int j = i - 1; j >= 0; --j)
|
||||
{
|
||||
auto& other = *copy[j];
|
||||
int prevCoordinate = updateYCoordinates ? other.totalBounds.getBottom() : other.totalBounds.getRight();
|
||||
int curCoordinate = updateYCoordinates ? current.totalBounds.getY() : current.totalBounds.getX();
|
||||
auto prevCoordinate = updateYCoordinates ? other.totalBounds.getBottom() : other.totalBounds.getRight();
|
||||
auto curCoordinate = updateYCoordinates ? current.totalBounds.getY() : current.totalBounds.getX();
|
||||
|
||||
if (prevCoordinate == curCoordinate)
|
||||
{
|
||||
// both displays are aligned! As "other" comes before "current" in the array, it must already
|
||||
// have a valid topLeftScaled which we can use
|
||||
Point<int> topLeftScaled = other.topLeftScaled;
|
||||
auto topLeftScaled = other.topLeftScaled;
|
||||
topLeftScaled += Point<int> (other.totalBounds.getWidth(), other.totalBounds.getHeight()) / other.scale;
|
||||
|
||||
if (updateYCoordinates)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue