16#include <unordered_map>
61 static const std::unordered_map<wxString, wxString> selectionFormatLookup = {
62 { L
"seconds", L
"seconds" },
63 { L
"seconds + milliseconds", L
"milliseconds" },
64 { L
"hh:mm:ss", L
"seconds" },
65 { L
"dd:hh:mm:ss", L
"seconds" },
66 { L
"hh:mm:ss + hundredths", L
"centiseconds" },
67 { L
"hh:mm:ss + milliseconds", L
"milliseconds" },
68 { L
"hh:mm:ss + samples", L
"samples" },
69 { L
"samples", L
"samples" },
70 { L
"hh:mm:ss + film frames (24 fps)", L
"film_24_fps" },
71 { L
"film frames (24 fps)", L
"film_24_fps" },
72 { L
"hh:mm:ss + NTSC drop frames", L
"ntsc_29.97_fps" },
74 { L
"hh:mm:ss + NTSC non-drop frames", L
"ntsc_30_fps" },
75 { L
"NTSC frames", L
"ntsc_29.97_fps" },
76 { L
"hh:mm:ss + PAL frames (25 fps)", L
"film_25_fps" },
77 { L
"PAL frames (25 fps)", L
"film_25_fps" },
78 { L
"hh:mm:ss + CDDA frames (75 fps)", L
"cd_75_fps" },
79 { L
"CDDA frames (75 fps)", L
"cd_75_fps" },
82 auto it = selectionFormatLookup.find(selectionFormat);
84 if (it != selectionFormatLookup.end())
114 { { L
"", L
"beats,triplets,time,video,cd" } },
123 using Cache = std::unordered_map<Identifier, const SnapRegistryItem*>;
126 auto it = cache.find(
id);
127 if (it != cache.end())
131 auto it = cache.find(item.
name);
133 if (it == cache.end())
135 cache.insert({ item.
name, &item });
143 return it != cache.end() ? it->second :
nullptr;
150 auto item =
Find(
id);
155 return item->Snap(
project, time, nearest);
162 auto item =
Find(
id);
167 return item->SingleStep(
project, time, upwards);
176 : SingleItem { internalName }
189 if (multiplier <= 0.0)
192 auto result = nearest ?
std::round(value * multiplier) / multiplier :
193 std::floor(value * multiplier) / multiplier;
205 , mMultiplier { multiplier }
207 assert(mMultiplier > 0.0);
219 const auto step = (upwards ? 1.0 : -1.0) / mMultiplier;
220 const double result = time + step;
223 return { 0.0,
false };
239 , mMultiplierFunctor {
std::move(functor) }
241 assert(mMultiplierFunctor);
247 if (!mMultiplierFunctor)
248 return { time,
false };
255 if (!mMultiplierFunctor)
256 return { time,
false };
258 const auto multiplier = mMultiplierFunctor(
project);
261 std::max(1.0, time) * std::numeric_limits<double>::epsilon();
263 const auto current =
static_cast<int>(std::floor(time * (1.0 + eps) * multiplier));
264 const auto next = upwards ? current + 1 : current - 1;
266 double result = next / multiplier;
269 return { 0.0,
false };
271 while (
static_cast<int>(std::floor(result * multiplier)) < next)
274 while (
static_cast<int>(std::floor(result * multiplier)) > next)
277 return { result,
true };
290 return std::make_unique<ProjectDependentMultiplierSnapItem>(
291 functionId,
label, std::move(functor));
298 return std::make_unique<ConstantMultiplierSnapItem>(
299 functionId,
label, multiplier);
audacity::BasicSettings * gPrefs
StringSetting SnapToSetting
std::unique_ptr< SnapRegistryItem > TimeInvariantSnapFunction(const Identifier &functionId, const TranslatableString &label, MultiplierFunctor functor)
EnumSetting< SnapMode > SnapModeSetting
std::function< double(const AudacityProject &)> MultiplierFunctor
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Adapts EnumSettingBase to a particular enumeration type.
An explicitly nonlocalized string, not meant for the user to see.
bool Write(const T &value)
Write value to config and return true if successful.
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined */
const T & GetDefault() const
Specialization of Setting for strings.
Holds a msgid for the translation catalog; may also bind format arguments.
SnapResult Snap(const AudacityProject &, double time, bool nearest) const override
ConstantMultiplierSnapItem(const Identifier &internalName, const TranslatableString &label, double multiplier)
SnapResult SingleStep(const AudacityProject &project, double time, bool upwards) const override
SnapResult SingleStep(const AudacityProject &project, double time, bool upwards) const override
const MultiplierFunctor mMultiplierFunctor
SnapResult Snap(const AudacityProject &project, double time, bool nearest) const override
ProjectDependentMultiplierSnapItem(const Identifier &internalName, const TranslatableString &label, MultiplierFunctor functor)
virtual bool Flush() noexcept=0
virtual bool HasEntry(const wxString &key) const =0
Checks whether specified key exists within the current group.
virtual bool Read(const wxString &key, bool *value) const =0
void Visit(const Visitors &visitors, const GroupItem< RegistryTraits > *pTopItem, const GroupItem< RegistryTraits > *pRegistry={}, typename RegistryTraits::ComputedItemContextType &computedItemContext=RegistryTraits::ComputedItemContextType::Instance)
void VisitWithFunctions(const VisitorFunctions< RegistryTraits > &visitors, const GroupItem< RegistryTraits > *pTopItem, const GroupItem< RegistryTraits > *pRegistry={}, typename RegistryTraits::ComputedItemContextType &computedItemContext=RegistryTraits::ComputedItemContextType::Instance)
const wxString SelectionFormatKey
SnapResult SnapWithMultiplier(double value, double multiplier, bool nearest)
const wxString SnapModeKey
const wxString OldSnapToKey
fastfloat_really_inline void round(adjusted_mantissa &am, callback cb) noexcept
static const SnapRegistryItem * Find(const Identifier &id)
static void Visit(const SnapRegistryVisitor &visitor)
static SnapResult Snap(const Identifier &id, const AudacityProject &project, double time, bool nearest)
static Registry::GroupItem< SnapRegistryTraits > & Registry()
static SnapResult SingleStep(const Identifier &id, const AudacityProject &project, double time, bool upwards)
~SnapRegistryGroup() override
SnapRegistryItem(const Identifier &internalName, const TranslatableString &label)
~SnapRegistryItem() override