// genwind.c // // This file implements the genealogy windows' menus, controls and events. // // by John D. de Boer #include "twist.h" #include "twindow.h" extern GlobalOpts Opt; extern void *Sel,*Was; extern real Breakout2; extern IBNibRef Nib; int GENWINDS; // number of genealogy windows window *GenWind[MAXGENWINDS]; // genealogy windows //static string Title; // window title from resource // Menus for the genealogy window static MenuRef GenMenu; static void InitGenMenus(void) { OSStatus err; err=CreateMenuFromNib(Nib,CFSTR("genealogy"),&GenMenu); } static void SetUpGenMenus(void) { SetUpFileMenu(); InsertMenu(GenMenu,0); SetUpSizeMenu(); SetUpWindowMenu(); } static void AdjustGenMenus(window *W) { GenInfo *D; if (!W) return; D=W->appdata; if (!D) return; AdjustFileMenu(W); AdjustSizeMenu(W); checkitem(W,'GeCT',D->compr); checkitem(W,'GeCo',D->vert==0); checkitem(W,'GeNo',D->vert==1); checkitem(W,'GeEx',D->vert==2); checkitem(W,'GePB',Opt.pink); checkitem(W,'GeRR',Opt.round); checkitem(W,'GeIt',Opt.italic); } static bool GenCommand(window *W, UInt32 C) { GenInfo *D; if (!W) return 0; D=W->appdata; if (!D) return 0; switch (C) { case 'GeCT': D->compr=!D->compr; D->recalc=1; redraw(W); return 1; case 'GeCo': D->vert=0; D->recalc=1; redraw(W); return 1; case 'GeNo': D->vert=1; D->recalc=1; redraw(W); return 1; case 'GeEx': D->vert=2; D->recalc=1; redraw(W); return 1; case 'GePB': Opt.pink=!Opt.pink; redraw(W); return 1; case 'GeRR': Opt.round=!Opt.round; redraw(W); return 1; case 'GeIt': Opt.italic=!Opt.italic; redraw(W); return 1; case 'GeHT': genhtml(W,D->pers); return 1; } return FileCommand(W,C); } // Contextual Menus static bool GenPopup(window *W, point Pt) { GenInfo *D; if (!Sel || !W) return 0; D=W->appdata; if (!D) return 0; if (VoidIsPers(Sel)) return PersonPopup(W,Pt,1,1,1,Sel!=D->pers,Sel); return 0; } // Dragging the map typedef struct { bool good, // struct has been initialised successfully same, // whether mouse has remained stationary since last draw did; // whether any dragging took place window *wind; // time-line window in which drag takes place point start, // start point of drag end, // current or end point of drag scroll; // scrollbar values at start of drag } gendragtask; static void initgendrag(mouseclick *M, gendragtask *T) { ControlRef C; point Pt; if (!M || !M->wind || !M->wind->hsb || !M->wind->vsb || !T) return; T->wind=M->wind; Pt=M->point; T->start=T->end=Pt; C=M->wind->hsb; T->scroll.x=GetControlValue(C); C=M->wind->vsb; T->scroll.y=GetControlValue(C); T->same=1; T->did=0; T->good=1; } static void trackgendrag(gendragtask *T, point P) { ControlRef C; int OLD,NEW; point Rel; if (!T) return; Rel.x= P.x - T->end.x; Rel.y= P.y - T->end.y; T->same=(Rel.x==0 && Rel.y==0); if (!T->did && (Rel.x * Rel.x) + (Rel.y * Rel.y) <= Breakout2) T->same=1; if (T->same) return; T->end=P; P.x= T->scroll.x + T->start.x - T->end.x; P.y= T->scroll.y - T->start.y + T->end.y; T->same=1; C=T->wind->hsb; OLD=GetControlValue(C); SetControlValue(C,P.x); NEW=GetControlValue(C); if (NEW!=OLD) T->same=0; C=T->wind->vsb; OLD=GetControlValue(C); SetControlValue(C,P.y); NEW=GetControlValue(C); if (NEW!=OLD) T->same=0; if (T->same) return; T->did=1; } static bool DragGen(mouseclick *M) { gendragtask T; long CONTEXTTIME; if (!M) return 0; T.good=0; initgendrag(M,&T); if (!T.good) return 0; CONTEXTTIME= TickCount() + GetDblTime(); if (stilldown(M)) trackgendrag(&T,M->now); if (Sel==Was) redraw(T.wind); else RedisplayAll(); while (stilldown(M)) { trackgendrag(&T,M->now); if (!T.same) redraw(T.wind); if (!T.did && Sel && TickCount()>CONTEXTTIME) return GenPopup(M->wind,T.start); } return 1; } // Controls static ControlActionUPP GenUPP; // control action procedure for scroll bars static pascal void genscroll(ControlRef C, short PART) { int OLD,NEW; window *W; if (!C) return; W=controlswindow(C); if (!W) return; if (PART==kControlIndicatorPart) { redraw(W); return; } OLD=GetControlValue(C); NEW= OLD + partincrement(PART,32,256); SetControlValue(C,NEW); NEW=GetControlValue(C); if (NEW==OLD) return; redraw(W); } static void GenControlsInit(window *W) { givescrolls(W); SetControlAction(W->hsb,GenUPP); SetControlAction(W->vsb,GenUPP); GenGrow(W); /*GenScrollToOrigin(W);*/ } static bool GenContent(mouseclick *M) { window *W; GenInfo *D; if (!M) return 0; W=M->wind; if (!W) return 0; D=W->appdata; if (!D) return 0; Was=Sel; Sel=GenHit(M); if (M->right && Sel) { if (Sel==Was) redraw(W); else RedisplayAll(); return GenPopup(W,M->point); } //if (M->cmnd) { if (Sel) SwitchToInfo(); else if (Was) RedisplayAll(); return 1; } return DragGen(M); } static bool GenDouble(mouseclick *M) { if (!M) return 0; Was=Sel; Sel=GenHit(M); if (Sel && Sel==Was) { SwitchToTimeLine(); return 1; } return GenContent(M); } static bool GenWheel(window *W, short DX, short DY) { ControlRef C; int OLD,NEW; bool Did; if (!W) return 0; Did=0; C=W->hsb; if (DX && C) { OLD=GetControlValue(C); SetControlValue(C,OLD - (3 * DX)); NEW=GetControlValue(C); if (NEW!=OLD) Did=1; } C=W->vsb; if (DY && C) { OLD=GetControlValue(C); SetControlValue(C,OLD - (3 * DY)); NEW=GetControlValue(C); if (NEW!=OLD) Did=1; } redraw(W); return Did; } static bool GenKey(keystroke *K) { if (!K) return 0; return 0; } // Genealogy windows void InitGenViews(void) { GENWINDS=0; //Title=resstring(202); GenUPP=NewControlActionUPP(&genscroll); InitGenMenus(); } static int IndexOfWindow(window *W) { int i; for (i=0;iappdata; if (!D) continue; if (D->pers==P) return W; } return NULL; } static void OldGenWindow(window *W) { if (!W) return; old(W->appdata); oldwindow(W); } static void CloseGenWindow(window *W) { int i; if (!W) return; i=IndexOfWindow(W); if (i<0) return; OldGenWindow(W); GenWind[i]=GenWind[--GENWINDS]; } void CloseAllGens(void) { while (GENWINDS>0) CloseGenWindow(GenWind[0]); } static window *NewGenWindow(Person *P) { window *W; GenInfo *D; char *S; if (!P) return NULL; W=standardwindow("Genealogy"); if (!W) return NULL; stackwindow(W,StackableWindows()); //makeoffscreen(W); D=W->appdata=pointer(sizeof(GenInfo)); D->lastsize=-1; D->compr=0; D->vert=1; D->recalc=1; D->pers=P; S=cat(0,"Genealogy of ",P->name); setwindowname(W,S); old(S); DoGenDrawCalcs(W); GenControlsInit(W); ScrollGenToSubject(W); installmenus(W,NULL,&SetUpGenMenus,&AdjustGenMenus,&GenCommand); installgrow(W,&GenGrow,NULL); installpaint(W,&DrawGen); installclick(W,&GenContent,&CloseGenWindow,&DrawGen); installdouble(W,&GenDouble); installwheel(W,&GenWheel); installkey(W,&GenKey); installprint(W,&GenPages,&PrintGen); installpict(W,&GenPDFSize,&GenPDFDraw); return W; } static void AddGenWindow(Person *P) { window *W; if (GENWINDS>=MAXGENWINDS) return; W=NewGenWindow(P); if (!W) return; GenWind[GENWINDS++]=W; revealwindow(W); redraw(W); } // Opening genealogy window for selection void SwitchToGen(void) { window *W; if (!Sel || !VoidIsPers(Sel)) return; W=GenWindOf(Sel); if (W) { revealwindow(W); return; } AddGenWindow(Sel); }