In den letzten Wochen und Monaten habe ich einem "Alternativprojekt" versucht einen Skin mal ganz anders anzugehen.
Leider wird die Dokumentation darüber etwas Umfangreich. Sie richtet sich nur an Skinner und ist ohne Übung nicht umsetzbar.
[h1]Ausgangslage[/h1]
- Kodi enthält über 100 Default Icons,
- viele sind mehr oder weniger nur an einer Stelle vorhanden,
- andere irgendwie überall, nur immer anders,
- die Icons Nerven irgendwie, aber ohne sieht es dann auch irgendwie langweilig aus.
Erstellt man nun auch noch einen Skin der Icons für Menüs und dergleichen nutzt, kommt man schnell auf über 200 Icons.
[h1]Die Problematik[/h1]
- Man hat Hunderte Default Icons.
- Teilweise werden die für recht unterschiedliche "Dinge" eingesetzt. "Default Folder" kann im Filebrowser in einem Format
30x30, aber genauso gut in einer View im Quadratischem 100x100 vorkommen, oder noch größer. - Verschiedene Icons wie Default videos oder Default tvshows will man nun in einer Textliste möglichst Quadratisch haben.
Als Fallback in einer Filmliste braucht man es dann plötzlich als Banner, Fanart oder Poster. In der Videoinfo sollte es dann
400x600 sein, für eine View dann 100x150. Kodi Skaliert dabei nicht unbedingt gut. Ein Default Icon in 400x600 passt nicht
nur nicht in eine Liste mit Quadratischen Icons, sondern sieht dann auch noch verkleinert in diversen Dialogen schlecht aus.
Die Konsequenz daraus ist dann das man teilweise ein und dasselbe in 4 oder mehr Größen und Formaten braucht.
Bei mir endete das in den über hundert Default Icons in Quadratischer Auflösung, und Sets für Small, Medium, Big und Bigger,
dazu noch die Default Fallbacks für Fanart-, Banner- und Poster-Abmessungen.
Das war erst mal die Situation die es zu Verbessern galt.
[h1]Die Lösung[/h1]
Nun kam mir die Idee wenn man nur einfarbige Icons verwenden will, warum sollten diese überhaupt als Größenabhängige Grafiken vorliegen?
Einfacher wäre es direkt in einer Schrift, mit verschiedenen Größen über die Font.xml Datei.
- Ein Icon in der Schrift geändert und schon passen alle Codestellen von selbst (bis auf die Ausrichten natürlich).
- Man kann aus einem Icon wie "Serien" dann Default TVShows in allen Größen und Proportionen
Nachbilden und genauso beliebig über Textcolor einfärben.
Als Nebeneffekt hat man sogar noch Selectedcolor usw. für Einfärbungen.
Die nächsten Vorteile wurden auch schnell klar
- die Größe
mit einem nicht einmal 100KB Font kann man alle Icons Abdecken,
ohne zusätzliches Laden als Texturen! - Mehrere Sets
Schriften kann man durch einfaches kopieren eines Font Sets aus der Font.xml
suchen und ersetzen und so sogar mehrere Sets erstellen. Durch "Schrift auswählen"
in den Einstellungen lassen sich so alle Icons inkl. der Default Icons wechseln.
[h2]Also gesagt getan[/h2]
Ohne zu sehr ins Details zu gehen war mein Workflow:
- Icons die ich sowieso schon hatte, plus neue in Photoshop als Vektormasken angelegt
- Kombinierte Pfade ausgegeben und über ein Hilfsprogramm SVG Dateien erstellt
- SVG Dateien in einen Fonteditor importiert um daraus einen Vektorbasierte Icon Truetype Font zu erstellen
Dafür habe ich die Freeware Fontforge benutzt. Die Freeware kämpft zwar mit Bugs, bietet sonst aber für diese Art
(Zeichnen darin ist die Hölle), genau das was man braucht:
- Import von SVG
- Größe Anpassen
- Export zu Truetype
Im Laufe der Zeit wurden daraus 3 vollständige Icon Sets. Sie enthalten neben 270 Glyphen die aufeinander Abgestimmt
sind und sich Unterschieden in den Sets (bis auf solche in denen mir absolut nichts zu einfiel oder eben aus Gründen
der Wiedererkennung in einem Menü zwingend so sein müssen). Dazu noch alles was irgendwie in Form von Text machbar
war wie ein Runder Kreis in 100 Schritte für Progress Bars, Laut/Leise in 7 Stufen, bis hin zur Ratingsternen 1-10,
Abweichendes Benutzerrating 1-10 oder Watchedoverlays. Wirklich alles was möglich war wurde in die 3 Fonts gepackt!
[h2]Das Negative[/h2]
Im Laufe der Umsetzung kristallisierten sich auch Nachteile heraus, mit denen man je nach Skin aber denke ich leben kann:
- Wie bei jedem Text sind zoom Animationen Unscharf und sollten sparsam eingesetzt werden.
8% am TV fallen mit gewisser Distanz kaum auf. - zweierlei Farben sind nicht Möglich - Fonts sind wie Bitmaps ja/nein Objekte. Abstufungen wie Verläufe,
weiche Kanten, Transparenzen in einigen Bereichen oder zwei Farben gehen nicht. - Ein Drehen per Animation (wie im Kreis) ist unmöglich
- erzeugt bei mir auf diversen Rechnern eine Art "Rahmen" um den Text. - Images wie Poster und dergleichen erhalten ein Fallbackicon das dahinterliegen muss.
Eine Fläche und darauf ein label mit Text - aspect keep ist dadurch keine Option weil es nicht
direkt in der Textur als fallback angesprochen werden kann.
[h2]Das Positive[/h2]
- Geringe bis gar keine Grafiklast vom Skin, bis auf Hintergründe,
einige Rahmen und Artworks bleibt fast nichts mehr (je nach Design) - Verschiedene Sets durch minimale Codeänderungen (erweitern der Font.xml)
- Einfaches wechseln der Icons durch Nutzer ohne Strings oder Bools durch Schriftauswahl
- Stufenlose Verwendbarkeit eines Icons in nahezu jeder Größe - von 30 Pixel bis 2000 Pixeln, immer gleich
- Keine Verschlechterung (zumindest nicht so extrem) bei starkem Verkleinern von
sehr großen Detaillierten Grafiken - Durch das „Auslagern“ der Fallbacks in Views als „Text auf Grafik“ ergab sich der Nebeneffeckt das
man so schnell scrollen kann wie man will, es ist immer etwas da!.
Viele werden das kennen – in einer View wie Walls springt man von A zu W bei 1000 Filmen oder mehr.
Es kommt erst mal nichts und irgendwann ist Kodi dann soweit und Baut den Inhalt auf.
Solange man fallbacks direkt in einer Artworktexture hat, ist das Programm bedingt nicht anders
möglich. Erst wenn Kodi das Artwork geladen hat, wird geprüft ob es vorhanden ist, oder
eine Ersatzgrafik geladen werden muss. Das führt dann zu einem „Stockendem“ Aufbau.
[h1]Die Umsetzung[/h1]
Im Skincode passiert dann nichts Weltbewegendes mehr.
Man erstellt sich ein label, und verwendet nun die passenden Buchstaben zum gewollten Icon, oder Arbeitet mit VAR´s.
<control type="label">
<description>Fallback icon</description>
<width>630</width>
<height>80</height>
<align>center</align>
<font>Iconbannerdefault</font>
<textcolor>$VAR[CirclesCol]</textcolor>
<label>B</label>
</control>
Bei Buttons habe ich es persönlich bevorzugt mit "leeren" Buttons zu Arbeiten und die Icons
separat darübergelegt mit denselben Visibles.
mit einem <visible>Control.IsEnabled(18)</visible> bei einem Button mit ID18 und
einem <visible>Control.IsVisible(18)</visible> im Iconlabel klappt das super.
[h2]Defaulticons[/h2]
Die Defaulticons brauchten einen Trick. Die Icons mussten damit sie von Kodi verwendet werden
auch als PNG Dateien im Skin vorhanden sein. Also hab ich einfach 1x1 Pixel große Fake PNG´s ins
Verzeichnis gelegt.
Im ganzen Skin wird kein ListItem.Icon verwendet (oder Angezeigt).
Stattdessen wird mit ListItem.Art(thumb) gearbeitet, das dasselbe ist wie Icon nur ohne das
Defaulticon als Fallback.
An Stellen in denen es so nicht ging (oder ich nicht sicher war weil man eben das Icon gewohnt war),
wurde mit visibles und String.StartsWith(ListItem.Icon,Default) das ListItem.Icon immer ausgeblendet
wenn es sich um ein DefaultIcon handelte.
Im Code wurde dann eine "Monstervariable" verwendet die alle DefaultIcons enthält.
Diese werden dann einfach auf die Buchstabenentsprechung "Umgelegt". So ist dann DefaultGenre einfach ein P.
Hier ein Auszug:
<variable name="DefaultIcons">
<value condition="String.IsEqual(ListItem.Icon,DefaultDirector.png)">J</value>
<value condition="String.IsEqual(ListItem.Icon,DefaultSets.png)">K</value>
<value condition="String.IsEqual(ListItem.Icon,DefaultStudios.png)">L</value>
<value condition="String.IsEqual(ListItem.Icon,DefaultYear.png)">M</value>
<value condition="String.IsEqual(ListItem.Icon,DefaultCountry.png)">N</value>
<value condition="String.IsEqual(ListItem.Icon,DefaultTags.png)">O</value>
<value condition="String.IsEqual(ListItem.Icon,DefaultGenre.png)">P</value>
<value condition="String.IsEqual(ListItem.Icon,DefaultActor.png)">U</value>
<value condition="String.IsEqual(ListItem.Icon,DefaultVideo.png)">W</value>
<value condition="String.IsEqual(ListItem.Icon,DefaultVideoCover.png)">W</value>
<value condition="String.IsEqual(ListItem.Icon,DefaultVideoDeleted.png)">W</value>
<value>Ī</value><!-- Dateien -->
</variable>
Alles anzeigen
[h2]Schwierigkeiten[/h2]
Anfangs ist das etwas ungewohnt, es entstehen dabei schon mehr Schriftdefinitionen in der Font.xml als gewohnt.
Wirklich jede Größe die gebraucht wird muss ja definiert werden. Da kommen schnell einige Dutzend zusammen
und den Überblick darf man dabei nicht verlieren. Das Positive daran ist aber das Nachher so ziemlich alle Icons
relativ identisch sind. Will ich nun alle Menüicons ohne das eine "Positionskorrektur" erforderlich ist minimal
größer oder kleiner, muss man nur die Punktgröße in der Font.xml Ändern.
Das wars eigentlich als grober Umriss. Einiges ist noch nicht Perfekt.
Probleme macht noch das nicht alle Icons 100% gleich groß sind. Mann ertappt sich da leicht das Icon an die
Verwendung anzupassen statt nochmal eine Schriftgröße einzuführen. Das ist ein Problem das ich aber leider
erst zu spät erkannt hab, da waren es schon 3 Sets mit verschiedenen Schriften, sodass ich davon jetzt nicht
mehr weg kann/will.
[h2]Was ist damit gemeint[/h2]
Glyphen werden ja in der Regel relativ klein angelegt. Da es Vektoren sind, also Anfangs und Endpunkt einer
Koordinate verbunden mit Linien, kann die Größe danach variabel sein ohne Qualitätsverlust. Das hat aber
nun zur Folge, das selbst Optisch 2 Pixel Differenz bei einem 36x36 großen Raster, Nachher in der Verwendung
von teilweise 80 Pixeln oder größer, irgendwann ins Gewicht fallen. Was so klein noch gar nicht auffällt sind
dann später merkliche Unterschiede. Innerhalb der Verwendeten Gruppe sind aber alle nahezu gleich.
Also z.B. Serien und Filmicons passen alle zueinander, ein Watched Overlay Icon, ein OK oder ein Ratingstern
passt aber proportional nicht dazu! Die sind dann entweder größer oder kleiner. Ein richtiges Problem ist es
aber nicht, die Verwendung ist ja eher gegeben (keiner nimmt ja ein Serienicon dann fürs OK).
[h1]Schlussendlich[/h1]
Die Fonts laufen alle unter einer OFL Lizenz, sind selbst erstellt oder lehnen sich an Icons anderer Skins an
wie dem Estuary v1 in denen auch alles Open Source ist.
Falls Interesse besteht kann ich sie hochladen wenn ich fertig bin.
Es sei aber Ausdrücklich nochmal erwähnt das man hierfür schon geübt sein muss und sich das nicht schnell mal so, ohne Kenntnisse Einbauen lässt.
Ein Skin hat ja schließlich hunderte Fenster und dafür braucht es schon ein durchdachtes Konzept und einen kompletten Neuaufbau.
Im Anhang einige Beispiele der Icons aus den 3 Sets.
Grüße