#include <avr/io.h>
#include <util/delay.h>
#include "UTFT.h"
#include "TouchScreen.h"
#include "calib.h"
#include "stellen.h"
/********************************
* _date-Objektfunktionen *
********************************/
/*
bool _date::ereignis(const char*p) const{
// monatsweise vorrücken
for (byte i=month;i>1;i--) p+=strlen_P(p)+1;
// Tag suchen
return strchr_P(p,day)!=0;
}
*/
char _date::dow() const{
char m=month, y=year;
if (m<3) m+=10, y--;
else m-=2;
return ((26*m-2)/10+day+y+(y>>2)+(jh>>2)-2*jh+14)%7;
}
char _date::maxday() const{
if (month==2) return year&3?28:29; // ohne Jahrhundertregel
return ((month>>3)^month)&1?31:30; // ungerade Monate 31 Tage, ab August (8!) gerade Monate
}
void _date::morgen() {
if (++day>maxday()) {
day=1; nextmonth();
}
}
void _date::gestern() {
if (!--day) {
prevmonth();
day=maxday();
}
}
void _date::nextmonth() {
if (++month>12) {
month=1; ++year;
}
}
void _date::prevmonth() {
if (!--month) {
--year;
month=12;
}
}
bool _date::heute() const{
return day==jetzt.d.day && month==jetzt.d.month && year==jetzt.d.year && jh==jetzt.d.jh;
}
// Makros um die Kompilierzeit als Startzeit einzusetzen
// (d.h. automatisches Stellen der Uhr beim „Betanken“)
#define YEAR ( __DATE__[9]*10+__DATE__[10]-528)
#define MONTH ( __DATE__[0]=='J'&&__DATE__[1]=='a'?1:\
__DATE__[0]=='F'?2:\
__DATE__[0]=='M'&&__DATE__[2]=='r'?3:\
__DATE__[0]=='A'&&__DATE__[1]=='p'?4:\
__DATE__[0]=='M'?5:\
__DATE__[0]=='J'&&__DATE__[2]=='n'?6:\
__DATE__[0]=='J'?7:\
__DATE__[0]=='A'?8:\
__DATE__[0]=='S'?9:\
__DATE__[0]=='O'?10:\
__DATE__[0]=='N'?11:\
__DATE__[0]=='D'?12:0)
#define DAY ((__DATE__[4]>='0'?__DATE__[4]:'0')*10+__DATE__[5]-528)
#define HOUR ( __TIME__[0]*10+__TIME__[1]-528)
#define MIN ( __TIME__[3]*10+__TIME__[4]-528)
#define SEC ( __TIME__[6]*10+__TIME__[7]-528)
_jetzt jetzt={{SEC,MIN,HOUR},{DAY,MONTH,YEAR,20}};
/****************************************
* Uhrzeit-Eingabe per Touchscreen *
****************************************/
extern TouchScreen ts;
void Rahmen(int top=19, int bot=2);
extern UTFT dc;
extern const byte ArialBP24[] PROGMEM;
void gotoXdY(int x, int dy);
#define COLOR_BACK RGB(200,200,200)
int nbuttons;
static struct _rect{
int l,t,r,b; // anklickbare Knöpfe
}buttons[14];
static _jetzt Stellen; // Zu stellende Uhrzeit
void Button(int x, int y, const char*s, int cx=-1,
word tlcolor=RGB(240,240,240), word brcolor=RGB(128,128,128)) {
if (cx<0) cx=dc.getTextExtent(s);
int x1=x-(cx>>1)-10;
int x2=x1+cx+20;
int y1=y-2;
int y2=y1+4+19+4;
dc.setColor(COLOR_SILVER);
dc.fillRect(x1,y1,x2,y2);
dc.setColor(tlcolor);
dc.fillRect(x1-2,y1-2,x1,y2+2); // Schattenrand: links
dc.fillRect(x1,y1-2,x2+2,y1); // oben
dc.setColor(brcolor);
dc.fillRect(x2,y1,x2+2,y2+2); // rechts
dc.fillRect(x1,y2,x2,y2+2); // unten
dc.drawPixel(x1-1,y2+1); // links unten
dc.drawPixel(x2+1,y1-1); // rechts oben
dc.gotoXY(x,y);
dc.setColor(COLOR_BLACK);
dc.setBackColor(COLOR_SILVER);
dc.print(s);
if (tlcolor!=brcolor) {
_rect&r=buttons[nbuttons++];
r.l=x1-2;
r.t=y1-2;
r.r=x2+2;
r.b=y2+2;
}
}
void UpDown(int n) {
static char s[6];
int y=dc.whereY();
sprintf_P(s,PSTR("%d"),n);
Button(140,y,s,80,COLOR_BLUE,COLOR_BLUE);
Button(60,y,"–"); // Mathematisches Minus!
Button(220,y,"+");
}
// Zeichnet alles oder nur das Clipping-Rechteck
void SetTime_Redraw(byte was=0xFF) {
if (was&0x80) {
Rahmen(); // Alles löschen
dc.print(F("Datum/Uhrzeit stellen"),120,0);
dc.setColor(COLOR_BACK);
dc.fillRectW(2,19,236,299);
dc.setColor(COLOR_BLACK);
dc.setBackColor(COLOR_BACK);
dc.align=0;
dc.print(F("Jahr"),1,34);
dc.print(F("Mon."),1,72);
dc.print(F("Tag"), 1,110);
dc.print(F("Std."),1,148);
dc.print(F("Min."),1,186);
dc.print(F("Sek."),1,224);
}
dc.setFont(ArialBP24);
dc.align=2;
dc.gotoXY(120,30); // oben anfangen
nbuttons=0;
if (was&0x01) UpDown(Stellen.d.jh*100+Stellen.d.year); gotoXdY(120,38);
if (was&0x02) UpDown(Stellen.d.month); gotoXdY(120,38);
if (was&0x04) UpDown(Stellen.d.day); gotoXdY(120,38);
if (was&0x08) UpDown(Stellen.t.hour); gotoXdY(120,38);
if (was&0x10) UpDown(Stellen.t.min); gotoXdY(120,38);
if (was&0x20) UpDown(Stellen.t.sec); gotoXdY(120,38);
if (was&0x80) {
Button(40,260,"OK");
Button(160,260,"Abbrechen");
}
}
// Wartet auf Touch-Ereignis, maximal 60 Sekunden
// Liefert false bei Abbruch durch Zeitüberschreitung
static bool Warte() {
dc.clrOrg();
dc.clrClip();
if (!waitTouch(600)) return false;
dc.setColor(COLOR_YELLOW);
int l=239,t=319,r=0,b=0;
while (ts.isTouching()) {
calib.getPoint();
dc.setColor(255,240,0);
dc.fillCircle(touch.x,touch.y,20);
dc.setColor(COLOR_BLUE);
dc.drawCircle(touch.x,touch.y,20);
dc.drawCircle(touch.x,touch.y,21);
dc.drawCircle(touch.x,touch.y,22);
if (l>touch.x-22) l=touch.x-22;
if (t>touch.y-22) t=touch.y-22;
if (r<touch.x+22) r=touch.x+22;
if (b<touch.y+22) b=touch.y+22;
_delay_ms(200); // zeige Berührpunkt zur Kontrolle
}
dc.setClip(l,t,r,b);
SetTime_Redraw(); // Nur den vermatschten Bereich neu zeichnen
dc.clrClip();
return true;
}
int HitTest() {
for (int i=0; i<nbuttons; i++) {
_rect&r=buttons[i];
if (r.l<=touch.x && touch.x<r.r
&& r.t<=touch.y && touch.y<r.b) return i; // gefunden
}
return -1; // daneben!
}
bool SetTime() {
Stellen=jetzt;
dc.clrClip();
SetTime_Redraw();
for(;;) {
if (!Warte()) return false; // Nach 1 Minute Inaktivität zurück (ohne Uhr stellen)
int ht;
switch (ht=HitTest()) {
case 0: Stellen.d.year--; if (Stellen.d.year<0) Stellen.d.year=99, Stellen.d.jh--; break;
case 1: Stellen.d.year++; if (Stellen.d.year>99) Stellen.d.year=0, Stellen.d.jh++; break;
case 2: Stellen.d.month--; if (Stellen.d.month<1) Stellen.d.month=12; break;
case 3: Stellen.d.month++; if (Stellen.d.month>12) Stellen.d.month=1; break;
case 4: Stellen.d.day--; if (Stellen.d.day<1) Stellen.d.day=Stellen.d.maxday(); break;
case 5: Stellen.d.day++; if (Stellen.d.day>Stellen.d.maxday()) Stellen.d.day=1; break;
case 6: Stellen.t.hour--; if (Stellen.t.hour<0) Stellen.t.hour=23; break;
case 7: Stellen.t.hour++; if (Stellen.t.hour>23) Stellen.t.hour=0; break;
case 8: Stellen.t.min--; if (Stellen.t.min<0) Stellen.t.min=59; break;
case 9: Stellen.t.min++; if (Stellen.t.min>59) Stellen.t.min=0; break;
case 10: Stellen.t.sec--; if (Stellen.t.sec<0) Stellen.t.sec=59; break;
case 11: Stellen.t.sec++; if (Stellen.t.sec>59) Stellen.t.sec=0; break;
case 12: jetzt=Stellen; return true; // Daten übernehmen und Uhr starten
case 13: return false; // Daten verwerfen
default: continue;
}
SetTime_Redraw(1<<(ht>>1)); // Nur eine Knopfzeile neu malen
}
}
Detected encoding: UTF-8 | 0
|