// drawthis.c // // This file draws the information in the "On This Day in..." window. // // by John D. de Boer #include "twist.h" #include "twindow.h" extern int PEOPLE,EVENTS; extern Person ***People; extern Event ***Events; extern GlobalOpts Opt; extern void *Sel; //extern string inHistory; static float //SIZE, // font height ItemHeight; // line spacing //static Rect Page; // page // Utility static void SetThisDrawVars(void) { //Page=*R; SIZE=Opt.size; ItemHeight= 1.4 * Opt.size; } static bool ThisDay(ThisInfo *T, Day *D, short *YEAR) { short MONTH,DATE; if (D->kind!=timeJD || D->unc>0) return 0; jdtodate(D->jd,YEAR,&MONTH,&DATE); return MONTH==T->month && DATE==T->date; } // Finding people milestones static void Milestone(ThisInfo *D, Person *P, int YEAR, char *S) { ThisItem *T; if (!D || !P || !S) return; T=pointer(sizeof(ThisItem)); T->obj=P; T->year=YEAR; T->str=cat(0,S,P->name); fuzzyresize(D->item,D->num + 1,sizeof(ThisItem *)); (*(D->item))[D->num++]=T; } static char *PowerWord(int HOW) { switch (HOW) { case powAcceeded: return "accession of "; case powAppointed: return "appointment of "; case powTook: return "assumption of power by "; case powElected: return "election of "; case powAbdicated: return "abdication of "; case powDeposed: return "deposing of "; case powRetired: return "retirement of "; } return NULL; } static void PowerMilestone(ThisInfo *D, Person *P, int YEAR, int HOW) { char *S; S=PowerWord(HOW); if (S) Milestone(D,P,YEAR,S); } static void PeopleThisDay(ThisInfo *D, Person *P) { short Y; int i; if (!D || !P) return; if (ThisDay(D,&(P->life.start),&Y)) Milestone(D,P,Y,"birth of "); if (ThisDay(D,&(P->life.end),&Y)) Milestone(D,P,Y,"death of "); for (i=0;inrgn;i++) { if (ThisDay(D,&(P->reign[i].start),&Y)) PowerMilestone(D,P,Y,P->pow[i]); if (ThisDay(D,&(P->reign[i].end ),&Y)) PowerMilestone(D,P,Y,P->ret[i]); } } // Finding events static void EventDate(ThisInfo *D, Event *E, int YEAR, char *S) { ThisItem *T; if (!D || !E) return; T=pointer(sizeof(ThisItem)); T->obj=E; T->year=YEAR; if (S) T->str=cat(0,S,E->name); else T->str=copyof(E->name); fuzzyresize(D->item,D->num + 1,sizeof(ThisItem *)); (*(D->item))[D->num++]=T; } static void EventsThisDay(ThisInfo *D, Event *E) { short Y; if (!D || !E) return; if (ZeroSpan(&(E->date))) { if (ThisDay(D,&(E->date.start),&Y)) EventDate(D,E,Y,NULL); return; } if (ThisDay(D,&(E->date.start),&Y)) EventDate(D,E,Y,"start of: "); if (ThisDay(D,&(E->date.end ),&Y)) EventDate(D,E,Y,"end of: "); } // Calculations to be done once when the window's date is set/changed static void OldThisItem(ThisItem *T) { if (!T) return; if (T->str) old(T->str); old(T); } void EmptyThisInfo(ThisInfo *D) { int i; if (!D) return; for (i=0;inum;i++) OldThisItem((*(D->item))[i]); D->num=0; } static bool OrderByYear(const void *A, const void *B) { ThisItem *C,*D; C=(ThisItem *)A; D=(ThisItem *)B; if (C->yearyear) return 1; if (C->year>D->year) return 0; if (begins(C->str,"death")) return 1; if (begins(D->str,"death")) return 0; return 1; } string TitleString(ThisInfo *D) { return cat5(4,monthname(D->month)," ",fig(D->date + 1)," ","in History"/*inHistory*/); } void DoThisDayCalcs(window *W) { int i; ThisInfo *D; char *S; if (!W) return; D=W->appdata; if (!D) return; S=TitleString(D); setwindowname(W,S); old(S); EmptyThisInfo(D); for (i=0;inum<2) return; lock(D->item); sort(*(D->item),D->num,&OrderByYear); unlock(D->item); } // Scroll bar ranges void SetThisScrolls(window *W) { ThisInfo *D; int VAL; if (!W || !W->vsb) return; D=W->appdata; if (!D) return; SetThisDrawVars(); D->fit= (height(W->page) /*- (Opt.size / 2.0)*/) / ItemHeight; VAL=GetControlValue(W->vsb); setscrollbar(W->vsb,VAL,0,gtr(0,D->num - D->fit)); } // Drawing contents static string ThisItemYear(ThisItem *T) { string S; if (!T) return NULL; S=fig(abso(T->year)); if (T->year<0) S=cat(1,S," B.C."); return S; } static void DrawThisItem(window *W, ThisItem *T, int POS) { float H,V; bool SI; string S; if (!W || !T) return; H= left(W->page) + (Opt.size / 2.0); V= height(W->page) - ((POS + 1) * ItemHeight); SI=Highlight(W,T->obj); //TextFace(SI ? (bold + outline) : bold); S=cat3(1,ThisItemYear(T)," : ",T->str); if (SI) boldtext(W,H,V,S,Opt.size); else drawtext(W,H,V,S); old(S); } // Entry points for drawing void DrawThisDay(window *W) { int i,FIRST,LAST; ThisInfo *D; if (!W) return; D=W->appdata; if (!D) return; SetThisScrolls(W); SetThisDrawVars(); textsize(W,Opt.size); fillindex(W,black); if (W->vsb) FIRST=GetControlValue(W->vsb); else FIRST=0; LAST=lsr(D->num,FIRST + D->fit); for (i=FIRST;iitem))[i],i - FIRST); } void PrintThisDay(window *W, short PAGE) { int i,FIRST,LAST; ThisInfo *D; if (!W) return; D=W->appdata; if (!D) return; SetThisDrawVars(); textsize(W,Opt.size); fillindex(W,black); FIRST=0; LAST=D->num; // no page # support yet drawtextold(W,left(W->page),top(W->page) + Opt.size,TitleString(D)); for (i=FIRST;iitem))[i],i - FIRST + 2); } // Copying text string ThisDayString(ThisInfo *D) { int i; string S; ThisItem *T; if (!D) return NULL; S=NULL; for (i=0;inum;i++) { T=(*(D->item))[i]; S=cat5(1,S,ThisItemYear(T),"\t",T->str,"\r"); } return S; } // Clicking in "This Day" windows void *ThisHit(mouseclick *M) { window *W; ThisInfo *D; int ITEM; float V; W=M->wind; if (!W || !W->vsb) return NULL; D=W->appdata; if (!D) return NULL; V= height(W->page) - M->point.y; V-= 0.35 * Opt.size; ITEM= V / ItemHeight; if (!range(ITEM,D->fit)) return NULL; ITEM+=GetControlValue(W->vsb); if (!range(ITEM,D->num)) return NULL; return (*(D->item))[ITEM]->obj; }