Dies ist eine alte Version des Dokuments!


Icons

Icons stellen eine besondere Art von Bild dar. Diese bestehen zwar auch aus einzelnen Bildpunkten (Pixel), sind meist jedoch kleiner und einfacher gehalten als übliche Bilder. Icons werden oft auch als Symbol oder Piktogramm bezeichnet. Der Aussagegehalt soll dabei auf das Wesentliche reduziert werden.

Dadurch, dass Symbole offensichtlich relativ wenig Ressourcen brauchen, sind sie besonders interessant für sich wiederholende Aufgaben (Schaltflächen, Statusanzeigen, etc.) in einer Mensch-Maschine-Schnittstelle in Form einer grafischen Benutzeroberfläche.

Aufgabe

Die verwendeten Bibliotheken enthalten eine Reihe von Icons. Diese Icons sind zum Beispiel in Form einer Liste auf dem Display darzustellen.

Vorbereitung

Falls Sie nicht in der Vorgehensmodell-Ebene sind, navigieren Sie diese bitte an (nach oben). Falls das Projekt nicht mehr geöffnet ist, öffnen sie das SiSy UML-Projekt wieder. Legen Sie ein neues Klassendiagramm an und wählen Sie die Sprache ARM C++. Beachten Sie die Einstellungen für die Zielplattform STM32F4-Discovery. Beim Öffnen des Diagramms (rechte Maustaste, nach unten) laden Sie die Diagrammvorlage für eine ARM C++ Applikation mit Grafikdisplay ohne µGL.

(Mit installiertem Flash kann man an dieser Stelle ein Video in dieser Web-Seite ansehen.)

Selektieren Sie die Operation onStart der Klasse Application.

Ersetzen Sie möglicherweise vorhandenen Beispielquelltext durch folgenden Code:

onStart()
display.clearScreen();

Erstellen und übertragen Sie die Anwendung auf den Mikrocontroller.

Grundlagen zu Icons

Icons werden in der µGL mit einer verringerten Farbtiefe abgebildet. Dabei wird auf eine Farbpalette zurückgegriffen. Diese kann bei Bedarf auch anwendungsspezifische Farbcodes enthalten. Jede Farbe in der Palette wird als RGB-Wert codiert.

// RGB-Makro, Farbanteil 0-255
// RGB(rot,grün,blau)
 
color_t red,green,blue,gray,black,white,
 
red   = RGB( 255,   0,   0 );
green = RGB(   0, 255,   0 );
blue  = RGB(   0,   0, 255 );
gray  = RGB( 128, 128, 128 );
black = RGB(   0,   0,   0 );
white = RGB( 255, 255, 255 );

Die Farbpalette selbst ist ein Array von 16 Farbwerten. Dabei sind den ersten vier Farbwerten besondere Bedeutungen zugewiesen. Diese werden in der Funktion drawIcon entsprechend dem Farbschema, der Darstellungsoptionen und der Displaymöglichkeiten berücksichtigt.

// Farbpalette für Icons, 4Bit Codiert, 16 Farbwerte
color_t paletteIcon[] = {	// Farb-Index
	ColorBackground,	// 0
	ColorForeground,	// 1
	ColorTransparent,	// 2
	ColorHalfTransparent,	// 3
	RGB(255,255,255),	// 4
	RGB(0,0,0),		// 5
	RGB(255,0,0),		// 6
	RGB(0,255,0),		// 7
	RGB(255,255,0),		// 8
	RGB(0,0,255),		// 9
	RGB(170,123,0),		// 10
	RGB(195,195,195),	// 11
	RGB(255,201,14),	// 12
	RGB(237,151,35),	// 13
	RGB(221,36,236),	// 14
	RGB(87,87,87)		// 15
	};	

Die oben aufgezeigte Standardpalette enthält die folgend dargestellten Farben:

Für 16 Farben reichen vier Bit zur Codierung aus. Damit lassen sich in einem Byte zwei Bildpunkte abbilden. Um dem Entwickler diese Codierungsaufgabe etwas zu erleichtern, bietet die Bibliothek das Makro Pixel4 an. Das Makro verfügt über zwei Parameter. Diese repräsentieren den Farbindex (0-16) der obigen Farbpalette. Die eigentlichen Bildpunkte der Icons werden dann über diese Makros im Code abgebildet.

// 2x4Bit Farbwerte, erst low, dann high
#define Pixel4(c1,c2) (c1+(c2<<4))

Die Displayfunktion drawIcon erwartet als Parameter das Icon in Form einer Struktur mit einem sogenannten Header. Darin werden wesentliche Eigenschaften des darzustellenden Icons abgebildet. Übrigens haben Bilder (Bitmaps) letztlich den selben Header. Das Strukturelement Typ enthält in diesem Fall ein 'b'.

struct IconHeader{
	unsigned char type;		// uint8_t='i'
	unsigned char width;		// uint8_t
	unsigned char height;		// uint8_t
	unsigned char dataStart;	// uint8_t
	};

Die in der Bibliothek vorgefertigten Icons werden wiederum als Liste und mit einem Namen angeboten.

// IconNamen
#define iconAbort_12	((IconHeader*)_iconAbort_12)
#define iconBack_12	((IconHeader*)_iconBack_12)
#define iconBatt0_12	((IconHeader*)_iconBatt0_12)
#define iconBatt100_12	((IconHeader*)_iconBatt100_12)
...
// IconListen-Struktur
struct IconIndex {
	unsigned char id;
	IconHeader* pIcon;
};	
 
//IconListe für 12x12Pixel Icons
IconIndex icons12[] ={
	{'x',iconAbort_12},
	{'b',iconBack_12},
	{'b',iconBatt0_12},
	{'9',iconBatt100_12},
	{'7',iconBatt33_12},
	{'8',iconBatt66_12},
	{'B',iconBright_12},
	{'C',iconCalculator_12},
	...

Somit lassen sich Icons als Element einer Icon-Liste, aber auch über ihren Namen ansprechen.

  • IconIndex icons12[]:
    1. iconAbort_12
    2. iconBack_12
    3. iconBatt0_12
    4. iconBatt100_12
    5. iconBatt33_12
    6. iconBatt66_12
    7. iconBright_12
    8. iconCalculator_12

Ein konkretes Icon sieht im Code dann wie folgt aus:

uint8_t _iconAbort_12[] ={
	'i', 12, 12,
	Pixel4(2,1),Pixel4(1,2),Pixel4(2,2),Pixel4(2,2),Pixel4(2,1),Pixel4(1,2),
	Pixel4(1,1),Pixel4(1,1),Pixel4(2,2),Pixel4(2,2),Pixel4(1,1),Pixel4(1,1),
	Pixel4(1,1),Pixel4(1,1),Pixel4(1,2),Pixel4(2,1),Pixel4(1,1),Pixel4(1,1),
	Pixel4(2,1),Pixel4(1,1),Pixel4(1,1),Pixel4(1,1),Pixel4(1,1),Pixel4(1,2),
	Pixel4(2,2),Pixel4(1,1),Pixel4(1,1),Pixel4(1,1),Pixel4(1,1),Pixel4(2,2),
	Pixel4(2,2),Pixel4(2,1),Pixel4(1,1),Pixel4(1,1),Pixel4(1,2),Pixel4(2,2),
	Pixel4(2,2),Pixel4(2,1),Pixel4(1,1),Pixel4(1,1),Pixel4(1,2),Pixel4(2,2),
	Pixel4(2,2),Pixel4(1,1),Pixel4(1,1),Pixel4(1,1),Pixel4(1,1),Pixel4(2,2),
	Pixel4(2,1),Pixel4(1,1),Pixel4(1,1),Pixel4(1,1),Pixel4(1,1),Pixel4(1,2),
	Pixel4(1,1),Pixel4(1,1),Pixel4(1,2),Pixel4(2,1),Pixel4(1,1),Pixel4(1,1),
	Pixel4(1,1),Pixel4(1,1),Pixel4(2,2),Pixel4(2,2),Pixel4(1,1),Pixel4(1,1),
	Pixel4(2,1),Pixel4(1,2),Pixel4(2,2),Pixel4(2,2),Pixel4(2,1),Pixel4(1,2)
};

Bei diesem Icon handelt es sich um das Symbol _iconAbort_12.

Für die Entwicklung von eigenen Icons steht Ihnen ein spezielles Werkzeug zur Verfügung. Mit dem Icon-Designer und Bitmap-Konverter können Sie sich den benötigten C++ Code für Icons und Bitmaps aus den Bildern generieren lassen.

Entwurf der Icon-Anwendung

Nach den Vorbereitungen liegt uns eine einfache Grafikanwendung vor. In der Operation onStart wird bis jetzt lediglich der Displayinhalt gelöscht. Die Icon-Anwendung soll in zwei Schritten realisiert werden.

  1. Itteration
    • das Icon mit dem Index 0 aus der Liste darstellen
    • das Icon mit dem Namen iconAbort_12 darstellen
    • das Icon mit dem Index 5 aus der Liste darstellen
    • das Icon mit dem Namen iconBatt66_12 darstellen
  2. Itteration
    • warte etwas
    • lösche das Display
    • stelle alle 12×12 Icons dar
    • warte etwas
    • stelle alle 20×20 Icons dar

Realisierung der Icon-Anwendung 1. Itteration

Um mit vorgefertigten Icons arbeiten zu können muss das entsprechende Paket in die Anwendung eingefügt werden. Das geschieht, indem Sie das Paket UglIcons zum Beispiel aus dem Navigator (Navigator, rechte Maustaste, UML-Pakete) in das Klassendiagramm der Anwendung ziehen.

In der ersten Itteration soll ganz einfach auf Icons aus dem Fundus 12 x 12 und 20 x 20 per Name und per Index zugegriffen werden.

onStart:
display.clearScreen();
 
display.drawIcon( 10, 10, icons12[0].pIcon );
display.drawIcon( 10, 30, iconAbort_20     );
display.drawIcon( 10, 60, iconBatt66_12 );
display.drawIcon( 10, 70, icons20[5].pIcon    );

Erstellen und übertragen sie die Anwendung auf den Controller. Vergleichen sie die Darstellung auf dem Display mit dem Programmcode.

Realisierung der Icon-Anwendung 2. Itteration

Bei der zweiten Itteration gehen wir je Icon-Liste (12×12 und 20×20) die Icons in einer Schleife durch und stellen diese an einer neuen Position dar. Wir wollen dabei dem Auge etwas Zeit geben jedes Icon einzeln wahrzunehmen.

onStart:
display.clearScreen();
// das Icon "Abbruch" 12x12 und 20x20
display.drawIcon( 10, 10, icons12[0].pIcon );
display.drawIcon( 10, 30, iconAbort_12     );
// das Icon "Batterie 60%" 12x12 und 20x20
display.drawIcon( 10, 50, icons12[5].pIcon );
display.drawIcon( 10, 70, iconBatt66_12    );
 
// etwas warten, nächstes Bild vorbereiten
waitMs(2000);
display.clearScreen();
 
// die komplette 12x12 IconListe
int i=0,x=5,y=5;
// solange index i auf ein gültiges 12x12 Icon zeigt
while( icons12[i].pIcon )
{
	// Icon mit Index i darstellen
	display.drawIcon( x, y, icons12[i].pIcon );
	// next Icon, next Position
	i++;
	x += icons12[i].pIcon->width+5;
	if(x > 240-5-20 )
	{
		x = 5;
		y += icons12[i].pIcon->height+5;
	}
	// etwas fürs Auge warten
	waitMs(200);
}
// etwas Abstand, neue Startposition, Index auf Listenanfang stellen
y += 50;
i=0,x=5;
// solange index i auf ein gültiges 20x20 Icon zeigt
while( icons20[i].pIcon )
{
	// Icon mit Index i darstellen
	display.drawIcon( x, y, icons20[i].pIcon );
	// next Icon, next Position
	i++;
	x += icons20[i].pIcon->width+5;
	if(x > 240-5-20 )
	{
		x = 5;
		y += icons20[i].pIcon->height+5;
	}
	// etwas fürs Auge warten
	waitMs(200);
}

Erstellen und übertragen sie die Anwendung auf den Controller. Vergleichen sie die Darstellung auf dem Display mit dem Programmcode.

Videozusammenfassung

Als Zusammenfassung dieses kurzen Abschnittes das Ganze nochmal als Video.

(Mit installiertem Flash kann man an dieser Stelle ein Video in dieser Web-Seite ansehen.)

Übung

Als Übung stellen Sie bitte ein eigenes (benutzerdefiniertes) Icon dar. Der Code für das Icon kann mit dem Icon-Desinger und Bitmap-Konverter erstellt werden. Im folgenden das Ergebnis der Codegenerierung.

// generierter Code aus dem IconDesiner
uint8_t _iconTest[] ={ 
	'i', 20, 20,
	Pixel4(4,4),Pixel4(4,4),Pixel4(4,4),Pixel4(4,6),Pixel4(6,6),Pixel4(6,6),
	Pixel4(6,4),Pixel4(4,4),Pixel4(4,4),Pixel4(4,4),Pixel4(4,4),Pixel4(4,4),
	Pixel4(4,6),Pixel4(6,8),Pixel4(8,8),Pixel4(8,8),Pixel4(8,6),Pixel4(6,4),
	Pixel4(4,4),Pixel4(4,4),Pixel4(4,4),Pixel4(4,4),Pixel4(6,8),Pixel4(8,8),
	Pixel4(8,8),Pixel4(8,8),Pixel4(8,8),Pixel4(8,6),Pixel4(4,4),Pixel4(4,4),
	Pixel4(4,4),Pixel4(4,6),Pixel4(8,8),Pixel4(8,8),Pixel4(8,8),Pixel4(8,8),
	Pixel4(8,8),Pixel4(8,8),Pixel4(6,4),Pixel4(4,4),Pixel4(4,4),Pixel4(6,8),
	Pixel4(8,8),Pixel4(8,8),Pixel4(8,8),Pixel4(8,8),Pixel4(5,8),Pixel4(8,8),
	Pixel4(8,6),Pixel4(4,4),Pixel4(4,6),Pixel4(8,8),Pixel4(8,8),Pixel4(5,5),
	Pixel4(5,8),Pixel4(8,8),Pixel4(8,5),Pixel4(8,8),Pixel4(8,8),Pixel4(6,4),
	Pixel4(4,6),Pixel4(8,8),Pixel4(8,5),Pixel4(4,4),Pixel4(4,5),Pixel4(8,8),
	Pixel4(8,5),Pixel4(8,8),Pixel4(8,8),Pixel4(6,4),Pixel4(6,8),Pixel4(8,8),
	Pixel4(8,5),Pixel4(4,5),Pixel4(5,5),Pixel4(8,8),Pixel4(8,8),Pixel4(5,8),
	Pixel4(8,8),Pixel4(8,6),Pixel4(6,8),Pixel4(8,8),Pixel4(8,5),Pixel4(4,5),
	Pixel4(5,5),Pixel4(8,8),Pixel4(8,8),Pixel4(5,8),Pixel4(8,8),Pixel4(8,6),
	Pixel4(6,8),Pixel4(8,8),Pixel4(8,8),Pixel4(5,5),Pixel4(5,8),Pixel4(8,8),
	Pixel4(8,8),Pixel4(8,5),Pixel4(8,8),Pixel4(8,6),Pixel4(6,8),Pixel4(8,8),
	Pixel4(8,8),Pixel4(8,8),Pixel4(8,8),Pixel4(8,8),Pixel4(8,8),Pixel4(8,5),
	Pixel4(8,8),Pixel4(8,6),Pixel4(6,8),Pixel4(8,8),Pixel4(8,8),Pixel4(5,5),
	Pixel4(5,8),Pixel4(8,8),Pixel4(8,8),Pixel4(8,5),Pixel4(8,8),Pixel4(8,6),
	Pixel4(6,8),Pixel4(8,8),Pixel4(8,5),Pixel4(4,5),Pixel4(5,5),Pixel4(8,8),
	Pixel4(8,8),Pixel4(5,8),Pixel4(8,8),Pixel4(8,6),Pixel4(4,6),Pixel4(8,8),
	Pixel4(8,5),Pixel4(4,5),Pixel4(5,5),Pixel4(8,8),Pixel4(8,8),Pixel4(5,8),
	Pixel4(8,8),Pixel4(6,4),Pixel4(4,6),Pixel4(8,8),Pixel4(8,5),Pixel4(4,4),
	Pixel4(4,5),Pixel4(8,8),Pixel4(8,5),Pixel4(8,8),Pixel4(8,8),Pixel4(6,4),
	Pixel4(4,4),Pixel4(6,8),Pixel4(8,8),Pixel4(5,5),Pixel4(5,8),Pixel4(8,8),
	Pixel4(8,5),Pixel4(8,8),Pixel4(8,6),Pixel4(4,4),Pixel4(4,4),Pixel4(4,6),
	Pixel4(8,8),Pixel4(8,8),Pixel4(8,8),Pixel4(8,8),Pixel4(5,8),Pixel4(8,8),
	Pixel4(6,4),Pixel4(4,4),Pixel4(4,4),Pixel4(4,4),Pixel4(6,8),Pixel4(8,8),
	Pixel4(8,8),Pixel4(8,8),Pixel4(8,8),Pixel4(8,6),Pixel4(4,4),Pixel4(4,4),
	Pixel4(4,4),Pixel4(4,4),Pixel4(4,6),Pixel4(6,8),Pixel4(8,8),Pixel4(8,8),
	Pixel4(8,6),Pixel4(6,4),Pixel4(4,4),Pixel4(4,4),Pixel4(4,4),Pixel4(4,4),
	Pixel4(4,4),Pixel4(4,6),Pixel4(6,6),Pixel4(6,6),Pixel4(6,4),Pixel4(4,4),
	Pixel4(4,4),Pixel4(4,4) 
	};
// Namens- und Typzuweisung		
#define iconTest (IconHeader*) _iconTest

Entwickeln Sie die vollständige Anwendung. Erstellen und Übertragen Sie den Code der Anwendung auf den Mikrocontroller. Das Ergebnis sollte wie folgt aussehen:

Nächstes Thema

icons.1389955857.txt.gz · Zuletzt geändert: 2014/01/17 11:50 von esche