// mapwind.c // // This file implements the map windows' menus, controls and events. // // by John D. de Boer #include "twist.h" #include "twindow.h" extern SortGlobs Sort; extern GlobalOpts Opt; extern StepGlobs Step; extern void *Sel,*Was; extern int LINEWINDS; extern window *LineWind[]; extern IBNibRef Nib; int MAPWINDS; // number of map windows window *MapWind[MAXMAPWINDS]; // map windows MapPrefs LatLong; // map view preferences //static string Title; // window title from resource // Utility static int IndexOfWindow(window *W) { int i; for (i=0;i=0; } static void MapChanged(void) { if (Opt.onmap && LINEWINDS>0) redraw(LineWind[0]); } bool SeenOnAMap(int i) { int j; window *W; MapInfo *D; for (j=0;jappdata; if (!D || !D->vis) continue; if ((*(D->vis))[i]) return 1; } return 0; } void MaintainFocus(void) { if (MAPWINDS>0) MapFocus(MapWind[0]); } // Menus for map window static MenuRef MapMenu; static void InitMapMenus(void) { OSStatus err; err=CreateMenuFromNib(Nib,CFSTR("map"),&MapMenu); } static void SetUpMapMenus(void) { SetUpFileMenu(); InsertMenu(MapMenu,0); SetUpSortMenu(); SetUpSizeMenu(); InsertFilterMenus(); SetUpWindowMenu(); } static void AdjustMapMenus(window *W) { int i; //MapInfo *D; if (!W) return; //D=W->appdata; if (!D) return; AdjustFileMenu(W); AdjustFilterMenus(); allowitem(W,'MaFo',Sel!=NULL); checkitem(W,'MaMa',Opt.focus); checkitem(W,'MaLe',Opt.term); checkitem(W,'MaRe',Opt.region); checkitem(W,'MaAg',Opt.age); checkitem(W,'MaFN',Opt.fullnam); checkitem(W,'MaUn',Opt.unc); checkitem(W,'MaTe',!Opt.always); checkitem(W,'MaAl',Opt.alt); checkitem(W,'MaCo',Opt.coord); checkitem(W,'MaCM',Opt.fill); for (i=0;i<7;i++) checkitem(W,'Grp0' + i,Opt.group==i); checkitem(W,'ItLi',Opt.trip==2); checkitem(W,'ItLS',Opt.trip==1); checkitem(W,'ItGp',Opt.gpvoy); AdjustSortMenu(W); AdjustSizeMenu(W); } static bool MapCommand(window *W, UInt32 C) { int i; if (!W) return 0; switch (C) { case 'MaFo': MapFocus(W); redraw(W); MapChanged(); return 1; case 'MaMa': Opt.focus=!Opt.focus; if (Opt.focus) MaintainFocus(); Redisplay(); return 1; case 'MaLe': Opt.term=!Opt.term; redraw(W); return 1; // redraw all maps case 'MaRe': Opt.region=!Opt.region; Redisplay(); return 1; case 'MaAg': Opt.age=!Opt.age; redraw(W); return 1; // redraw all maps case 'MaFN': Opt.fullnam=!Opt.fullnam; redraw(W); return 1; // redraw all maps case 'MaUn': Opt.unc=!Opt.unc; Redisplay(); return 1; case 'MaTe': Opt.always=!Opt.always; redraw(W); return 1; // redraw all maps case 'MaAl': Opt.alt=!Opt.alt; redraw(W); return 1; // redraw all maps (and info?) case 'MaCo': Opt.coord=!Opt.coord; redraw(W); return 1; // redraw all maps case 'MaCM': Opt.fill=!Opt.fill; redraw(W); return 1; // redraw all maps case 'ItLi': if (Opt.trip!=2) Opt.trip=2; else Opt.trip=0; Redisplay(); return 1; case 'ItLS': if (Opt.trip!=1) Opt.trip=1; else Opt.trip=0; Redisplay(); return 1; case 'ItGp': Opt.gpvoy=!Opt.gpvoy; Redisplay(); return 1; } for (i=0;i<7;i++) if (C == 'Grp0' + i) { Opt.group=i; Redisplay(); return 1; } return FileCommand(W,C); } // Contextual Menus static bool MapPopup(window *W, point Pt) { if (!W || !Sel) return 0; if (VoidIsPers(Sel)) return PersonPopup(W,Pt,1,0,1,1,Sel); if (VoidIsEvent(Sel)) return EventPopup(W,Pt,1,0,1,Sel); return 0; } // Dragging the map static bool DragMap(mouseclick *M) { projdragtask T; long CONTEXTTIME; if (!M) return 0; T.good=0; initspheredrag(M,&T); if (!T.good) return 0; CONTEXTTIME= TickCount() + GetDblTime(); if (stilldown(M)) trackspheredrag(&T,M->now); if (Sel==Was) redraw(T.wind); else RedisplayAll(); while (stilldown(M)) { trackspheredrag(&T,M->now); if (!T.same) redraw(T.wind); if (!T.did && Sel && TickCount()>CONTEXTTIME) return MapPopup(T.wind,T.start); } MapChanged(); return 1; } // Controls static ControlActionUPP MapUPP; // control action procedure for buttons void AdjustMapControlState(window *W, int STATE) { MapInfo *D; if (!W || !IsMapWindow(W)) return; D=W->appdata; if (!D) return; HiliteControl(D->rwnd,(Step.running<0) ? 1 : 0); HiliteControl(D->stop,Step.running ? 0 : 1); HiliteControl(D->play,(Step.running>0) ? 1 : 0); } static void MapControlsInit(window *W) { MapInfo *D; if (!W) return; D=W->appdata; if (!D) return; D->slow=commonbutton(W,0,tdDownTriangle ); SetControlAction(D->slow,MapUPP); D->fast=commonbutton(W,1,tdUpTriangle ); SetControlAction(D->fast,MapUPP); D->rwnd=commonbutton(W,2,tdLeftTriangle ); SetControlAction(D->rwnd,MapUPP); D->stop=commonbutton(W,3,tdSquare ); SetControlAction(D->stop,MapUPP); D->play=commonbutton(W,4,tdRightTriangle); SetControlAction(D->play,MapUPP); } static pascal void mapbuttons(ControlRef C, short PART) { window *W; MapInfo *D; UInt32 Mods; bool Shift; if (!C) return; W=controlswindow(C); if (!W || !IsMapWindow(W)) return; D=W->appdata; if (!D) return; Mods=GetCurrentKeyModifiers(); Shift=((Mods & shiftKey)!=0); if (C==D->slow) { Slower(Shift); Redisplay(); AdjustMapControlState(W,0); return; } if (C==D->fast) { Faster(Shift); Redisplay(); AdjustMapControlState(W,0); return; } if (C==D->rwnd) { ReverseAnim(); AdjustMapControlState(W,0); return; } if (C==D->stop) { StopAnim(); AdjustMapControlState(W,0); return; } if (C==D->play) { StartAnim(); AdjustMapControlState(W,0); return; } } static bool MapContent(mouseclick *M) { window *W; if (!M) return 0; W=M->wind; if (!W) return 0; Was=Sel; Sel=MapHit(M); if (M->right && Sel) { if (Sel==Was) redraw(W); else RedisplayAll(); return MapPopup(W,M->point); } //if (M->cmnd) { if (Sel) SwitchToInfo(); else if (Was) RedisplayAll(); return 1; } return DragMap(M); } static bool MapDouble(mouseclick *M) { if (!M) return 0; Was=Sel; Sel=MapHit(M); if (Sel && Sel==Was) { SwitchToTimeLine(); return 1; } return MapContent(M); } static bool MapWheel(window *W, short DX, short DY) { return projectionwheel(W,-DX,-DY); } // "document mode" // The projection static bool MapKey(keystroke *K) { if (!K) return 0; if (ArrowKey(K)) return 1; if (K->c==8 || K->c==128) { if (!Sel) return 0; DeleteFromOrder(Sel); Sel=NULL; Redisplay(); return 1; } if (K->c==' ') { StopAnim(); return 1; } return projectionkey(K); } static void MapGrow(window *W) { if (!W || !W->proj) return; resizeproj(W->proj,W->page); MapChanged(); } static void MapAction(window *W) { DrawMap(W); MapChanged(); } // Map Preferences void RecordMapPrefs(void) { window *W; projection *P; if (MAPWINDS<1) return; W=MapWind[0]; if (!W) return; P=W->proj; if (!P) return; LatLong.theta= pibytwo - P->elev; LatLong.phi=P->azim; LatLong.mag=P->mag; LatLong.good=1; } static void InitMapProjection(window *W) { projection *P,*F; if (!W) return; P=W->proj; if (!P) return; if (MAPWINDS==0 && LatLong.good) { setviewangles(P,LatLong.theta,LatLong.phi); projtoscroll(W); setmagnification(P,LatLong.mag); } else if (MAPWINDS>0) { F=MapWind[0]->proj; setazimelev(P,F->azim,F->elev); projtoscroll(W); setmagnification(P,F->mag); } } // Map windows void InitMapViews(void) { MAPWINDS=0; //Title=resstring(201); MapUPP=NewControlActionUPP(&mapbuttons); InitMapMenus(); InitDrawGlobe(); LatLong.good=0; } static void OldMapWindow(window *W) { MapInfo *D; if (!W) return; D=W->appdata; if (D) release(D->vis); old(D); oldwindow(W); } static void CloseMapWindow(window *W) { int i; if (!W) return; i=IndexOfWindow(W); if (i<0) return; if (MAPWINDS==1) RecordMapPrefs(); OldMapWindow(W); MapWind[i]=MapWind[--MAPWINDS]; if (!AnimatedWindows()) StopAnim(); if (MAPWINDS<1) { Opt.onmap=0; if (LINEWINDS>0) redraw(LineWind[0]); } } static window *NewMapWindow(void) { window *W; MapInfo *D; W=standardwindow("Map"); if (!W) return NULL; stackwindow(W,StackableWindows()); W->erase=0; D=W->appdata=pointer(sizeof(MapInfo)); D->vis=(bool **)handle(0); W->proj=newprojection(0.0,0.0,0.0,275.0,W->page); setmaglimits(W->proj,250.0,40000.0); MapControlsInit(W); giveglobecontrols(W,5,40,45); scrolltoproj(W); InitMapProjection(W); installmenus(W,NULL,&SetUpMapMenus,&AdjustMapMenus,&MapCommand); installgrow(W,&MapGrow,NULL); installpaint(W,&DrawMap); installclick(W,&MapContent,&CloseMapWindow,&MapAction); installdouble(W,&MapDouble); installwheel(W,&MapWheel); installkey(W,&MapKey); installprint(W,NULL,&PrintMap); return W; } void AddMapWindow(void) { window *W; if (MAPWINDS>=MAXMAPWINDS) return; W=NewMapWindow(); if (!W) return; MapWind[MAPWINDS++]=W; revealwindow(W); //if (MAPWINDS==1 && LINEWINDS>0) redraw(LineWind[0]); Redisplay(); } // Command-click to change windows void SwitchToMap(void) { window *W; if (!Sel) return; if (MAPWINDS==0) AddMapWindow(); if (MAPWINDS==0) return; W=MapWind[0]; if (!W) return; ShowThisItem(Sel); TimeFocus(); MapFocus(W); RedisplayAll(); revealwindow(W); }