Source file: /~heha/Mikrocontroller/Displays/utft/Kalender.zip/ILI9341/stellen.cpp

#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-80