eurorack/midi2cv/menu/menu_items.h

130 lines
2.9 KiB
C
Raw Normal View History

2020-01-03 21:09:11 +00:00
#pragma once
#include "stmlib/stmlib.h"
#include <stdio.h>
// MenuItem without template so we can easily store pointers
class AbstractMenuItem {
public:
virtual const char* get_label();
virtual char* get_string_representation();
2020-02-21 00:39:20 +00:00
virtual void increase();
virtual void decrease();
2020-01-03 21:09:11 +00:00
};
template <class T>
class MenuItem : public AbstractMenuItem {
private:
const char* label;
bool visible;
2020-01-03 21:09:11 +00:00
T value;
T step;
char stringRepresentation[24];
protected:
MenuItem(const char* _label, T _initialValue)
: label(_label)
, visible(true)
2020-01-03 21:09:11 +00:00
, value(_initialValue) {};
virtual void to_string(char* buf) = 0;
void set_value(T value)
{
this->value = value;
this->to_string(stringRepresentation);
};
public:
T get_value()
{
return value;
}
const char* get_label()
{
return label;
}
char* get_string_representation()
{
2020-02-17 19:33:01 +00:00
if (!stringRepresentation[0])
this->to_string(stringRepresentation);
2020-01-03 21:09:11 +00:00
return stringRepresentation;
}
};
template <class T>
class NumberMenuItem : public MenuItem<T> {
private:
T minimumValue;
T maximumValue;
2020-02-21 00:39:20 +00:00
T step;
2020-01-03 21:09:11 +00:00
protected:
NumberMenuItem(const char* _label, T _initialValue, T _minimumValue, T _maximumValue, T _step)
: MenuItem<T>(_label, _initialValue)
, minimumValue(_minimumValue)
2020-02-21 00:39:20 +00:00
, maximumValue(_maximumValue)
, step(_step) {};
2020-01-03 21:09:11 +00:00
virtual const char* get_format_string() = 0;
void to_string(char* buf)
{
sprintf(buf, this->get_format_string(), this->get_value());
}
public:
void increase()
{
2020-02-21 00:39:20 +00:00
if (this->get_value() + step <= maximumValue && this->get_value() + step >= minimumValue)
2020-01-03 21:09:11 +00:00
this->set_value(this->get_value() + step);
};
void decrease()
{
2020-02-21 00:39:20 +00:00
if (this->get_value() - step >= minimumValue && this->get_value() - step <= maximumValue)
2020-01-03 21:09:11 +00:00
this->set_value(this->get_value() - step);
};
};
class UIntMenuItem : public NumberMenuItem<uint32_t> {
private:
protected:
const char* get_format_string()
{
return "%u";
}
public:
UIntMenuItem(const char* _label, uint32_t _initialValue, uint32_t _minimumValue, uint32_t _maximumValue, uint32_t _step)
2020-02-17 19:33:01 +00:00
: NumberMenuItem(_label, _initialValue, _minimumValue, _maximumValue, _step) {};
2020-01-03 21:09:11 +00:00
};
class IntMenuItem : public NumberMenuItem<int32_t> {
private:
protected:
const char* get_format_string()
{
return "%d";
}
public:
IntMenuItem(const char* _label, int32_t _initialValue, int32_t _minimumValue, int32_t _maximumValue, int32_t _step)
: NumberMenuItem(_label, _initialValue, _minimumValue, _maximumValue, _step) {};
};
class FloatMenuItem : public NumberMenuItem<float> {
private:
protected:
const char* get_format_string()
{
2020-02-21 00:39:20 +00:00
return "%.2f";
2020-01-03 21:09:11 +00:00
}
public:
FloatMenuItem(const char* _label, float _initialValue, float _minimumValue, float _maximumValue, float _step)
: NumberMenuItem(_label, _initialValue, _minimumValue, _maximumValue, _step) {};
};