Kachelsymbole: jedes Bootstrap-Icon statt einer Handvoll
Fuer die Symbole vor den Zahlen standen drei Codepunkte von Hand in rooms.php, und die Maske bot genau diese drei an. Jedes weitere Symbol waere eine Codeaenderung gewesen. Die Codepunkte stehen aber schon im Haus: css/bootstrap-icons.min.css fuehrt sie unter .bi-<name>::before - dieselbe Quelle, aus der auch der Browser liest. bootstrapIcons() liest sie von dort (2078 Stueck, einmal je Anfrage), kachelIcon() schlaegt darin nach. Damit ist jedes Symbol moeglich, und ein Versionswechsel der Icons zieht von selbst mit. In der Maske steht deshalb kein Auswahlfeld mehr, sondern der Name mit einer Vorschau davor - "moisture" sagt nichts, das Symbol daneben schon. Die Vorschlagsliste beginnt mit gut dreissig ueblichen Symbolen unter deutscher Beschriftung (Temperatur, Feuchte, Leistung, Wallbox, Regen ...), danach folgt der ganze Rest alphabetisch. Ein Name, den es nicht gibt, zeigt sofort ein rotes Fragezeichen und wird beim Speichern mit Begruendung abgelehnt. In der eingeklappten Kurzfassung einer Kachel steht das Symbol jetzt mit - es ist das schnellste Erkennungszeichen dafuer, welcher der drei Werte gemeint ist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+97
-9
@@ -18,7 +18,10 @@
|
||||
* einheit sonst die Einheit, die hinter der Zahl steht
|
||||
* stellen Nachkommastellen (0-3)
|
||||
* gross die Zahl steht gross auf der Kachel
|
||||
* icon Symbol vor der Zahl, siehe kachelIcon() in rooms.php
|
||||
* icon Symbol vor der Zahl: der Name eines Bootstrap-Icons ohne
|
||||
* das "bi-" davor ("thermometer-half"). Erlaubt ist jedes,
|
||||
* das im Stylesheet steht - siehe bootstrapIcons() in
|
||||
* rooms.php; kachelSymbole() ist nur die Vorschlagsliste.
|
||||
*
|
||||
* Die Tabelle darf fehlen. Ist sie nicht angelegt (solarLog_kacheln.sql), so
|
||||
* verhält sich alles wie vorher, statt dass die Startseite mit einem
|
||||
@@ -38,17 +41,97 @@ require_once(__DIR__ . "/costs.php"); // solarDb()
|
||||
/** Höchstens drei Werte je Kachel - mehr passt nicht auf 24 x 19 Einheiten. */
|
||||
const KACHEL_MAX = 3;
|
||||
|
||||
/** Symbole, die vor einer Zahl stehen dürfen. Schlüssel wie in kachelIcon(). */
|
||||
/**
|
||||
* Vorschläge für das Symbol vor einer Zahl.
|
||||
*
|
||||
* Erlaubt ist jedes Bootstrap-Icon (bootstrapIcons() in rooms.php liest sie
|
||||
* aus dem Stylesheet, es sind gut zweitausend). Diese Liste ist deshalb keine
|
||||
* Beschränkung, sondern eine Abkürzung: sie steht in der Maske obenan, damit
|
||||
* man für die üblichen Messwerte nicht erst einen Namen suchen muss.
|
||||
*
|
||||
* Gruppiert nach dem, was auf den Kacheln steht - nicht nach dem, wie die
|
||||
* Symbole heißen.
|
||||
*/
|
||||
function kachelSymbole()
|
||||
{
|
||||
return [
|
||||
"" => "ohne",
|
||||
"ev-station" => "Ladesäule",
|
||||
"cloud-rain" => "Regen",
|
||||
"sun" => "Sonne",
|
||||
"Klima" => [
|
||||
"thermometer-half" => "Temperatur",
|
||||
"thermometer-sun" => "Temperatur draußen",
|
||||
"thermometer-snow" => "Kälte",
|
||||
"droplet-half" => "Feuchte",
|
||||
"moisture" => "Luftfeuchte",
|
||||
"fan" => "Lüftung",
|
||||
"fire" => "Heizung",
|
||||
"wind" => "Wind",
|
||||
],
|
||||
"Strom" => [
|
||||
"lightning-charge-fill" => "Leistung",
|
||||
"plug-fill" => "Verbrauch",
|
||||
"sun" => "Erzeugung",
|
||||
"battery-half" => "Speicher",
|
||||
"battery-charging" => "Ladung",
|
||||
"ev-station" => "Wallbox",
|
||||
"car-front" => "Fahrzeug",
|
||||
"speedometer2" => "Zähler",
|
||||
"graph-up-arrow" => "Ertrag",
|
||||
"arrow-down-up" => "Bezug und Einspeisung",
|
||||
],
|
||||
"Wasser und Wetter" => [
|
||||
"cloud-rain" => "Regen",
|
||||
"cloud-sun" => "Wetter",
|
||||
"snow" => "Schnee",
|
||||
"water" => "Wasserstand",
|
||||
"bucket" => "Menge",
|
||||
"tree" => "Garten",
|
||||
],
|
||||
"Haus" => [
|
||||
"lightbulb" => "Licht",
|
||||
"door-open" => "Tür",
|
||||
"window" => "Fenster",
|
||||
"house-door" => "Haus",
|
||||
"clock-history" => "Zeit",
|
||||
"wifi" => "Verbindung",
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/** Die Vorschläge flach, wie die Maske sie braucht: Name => Beschriftung. */
|
||||
function kachelSymboleFlach()
|
||||
{
|
||||
$flach = [];
|
||||
foreach (kachelSymbole() as $gruppe) {
|
||||
foreach ($gruppe as $name => $titel) {
|
||||
$flach[$name] = $titel;
|
||||
}
|
||||
}
|
||||
return $flach;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alle Symbolnamen für die Vorschlagsliste der Maske.
|
||||
*
|
||||
* Die Vorschläge zuerst und mit ihrer Beschriftung, danach der ganze Rest
|
||||
* alphabetisch: so steht das Übliche oben, und wer etwas anderes will, tippt
|
||||
* los und bekommt es angeboten.
|
||||
*/
|
||||
function kachelIconNamen()
|
||||
{
|
||||
$vorschlag = kachelSymboleFlach();
|
||||
$liste = [];
|
||||
foreach ($vorschlag as $name => $titel) {
|
||||
if (isset(bootstrapIcons()[$name])) {
|
||||
$liste[] = ["name" => $name, "titel" => $titel];
|
||||
}
|
||||
}
|
||||
foreach (array_keys(bootstrapIcons()) as $name) {
|
||||
if (!isset($vorschlag[$name])) {
|
||||
$liste[] = ["name" => $name, "titel" => ""];
|
||||
}
|
||||
}
|
||||
return $liste;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alle Kacheln mit ihrem aktuellen Stand, für die Einstellungsseite.
|
||||
*
|
||||
@@ -262,10 +345,15 @@ function kachelWertPruefen($wert, $nummer)
|
||||
}
|
||||
}
|
||||
|
||||
$icon = (string)($wert["icon"] ?? "");
|
||||
// Jedes Bootstrap-Icon darf es sein; geprüft wird gegen dieselbe Liste,
|
||||
// aus der die Anzeige später das Zeichen holt. Ein Tippfehler faellt so
|
||||
// beim Speichern auf und nicht erst als leere Stelle auf der Kachel.
|
||||
$icon = trim((string)($wert["icon"] ?? ""));
|
||||
if ($icon !== "") {
|
||||
if (!array_key_exists($icon, kachelSymbole())) {
|
||||
throw new InvalidArgumentException("Wert " . $nummer . ": unbekanntes Symbol.");
|
||||
if (!isset(bootstrapIcons()[$icon])) {
|
||||
throw new InvalidArgumentException(
|
||||
"Wert " . $nummer . ": das Symbol \"" . $icon . "\" gibt es nicht. "
|
||||
. "Die Namen stehen auf icons.getbootstrap.com, ohne das \"bi-\" davor.");
|
||||
}
|
||||
$sauber["icon"] = $icon;
|
||||
}
|
||||
|
||||
+40
-10
@@ -202,25 +202,55 @@ function floorLabel($floor)
|
||||
}
|
||||
|
||||
/**
|
||||
* Codepunkt eines Bootstrap-Icons für die Kacheln.
|
||||
* Alle Bootstrap-Icons als Name => Codepunkt.
|
||||
*
|
||||
* Die Zahlen standen früher als Handabschrift hier - drei Stück, und jedes
|
||||
* weitere Symbol war eine Codeänderung. Sie stehen aber ohnehin schon im
|
||||
* Haus: css/bootstrap-icons.min.css führt sie unter .bi-<name>::before, das
|
||||
* ist die Quelle, aus der auch der Browser liest. Also wird sie gelesen,
|
||||
* statt sie abzuschreiben; damit steht jedes der gut zweitausend Symbole zur
|
||||
* Verfügung, und ein Wechsel der Icon-Version zieht von selbst mit.
|
||||
*
|
||||
* Einmal je Anfrage - das Auslesen kostet rund eine Millisekunde, und die
|
||||
* Startseite fragt für jede Kachel nach.
|
||||
*/
|
||||
function bootstrapIcons()
|
||||
{
|
||||
static $icons = null;
|
||||
if ($icons !== null) {
|
||||
return $icons;
|
||||
}
|
||||
$icons = [];
|
||||
$css = @file_get_contents(__DIR__ . "/../css/bootstrap-icons.min.css");
|
||||
if ($css === false) {
|
||||
return $icons; // ohne Datei eben ohne Symbole
|
||||
}
|
||||
// Im CSS steht content:"\f5a2" - der Backslash gehoert zum Inhalt, im
|
||||
// Muster ist er deshalb doppelt.
|
||||
if (preg_match_all('/\.bi-([a-z0-9-]+)::before\{content:"\\\\([0-9a-f]+)"\}/',
|
||||
$css, $treffer, PREG_SET_ORDER)) {
|
||||
foreach ($treffer as $t) {
|
||||
$icons[$t[1]] = hexdec($t[2]);
|
||||
}
|
||||
}
|
||||
return $icons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Das Zeichen eines Bootstrap-Icons für die Kacheln.
|
||||
*
|
||||
* Die Icons kommen als Schrift, nicht als Pfad: css/bootstrap-icons.min.css
|
||||
* ist ohnehin eingebunden (restricted/header.php), und SVG-Text darf dieselbe
|
||||
* Schriftfamilie benutzen wie HTML. Ein eingebettetes <path> je Symbol wäre
|
||||
* dieselbe Wirkung mit mehr Zeilen.
|
||||
*
|
||||
* Die Zahlen stehen in genau dieser CSS unter .bi-<name>::before und sind von
|
||||
* dort abgeschrieben - deshalb steht der Name daneben, sonst prüft das nie
|
||||
* wieder jemand nach.
|
||||
* Ein unbekannter Name gibt einen leeren Text - die Kachel zeigt dann die
|
||||
* Zahl ohne Symbol, statt ein leeres Kästchen anzuzeigen.
|
||||
*/
|
||||
function kachelIcon($name)
|
||||
{
|
||||
$icons = [
|
||||
"ev-station" => "F83A", // Wallbox, Ladeleistung
|
||||
"cloud-rain" => "F2B6", // Regenmenge
|
||||
"sun" => "F5A2", // PV-Erzeugung
|
||||
];
|
||||
return isset($icons[$name]) ? mb_chr(hexdec($icons[$name]), "UTF-8") : "";
|
||||
$icons = bootstrapIcons();
|
||||
return isset($icons[$name]) ? mb_chr($icons[$name], "UTF-8") : "";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user