Number_Slider¶
Beschreibung¶
Diese Klasse ermöglicht das Erstellen von einfachen Schiebereglern. Sie erbt von Number_Input.
Beispielbild¶
Diese Bild dient nur der Veranschaulichung, wie Objekte dieser Klasse aussehen können.
new Number_Slider(COLOR_BLUE, TML_empty_slider, &numberValue2)
new Number_Slider((COLOR_RED|COLOR_LIGHT_YELLOW|COLOR_GRAY) + COLOR_DARK_GREEN, TML_empty_slider, &numberValue)
Funktionen¶
inline |
Number_Slider (const Color& color, const std::function<void(int)> slider_callback, ExternalNumberValue* value=nullptr) |
inline void |
draw () |
inline void |
setTouch (Inputs& input) override |
inline bool |
checkSize (uint16_t sizeX, uint16_t sizeY, uint8_t rotation) override |
Variablen und Konstanten¶
const „Color“ |
|
bool |
isVertical = false |
const uint16_t |
t = 5 |
const uint16_t |
b = 4 |
const uint16_t |
r = 6 |
Funktionen Beschreibung¶
inline Number_Slider(const Color& color, const std::function<void(int)> slider_callback, ExternalNumberValue* value=nullptr)¶
1 inline Number_Slider(const Color& color, const std::function<void(int)> slider_callback, ExternalNumberValue* value=nullptr):
2 NumberInput(slider_callback, value),
3 color(color)
4 {}
5
6 inline void draw() {
7
Diese Funktion ist ein Konstruktor, der einen rechteckigen Slider erzeugt.
Als Parameter nimmt der Konstruktor eine Farbe (color), die „Callback“ Funktion slider_callback und einem value, der angibt, ob das Objekt aktiviert oder deaktiviert ist.
In der Initialisierungsliste erfolgt zuerst der Aufruf vom „NumberInput Konstruktor“. Außerdem erfolgt die Initialisierung von color mit dem entsprechenden Parameter.
inline void draw();¶
1 LOGGER_ERROR("DISPLAY IS NULLPTR!")
2 return;
3 }
4
5 uint16_t size = isVertical? sizeY : sizeX;
6 uint16_t boxes = (uint16_t)(getMaxValue() - getMinValue()) / steps;
7
8 // calculate position for the slider
9 if (getMaxValue() == getMinValue())
10 sliderPos = size/2;
11
12 else if (boxes * r > size)
13 sliderPos = map(value, minValue-1, maxValue+1, 0, size);
14
15 else {
16 uint16_t boxSize = size / boxes;
17 sliderPos = boxSize * value/steps + boxSize/2;
18 }
19
20 uint16_t sy = sizeY - (2*b) - (2*t); // Slider movement length
Diese Funktion zeichnet Objekte der Number_Slider Klasse. Für den Zeichenprozess ist es relevant, ob das Objekt vertikal oder horizontal ausgerichtet
ist (isVertical).
}
uint16_t size = isVertical? sizeY : sizeX;
uint16_t boxes = (uint16_t)(getMaxValue() - getMinValue()) / steps;
// calculate position for the slider
if (getMaxValue() == getMinValue())
sliderPos = size/2;
Sollte isVertical==true gelten, soll das Objekt auch vertikal gezeichnet werden. Dafür wird zuerst die Variable sy erstellt, welche den Wert von sizeY annimmt
abzüglich der Breite der Umrandung (“b“) und dem Abstand zur Umrandung (“t“). Beide werden mit 2 multipliziert, da sich
die Umrandung auf beiden Seiten des Elements befindet. Mit sliderPos wird die Y-Koordinate des Schiebereglers berechnet, bei welcher sich der Regler momentan befindet.
Zuerst zeichnent wir mit dem Funktionsaufruf von „rect_center“ auf dem „display“ Objekt den deaktivierten Bereich des
Sliders, um dann beim „rect“ Funktionsaufruf den aktivierten Bereich des Sliders über Teile des deaktivierten Bereichs überzuzeichnen.
Schließlich wird durch den folgenden „rect_center“ Funktionsaufruf der Schieberegler zwischen dem aktivierten und deaktivierten Bereich gezeichnet.
else if (boxes * r > size)
sliderPos = map(value, minValue-1, maxValue+1, 0, size);
else {
uint16_t boxSize = size / boxes;
sliderPos = boxSize * value/steps + boxSize/2;
}
Sollte isVertical==false gelten, soll das Objekt horizontal statt vertikal gezeichnet werden. Der prinzipielle Ablauf bleibt aber der selbe.
inline void setTouch(Inputs& input) override;¶
1
2 if (isVertical) {
3 display->rect_center(posX + sizeX/2, posY + sizeY/2, sizeX - t*2, sizeY - t*2, b, r, color.getBorderColor(), color.getSecondaryColor()); //
4 display->rect(posX + t + b, posY + t + b + sliderPos, sx, sy - sliderPos, 0, r, color.getBorderColor(), color); //
5 display->rect_center(posX + sizeX/2, posY + t + b + sliderPos, sx + b, r * 2, 0, r, color.getBorderColor(), color.getItemColor()); // Slider
6
7 // // Dubug Hitboxes:
8 // if (getMinValue() != getMaxValue()) {
9 // uint16_t boxes = (uint16_t)(getMaxValue() - getMinValue()) / steps;
10 // for (int i = 0; i < boxes; i++)
11 // display->line(posX, sizeY/boxes*i + posY + t + b, posX+sizeX, sizeY/boxes*i + posY + t + b, COLOR_RED);
12 // LOGGER(boxes)
13 // }
14
15 } else {
16 display->rect_center(posX + sizeX/2, posY + sizeY/2, sizeX - t*2, sizeY - t*2, b, r, color.getBorderColor(), color.getSecondaryColor());
17 display->rect(posX + t + b, posY + t + b, sliderPos, sy, 0, r, color.getBorderColor(), color);
18 display->rect_center(posX + t + b + sliderPos, posY + sizeY/2, r * 2, sy + b, 0, r, color.getBorderColor(), color.getItemColor());
19 }
20 }
21
22
23 // value soll 0 - 10 in 2er schritten abbilden können (also 0, 2, 4, 6, 8, 10)
24 // Slider soll dabei auf der Mitte anhalten
Um den Schieberegler des Number_Slider Objekts auch verschieben zu können, muss mit dieser Funktion ermittelt werden, ob und wo der Benutzer das Objekt berührt.
Die Parameter x und y geben an, wo „Display“ berührt wird.
display->rect(posX + t + b, posY + t + b + sliderPos, sx, sy - sliderPos, 0, r, color.getBorderColor(), color); //
display->rect_center(posX + sizeX/2, posY + t + b + sliderPos, sx + b, r * 2, 0, r, color.getBorderColor(), color.getItemColor()); // Slider
// // Dubug Hitboxes:
// if (getMinValue() != getMaxValue()) {
x1 entspricht der X-Koordinate, bei dem das Objekt anfängt.xr entspricht der X-Koordinate, bei dem das Objekt endet.y1 entspricht der Y-Koordinate, bei dem das Objekt anfängt.yr entspricht der Y-Koordinate, bei dem das Objekt endet. // for (int i = 0; i < boxes; i++)
// display->line(posX, sizeY/boxes*i + posY + t + b, posX+sizeX, sizeY/boxes*i + posY + t + b, COLOR_RED);
Sollte sich y nicht zwischen y1 und yr befinden, wird das Objekt nicht berührt und der Schieberegler wird nicht angepasst. Selbiges gilt, wenn
x sich nicht zwischen x1 und xr befindet. Andernfalls wird das Objekt berührt.
// LOGGER(boxes)
// }
Bei einem vertikalen (isVertical) Objekt, muss nur die Y-Koordinate des Schiebereglers beachtet werden, da dieser sich von oben nach unten bzw. umgekehrt bewegen lässt. Dafür wird für value die neue Y-Koordinate des Reglerposition gespeichert.
} else {
display->rect_center(posX + sizeX/2, posY + sizeY/2, sizeX - t*2, sizeY - t*2, b, r, color.getBorderColor(), color.getSecondaryColor());
display->rect(posX + t + b, posY + t + b, sliderPos, sy, 0, r, color.getBorderColor(), color);
display->rect_center(posX + t + b + sliderPos, posY + sizeY/2, r * 2, sy + b, 0, r, color.getBorderColor(), color.getItemColor());
Bei einem horizontalen (isVertical) Objekt, muss nur die X-Koordinate des Schiebereglers beachtet werden, da dieser sich von rechts nach links bzw. umgekehrt bewegen lässt. Dafür wird für value die neue X-Koordinate der Reglerposition gespeichert.
}
}
Sollte „externalValue“ nicht null sein, so wird er mit dem neuen „value“ aktualisiert.
Anschließend wird die „Callback Funktion“ aufgerufen.
Zum Schluss folgt ein Aufruf der „draw“ Funktion, um die neue Schiebereglerposition zu zeichnen.
inline bool checkSize(uint16_t sizeX, uint16_t sizeY, uint8_t rotation) override;¶
1 uint16_t xr = xl + sizeX - (2*b) - (2*t); // Right X value
2
3 uint16_t yl = posY + t + b; // Left Y value
4 uint16_t yr = yl + sizeY - (2*b) - (2*t); // Right Y value
5
6 if (!(xl < input.touchX && input.touchX < xr)) return;
7 if (!(yl < input.touchY && input.touchY < yr)) return;
8
9 int new_value;
10 if (isVertical) new_value = map(input.touchY, yl, yr, minValue, maxValue);
11 else new_value = map(input.touchX, xl, xr, minValue, maxValue);
12
13 if (new_value == value) return;
14 else value = getMinValue() + (int)((new_value - getMinValue()) / steps) * steps;
15
Diese Funktion testet, ob die Höhe (sizeX) und Breite (sizeY) eines Objektes in einem bestimmten Größenverhältnis zueinander stehen, um das Objekt zeichnen zu können.
uint16_t yl = posY + t + b; // Left Y value
uint16_t yr = yl + sizeY - (2*b) - (2*t); // Right Y value
if (!(xl < input.touchX && input.touchX < xr)) return;
Wenn ein Objekt mindestens 1.5 mal so hoch ist, wie es breit ist, dann ist das Objekt „vertikal“ und zeichenbar.
int new_value;
if (isVertical) new_value = map(input.touchY, yl, yr, minValue, maxValue);
else new_value = map(input.touchX, xl, xr, minValue, maxValue);
Wenn ein Objekt mindestens 1.5 mal so breit ist, wie es hoch ist, dann ist das Objekt horizontal und zeichenbar.
if (new_value == value) return;
else value = getMinValue() + (int)((new_value - getMinValue()) / steps) * steps;
Stimmt das Verhältnis nicht, ist das Objekt weder vertikal noch horizontal.
Variablen und Konstanten Beschreibung¶
const Color color¶
Gibt die Farbe (Color) des Objektes an.
bool isVertical = false;¶
Gibt an, ob das Objekt horizontal oder vertikal ist.
const uint16_t t = 10¶
Gibt den Abstand zur Umrandung an.
const uint16_t b = 10¶
Gibt die Breite der Umrandung an.
const uint16_t r = 6¶
Gibt den Radius der Umrandung (bzw. den Krümmungsgrad) an.