unit framegrafico; {$mode ObjFPC}{$H+} interface uses Classes, SysUtils, Forms, Controls, ExtCtrls, Astronomy, DateUtils, Graphics, StdCtrls, LResources; procedure calcolapianeti; function FormattaOraDaMinutiGiorno(minutigiorno:integer):string; type { TPianetiGraph } TPianetiGraph = class(TFrame) Label1: TLabel; PaintBox1: TPaintBox; procedure FrameMouseLeave(Sender: TObject); procedure ImpostaTempoClick(Sender: TObject; Tempo:TDateTime; lat, long:double); procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure PaintBox1Paint(Sender: TObject); private public var colorform:TColor; end; type TNomePianeta= (Sole, Luna, Mercurio, Venere, Marte, Giove, Saturno, Urano, Nettuno); TPianeta= record colore:Tcolor; sorge:integer; //minuti da inizio giornata tramonta:integer; //minuti da inizio giornata distanza:double; //distanza in unità astronomiche testo:string; isinsky: boolean; // variabile che dice se l'oggetto è nel cielo nel caso sia l'alba che il tramonto non siano ottenibili illumData:astro_illum_t; case nome: TNomePianeta of //questo record genera i campi per il crepuscolo civile solo se il nome è Sole Sole: (civildawn, civildusk, nauticaldawn, nauticaldusk, astronomicaldawn, astronomicaldusk :integer); Luna, Mercurio, Venere, Marte, Giove, Saturno, Urano, Nettuno: ( ); end; implementation {$R *.lfm} { TPianetiGraph } var //Array dei vari oggetti celesti $00090909 oggetticelesti:array of TPianeta= (( colore: $003AE1FE; sorge: 0; tramonta: 0; distanza: 0; testo: 'Sole'; isinsky: False; illumData:(); nome: Sole; civildawn: 0; civildusk:0; nauticaldawn:0; nauticaldusk:0; astronomicaldawn:0; astronomicaldusk:0 ), ( colore: $00EADBCD; sorge:0; tramonta: 0; distanza: 0; testo: 'Luna'; isinsky: False;illumData:(); nome: Luna;), ( colore: $00A1D11D; sorge:0; tramonta: 0; distanza: 0; testo: 'Mercurio'; isinsky: False;illumData:(); nome: Mercurio;), ( colore: $00D3D200; sorge:0; tramonta: 0; distanza: 0; testo: 'Venere'; isinsky: False;illumData:(); nome: Venere; ), ( colore: $005352EE; sorge: 0; tramonta: 0; distanza: 0; testo: 'Marte'; isinsky: False;illumData:(); nome: Marte;), ( colore: $00628EFF; sorge: 0; tramonta: 0; distanza: 0; testo: 'Giove'; isinsky: False;illumData:(); nome: Giove; ), ( colore: $00439FFF; sorge: 0; tramonta: 0; distanza: 0; testo: 'Saturno'; isinsky: False;illumData:(); nome: Saturno;), ( colore: $00FFA054; sorge: 0; tramonta: 0; distanza: 0; testo: 'Urano'; isinsky: False;illumData:(); nome: Urano;), ( colore: $00CD275F; sorge: 0; tramonta: 0; distanza: 0; testo: 'Nettuno'; isinsky: False;illumData:(); nome: Nettuno;) ); oggetto:string; durataora:double; durataminuto:double; duratamezzora:double; durataorai:integer; //la durata ora per la variabile i orafine:integer; altezzarighe:double; //variabili di posizione latitudine:double; longitudine:double; altitudine:integer=500; tempoinizio:TDateTime;//tempo di inizio della giornata coincide con le 0.0 della giornata corrente oppure quello impostato dall'utente isFirstTime:boolean=True; const xtesto=10; xgrafico=50; // cordinata x di inizio del grafico distrighetop=30; spesspianeti=13; //spessore righe sorgere e tramonto PianetiGraph aggpospianeti=2; //aggiusta la posizione del rettangolo PianetiGraph rispetto al testo ridpaint=60; //indica quanto è più piccolo in pixel il grafico (dal righello in poi) rispetto alla larghezza della paintbox distrighellotop=25; altezzarighello=6; mezzorighello=5; roundrett=5; //arrottondamento angoli rettangoli procedure TPianetiGraph.PaintBox1Paint(Sender: TObject); var i:integer=1; corpo:TPianeta; orafine2:integer; begin if isFirstTime then begin tempoinizio:=EncodeDate(YearOf(Now), MonthOf(Now), DayOf(Now)); calcolapianeti; isFirstTime:=False; end; orafine:=PaintBox1.Width-ridpaint+xgrafico; //calcola gli ultimi pixel da rappresentare nel righello orafine2:=PaintBox1.Width-ridpaint; durataora:=(PaintBox1.Width-ridpaint)/24; //calcola il numero di pixel che sono rappresentati da un ora durataminuto:=durataora/60; //calcola il numero di pixel che rappresentano un minuto duratamezzora:=(PaintBox1.Width-ridpaint)/48; altezzarighe:=(PaintBox1.height/11); //calcola la distanza che vi è tra le diverse righe che rappresentano il sorg e il tramont dei PianetiGraph PaintBox1.Canvas.Brush.Color:=colorform; //decide il colore di sfondo del canvas PaintBox1.Canvas.Font.Color:=clWhite; //mette il font bianco di default perchè cambia colore dal tema chiaro a scuro del sistema for corpo in oggetticelesti do //scrive i nomi degli oggetti celesti e rettangoli begin PaintBox1.Canvas.Pen.Color:=clWhite; PaintBox1.Canvas.Font.Size:=11; PaintBox1.Canvas.TextOut(xtesto,round(altezzarighe*i+distRighetop), copy(corpo.testo,0,3)); if corpo.nome= Sole then begin //i crepuscoli vanno messi in ordine dall'astronomio al civile per non fare in modo che si sovrascrivano a vicenda //crepuscolo astronomico PaintBox1.Canvas.Brush.Color:=$00300A00; PaintBox1.Canvas.Pen.Color:=clWhite; PaintBox1.Canvas.RoundRect(round(xgrafico+orafine2*corpo.astronomicaldusk/1440),round(altezzarighe*i+aggpospianeti+distrighetop),round(xgrafico+orafine2*corpo.astronomicaldawn/1440),round(altezzarighe*i+aggpospianeti+spesspianeti+distrighetop),roundrett,roundrett); //crepuscolo nautico PaintBox1.Canvas.Brush.Color:=$009E2200; PaintBox1.Canvas.Pen.Color:=clWhite; PaintBox1.Canvas.RoundRect(round(xgrafico+orafine2*corpo.nauticaldusk/1440),round(altezzarighe*i+aggpospianeti+distrighetop),round(xgrafico+orafine2*corpo.nauticaldawn/1440),round(altezzarighe*i+aggpospianeti+spesspianeti+distrighetop),roundrett,roundrett); //crepuscolo civile PaintBox1.Canvas.Brush.Color:=$00FF3700; PaintBox1.Canvas.Pen.Color:=clWhite; PaintBox1.Canvas.RoundRect(round(xgrafico+orafine2*corpo.civildusk/1440),round(altezzarighe*i+aggpospianeti+distrighetop),round(xgrafico+orafine2*corpo.civildawn/1440),round(altezzarighe*i+aggpospianeti+spesspianeti+distrighetop),roundrett,roundrett); end; PaintBox1.Canvas.Brush.Color:=corpo.colore; PaintBox1.Canvas.Pen.Color:=clWhite; if (corpo.sorge=-1) and (corpo.tramonta>=0) then begin PaintBox1.Canvas.RoundRect(xgrafico,round(altezzarighe*i+aggpospianeti+distrighetop),round(xgrafico+(orafine2*corpo.tramonta/1440)),round(altezzarighe*i+aggpospianeti+spesspianeti+distrighetop),roundrett,roundrett); end else begin if (corpo.sorge>=0) and (corpo.tramonta=-1) then begin PaintBox1.Canvas.RoundRect(round(xgrafico+orafine2*corpo.sorge/1440),round(altezzarighe*i+aggpospianeti+distrighetop),orafine,round(altezzarighe*i+aggpospianeti+spesspianeti+distrighetop),roundrett,roundrett); end else begin if (corpo.sorge=-1) and (corpo.tramonta=-1) then begin if corpo.isinsky=True then PaintBox1.Canvas.RoundRect(xgrafico,round(altezzarighe*i+aggpospianeti+distrighetop),orafine,round(altezzarighe*i+aggpospianeti+spesspianeti+distrighetop),roundrett,roundrett); end else begin if corpo.sorgevaloreriga) and (Y0 then oggetticelesti[i].isinsky:=True else oggetticelesti[i].isinsky:=False; end; end; end.