/* 3D graphic window class functions. They need not to be reenterable but MUST be reusable. */ #include "common.h" #define SCROLL_ANGLES 1 /* Attach scroll bar to angle DialogText */ #define MOUSE 0 /* Allow pick up corrdinates by mouse */ #if LINKIN #include "large.h" #include "datalib0.h" #include "visual.h" #include "tsprintf.h" #undef MemNew #undef MemMore #undef MemFree #undef StringSave #define MemNew _MemNew #define MemMore _MemMore #define MemFree _MemFree #define StringSave _StringSave #else /* LINKIN */ #include "corefunc.h" #include "inter.h" #endif /*LINKIN */ #define GET_CLASS_TABLE g3d_GetClassTable /* Unique name of the 'Get Class Table' function */ #include "window.h" /* GetClassTable is generated by window.h */ /* Texts */ Local(CharPtr) Text[]={ "Compute{", "Forward", "Backward", "Extend", "Window{", "Redraw diagram", "Redraw curve", "Clear", "Fit diagram", "Fit curve", "Undo scale", "Undo rotate", "Layout...", "Hardcopy...", "Duplicate", "Hide", "Attributes{", "Current...", "Curve...", #if MOUSE "Mouse{", "Pick up coordinates?", "Immediate forward?", "Immediate backward?", #endif /* MOUSE */ "Help{", "This window", "Search", "-", "}", "OX", /***"Abscissa",***/ "OY", /***"Ordinate",***/ "OZ", /***"Applicata",***/ "Waiting for attributes setting", "Attributes of graphic window", "Current drawing attributes", "Drawing attributes of current curve", "4,11,(6,13)", /* NumLen,TextLen,(ListLines,LineLen) */ "Limits of visibility", "Min", "Max", "Tick", "Scale", "Label", "Box", "Axis", "Projections", "Angles", #define THETA_STR "J" #define PHI_STR "j" "Colors", "Change color", "Foreground", "Background", "Show palette", "The first point", "The last point", "Show in window", "Points", "Traces", "Paths", "Shifts", "Graphic attributes", "Set attributes of", "Curve segment", "From point", "To point", "Functions along axes", "New functions", "Delete functions", "Attributes set", "Add attributes", "Delete attributes", "Join", "Width", "No", "Solid", "Dotted", "Options", "Clear before each point", "Hardcopy options", "Waiting for hardcopy options", "File", "Browse", "Picture", "Width", "Height", "mm cm in", "Font", "Options", "Curve width scale factor", "Line width scale factor", "Marker scale factor", "Try to preserve colors", #if _UNIX "Show on screen", "Send to printer", #endif "Sample of window", "1/1 ", "Window title", NULL }; enum { COMPUTE_M, FORWARD_I, BACKWARD_I, EXTEND_I, WINDOW_M, REDRAWD_I, REDRAWC_I, CLEAR_I, FITD_I, /* Fit diagram */ FITC_I, /* Fit curve */ UNDOSCALE_I, /* Undo scale */ UNDOROTATE_I, /* Undo rotate */ LAYOUT_I, /* Layout */ HARDCOPY_I, /* Hardcopy */ DUPLICATE_I, /* Duplicate */ HIDE_I, ATTRIBUTES_M, /* Attributes{ */ CURRENTATR_I, /* Current... */ CURVEATR_I, /* Curve... */ #if MOUSE MOUSE_M, /* Mouse{ */ MOUSEPICK_I, /* Pick up coordinates? */ MOUSEIMMEDF_I,/* Immediate forward? */ MOUSEIMMEDB_I,/* Immediate backward? */ #endif /* MOUSE */ HELP_M, HELP_I, SEARCH_I, SEPARATOR_I, DUMMYEND_I, ABS_P, /* Abscissa */ ORD_P, /* Ordinate */ APP_P, /* Applicata */ WAITATTR_C, /* Waiting for attributes setting */ LAYOUT_T, /* Attributes of graphic window */ DRAWATTR_T, /* Current drawing attributes */ CURVEATTR_T, /* Drawing attributes of current curve */ SIZES, /* 4,11,(6,13) ! NumLen,TextLen,(ListLines,LineLen) */ LIMOFVIS_T, /* Limits of visibility */ MIN_P, /* Min */ MAX_P, /* Max */ TICK_P, /* Tick */ SCALE_P, /* Scale */ FUNC_P, /* Label */ BOX_P, /* Box (bounding) */ AXIS_P, /* Axis */ PROJ_P, /* Projections */ ANGLES_P, /* Angles */ COLORS_T, /* Colors */ COLOR_B, /* Change color */ FG_P, /* Foreground */ BG_P, /* Background */ SHOWPAL_P, /* Show palette */ FP_P, /* The first point */ LP_P, /* The last point */ SHOWOPT_P, /* Show in window */ POINTS_P, /* Points */ TRACES_P, /* Traces */ PATHS_P, /* Paths */ SHIFTS_P, /* Shifts */ ATTR_T, /* Graphic attributes */ ATTROF_T, /* Set attributes of */ SEG_P, /* Curve segment */ SPF_P, /* From point */ SPT_P, /* To point */ CURVES_P, /* Functions along axes */ ADDFUN_B, /* New functions */ DELFUN_B, /* Delete functions */ AN_P, /* Attributes set */ AA_B, /* Add attributes */ DA_B, /* Delete attributes */ JOIN_T, /* Join points along */ WIDTH_P, /* Width */ NO_B, /* No */ SOLID_B, /* Solid */ DOTTED_B, /* Dotted */ OPTIONS_P, /* Options */ CLEAR_P, /* Clear before each point */ HARDCOPY_T, /* Hardcopy options */ HARDCOPY_C, /* Waiting for hardcopy options */ HCFILE_G, /* File */ HCFILELIST_B, /* Browse */ HCPIC_P, /* Picture */ HCWIDTH_P, /* Width */ HCHEIGHT_P, /* Height */ HCUNITS, /* mm cm in */ HCFONTG_P, /* Font */ HCOPT_P, /* Options */ HCCWIDF_P, /* Curve width scale factor */ HCLWIDF_P, /* Line width scale factor */ HCMF_P, /* Marker scale factor */ HCOPTCOL_P, /* Try to preserve colors */ #if _UNIX HCOPTPRE_P, /* Show on screen */ HCOPTPRI_P, /* Send to printer */ #endif SAMPLE_WIN, /* Sample of window */ FUNCNUM_P, /* "1/1 " */ WINTITLE_P, /* Window title */ _L_A_S_T_ }; #define DEFAULT_TITLE "3D graphic" /* default title of window */ #define HK_3DWIN "kh_3DWin" /* Help key for the window */ #define HK_LAYOUTWIN "kh_3DWinLayout" /* Help key for layout dialog box */ #define HK_HARDCOPYWIN "kh_3DWinHardcopy" /* Help key for hardcopy dialog box */ #define KH_CURRENTATTR "kh_3DWinCurrentAttr" /* Help key for current attributes dialog box */ #define KH_CURVEATTR "kh_3DWinCurveAttr" /* Help key for curve's attributes dialog box */ /* Settings file section name */ #define SECTION "Window_3DGraphic" #define SECTION_COM "Visual" #define PI NCBIMATH_PI /* Axis function */ typedef EntryPtr(FloatHi,WinFloatValue,(FloatHiPtr PNTR PNTR ptr)); /* Axis descriptor */ typedef struct { CharPtr pFunc; /* user-specified function along the axis */ union { /* depends on FuncKind */ struct { Int2 IndirectIndex; /* index to IndirectValues */ Uint2 Offset; /* offset in values vector */ } Simple; /* Simple value */ struct { WinFloatValue FloatFunc; /* ptr to axis's function */ } General; /* General case */ } Func; FloatHi Wcoord; /* windows coords of previous point */ Int1 FuncKind; /* 0 - simple variable, 1 - must be compiled, -1 - undefined */ Boolean Gdim; /* TRUE - Gdim(pFunc)==1 */ FloatHi Eip; } AxisFunc, PNTR AxisFuncPtr; /* Hardcopy */ typedef struct { FloatHi u,v; } Point2d, PNTR Point2dPtr; typedef FloatHi Point3d[3]; typedef Point3d PNTR Point3dPtr; /* Draw attributes of points, traces, and paths */ typedef struct { DrawAttr Point; DrawAttr Trace; /* style>0 => join along traces */ DrawAttr Path; /* style>0 => join along paths */ Point3dPtr PrevPath; /* used if Attr[].Path.style>0 and points to 2 vectors */ Point3dPtr CurPath; /* with windows coordinates of M-points on prev and cur G-points */ Int2 PrevNum,CurNum; /* number of PoinTs in PrevPath and CurPath */ Int2 flags; /* func-specific flags */ #define PATH_CHANGE 0x0001 /* Path.style has been chaged from <0 to >0 */ } FuncAttr, PNTR FuncAttrPtr; /* Options unrelated to axes, traces and paths */ typedef struct { FloatHi Angle[2]; #define Theta Angle[0] /* colatitude of point of view */ #define Phi Angle[1] /* longitude of point of view */ DrawAttr Shift; /* style>0 => join along shifts */ Uint1 Flags; #define GWIN_PALETTE 0x01 #define GWIN_CLEAR 0x02 Uint1 Reserve; /* unused now */ } ShowOptions; /* Element of the undo scale buffer */ typedef struct { FloatHi xMin,xMax,yMin,yMax,zMin,zMax; } UndoElem, PNTR UndoElemPtr; /* Element of the undo rotate buffer */ typedef struct { FloatHi theta,phi; } UndoRElem, PNTR UndoRElemPtr; /* Private data structure which describes window's controls */ typedef struct { /* Description of controls */ struct { CharPtr pText[4]; #define pMin pText[0] /* Min */ #define pMax pText[1] /* Max */ #define pCurFunc pText[2] /* Current Function along the axis */ #define FUNCINDEX 2 #define FuncIndex(i) (i==FUNCINDEX) #define pTick pText[3] /* Tick */ AxisFuncPtr Funcs; /* to array of axis function */ Boolean Prop[8]; /* Properties (valid for [0] only) */ #define bLimits Prop[0] #define bTick Prop[1] #define bScale Prop[2] #define bFunc Prop[3] #define bBox Prop[4] #define bAxis Prop[5] #define bProj Prop[6] #define bAngles Prop[7] } Axis[3]; /* 0 - abs, 1 - ord, 2 - app */ CharPtr pAngle[2]; /* 0 - theta, 1 - phi */ #define pTheta pAngle[0] #define pPhi pAngle[1] FuncAttrPtr Attr; /* to array of attributes of points,traces,paths */ FuncAttrPtr SaveAttr;/* used for temporary storage of attrs */ ShowOptions Options; /* Work area */ Int2 flags; #define DONT_SCALE 0x0001 /* don't draw scale; set by MInit for DrawProc */ #if MOUSE #define MOUSE_PICK 0x0002 /* Mouse click sets up initial point */ #define MOUSE_IMMB 0x0004 /* and starts backward */ #define MOUSE_IMMF 0x0008 /* and starts forward */ #endif /* MOUSE */ #define FIT_IN_PROGRESS 0x0010 /* Fit diagram/curve in progress */ GrouP grLimits; /* Limits SpeedBar group */ GrouP grPalette; /* Palette SpeedBar group */ #if MYSWITCH Switch swNum; /* Palette: number of current curve */ #else SwitcH swNum; /* Palette: number of current curve */ #endif PaneL paSample; /* Palette: sample of curve color */ struct { TexT teLimits[4]; /* 0 - Min, 1 - Max, 2 - Func, 3 - Tick */ PrompT prompt; } teAxis[3]; /* Limits SpeedBar controls */ struct { TexT teAngle; PrompT prompt; #if SCROLL_ANGLES BaR baAngle; #endif /* SCROLL_ANGLES */ } teAngle[2]; /* Angles SpeedBar controls: 0 - theta, 1 -phi */ /* A list of window coordinates of special points */ ByteStorePtr SpecialPoints; /* Drawing area */ PaneL paPanel; /* Graphics drawing area */ RecT Slate; /* coincides with the Panel if scales are off */ ButtoN buRefr; /* invisible default button */ TexT teAct; /* invisible; actvie while compute */ FloatHi DeltaU,DeltaV; FloatHi uMin,uMax,vMin,vMax; Int2 FuncNum; /* number of function pairs; usually 1 */ Int2 FuncCur; /* current function pair (from 0) */ Int2 SaveFuncNum; /* temp store FuncNum: Push/Pop attr */ Int2 InitLevel; /* depth of GInit nested calls (redraw in pause) */ struct { FloatHi Limits[4]; #define Min Limits[0] #define Max Limits[1] /* Limits[2] (Func) used only to align Tick to have the same index as pTick */ /* From 15.07.94 it is overlayed by Step */ #define Step Limits[2] #define Tick Limits[3] FloatHi FitLimits[2]; /* used by fit diagram/curve only */ #define FitMin FitLimits[0] #define FitMax FitLimits[1] } RAxis[3]; /* Used by conversion routines. May differ from Axis[].pText[] in cases the user set invalid Min and/or Max and/or Tick */ PoinT l[2],f[2],r[2],b[2]; /* left-front-right-back vertical edges as they are visible */ Point2d lhc[2],fhc[2],rhc[2],bhc[2]; /* Hardcopy: left-front-right-back vertical edges as they are visible */ Int2 ilx,ily,ifx,ify,irx,iry,ibx,iby; /* bounding box */ PoinT xy[2][2]; /* scale: win coords of X and Y edges; x/y and from/to */ Point2d xyhc[2][2]; /* hardcopy: 2d coords of X and Y edges; x/y and from/to */ Boolean xybottom[2]; /* numbers under the axis */ Int2 xywidth[2]; /* used for labels */ PoinT xa[2],ya[2],za[2]; /* axes */ Point2d xahc[2],yahc[2],zahc[2]; /* hardcopy: math2d axes */ Boolean xay,yay,zay; /* visibility of axes */ FloatHi sinTheta,cosTheta,sinPhi,cosPhi; Boolean usurface; /* TRUE when upper horizontal surface is visible */ Boolean joinpath; /* OR'ed Attr[0..FuncNum-1].Path.style>0 */ /* Undo scale */ UndoElemPtr UndoBuf; Int2 UndoNum; /* Undo rotate */ UndoRElemPtr UndoRBuf; Int2 UndoRNum; /* Hardcopy */ FILE PNTR HardFile; /* output for hardcopy */ Boolean Hardcopy; /* set when in hardcopy progress for this window */ Int2 hcMarkerNo; /* Ordinal number of current marker */ /* Click-hold-release */ FloatHi saveTheta,savePhi; PoinT ptClick; Boolean bDrag; /* Multi-point paths */ Int2 PrevNum,Q,Qs,Q1s,JoinIndex,JoinNum; } GraphicData, PNTR GraphicDataPtr; /* Head and tail of window functions */ typedef EntryPtr(void,WinFuncPtr,(FloatHiPtr PNTR PNTR ptr)); #define WIN_HEAD \ "double" \ " $("SFS_COMPILER".RHSATTR)" \ " %s" \ " (double * * * $("SFS_VISUAL".WINPAR)) {"STR_NL \ " return "STR_EMPTY #define WIN_TAIL \ ";"STR_NL"}"STR_NL #define UNDODEPTH 10 /* undo scale buffer's length */ #define round(x) ((Int2)floor((x)+0.5)) /* to the nearest integer */ /* Needed but missed in ncbidraw */ Local(void) MultPt(PointPtr pt, FloatHi factor) { pt->x=round(pt->x*factor); pt->y=round(pt->y*factor); } #if _WIN #pragma argsused #endif Callback(Boolean) AlwaysStatus(Int2 indx) { return TRUE; } Callback(void) lRedrawD(Int2 indx); Callback(void) lRedrawC(Int2 indx); Callback(void) lClear(Int2 indx); Callback(void) lFitDiagram(Int2 indx); Callback(void) lFitCurve(Int2 indx); Callback(void) lLayout(Int2 indx); Callback(void) lUndoScale(Int2 index); Callback(Boolean) lUndoScale_Status(Int2 index); Callback(void) lUndoRotate(Int2 index); Callback(Boolean) lUndoRotate_Status(Int2 index); Callback(void) lHardcopy(Int2 indx); Callback(void) lDuplicate(Int2 index); Callback(void) lCurrentAtr(Int2 indx); Callback(void) lCurveAtr(Int2 indx); #if MOUSE Callback(void) lPickCoord(Int2 index); Callback(Boolean) lPickCoord_Status(Int2 index); Callback(void) lImmedFComp(Int2 index); Callback(Boolean) lImmedFComp_Status(Int2 index); Callback(void) lImmedBComp(Int2 index); Callback(Boolean) lImmedBComp_Status(Int2 index); #endif /* MOUSE */ Callback(void) lHelp(Int2 indx); Callback(void) lHelpSearch(Int2 indx); /* Menu */ Local(MenuItem) GraphicMenu[]={ {COMPUTE_M, NULL, NULL}, { FORWARD_I, NULL, NULL}, { BACKWARD_I, NULL, NULL}, { SEPARATOR_I, NULL, NULL}, { EXTEND_I, NULL, NULL}, { DUMMYEND_I, NULL, NULL}, {WINDOW_M, NULL, NULL}, { REDRAWD_I, lRedrawD, NULL,0,MNFL_ACTIVEINPAUSE}, { REDRAWC_I, lRedrawC, NULL,0,MNFL_ACTIVEINPAUSE}, { SEPARATOR_I, NULL, NULL}, { CLEAR_I, lClear, AlwaysStatus,0,MNFL_ACTIVEINPAUSE}, { SEPARATOR_I, NULL, NULL}, { FITD_I, lFitDiagram, NULL,0,MNFL_ACTIVEINPAUSE}, { FITC_I, lFitCurve, NULL,0,MNFL_ACTIVEINPAUSE}, { SEPARATOR_I, NULL, NULL}, { UNDOSCALE_I, lUndoScale, lUndoScale_Status,0,MNFL_ACTIVEINPAUSE}, { UNDOROTATE_I, lUndoRotate, lUndoRotate_Status,0,MNFL_ACTIVEINPAUSE}, { SEPARATOR_I, NULL, NULL}, { LAYOUT_I, lLayout, AlwaysStatus}, { SEPARATOR_I, NULL, NULL}, { HARDCOPY_I, lHardcopy, NULL}, { SEPARATOR_I, NULL, NULL}, { DUPLICATE_I, lDuplicate, AlwaysStatus}, { SEPARATOR_I, NULL, NULL}, { HIDE_I, NULL, AlwaysStatus,0,MNFL_ACTIVEINPAUSE}, { DUMMYEND_I, NULL, NULL}, {ATTRIBUTES_M, NULL, NULL}, { CURRENTATR_I, lCurrentAtr, AlwaysStatus,0,MNFL_ACTIVEINPAUSE}, { CURVEATR_I, lCurveAtr, NULL,2,MNFL_ACTIVEINPAUSE}, { DUMMYEND_I, NULL, NULL}, #if MOUSE {MOUSE_M, NULL, NULL}, { MOUSEPICK_I, lPickCoord, lPickCoord_Status}, { MOUSEIMMEDF_I, lImmedFComp, lImmedFComp_Status}, { MOUSEIMMEDB_I, lImmedBComp, lImmedBComp_Status}, { DUMMYEND_I, NULL, NULL}, #endif /* MOUSE */ {HELP_M, NULL, NULL}, { HELP_I, lHelp, AlwaysStatus,0,MNFL_ACTIVEINPAUSE}, { SEPARATOR_I, NULL, NULL}, { SEARCH_I, lHelpSearch, AlwaysStatus,0,MNFL_ACTIVEINPAUSE}, { DUMMYEND_I, NULL, NULL} }; Local(void) UndoRecord(WinComDataPtr wcd); Local(void) UndoRRecord(WinComDataPtr wcd); Local(FonT) SymFont; /* symbol font (greek letters) */ #define GetComDataI ((WinComDataPtr)GetWindowExtra(CurrentWindow())) #define GetComDataC(h) ((WinComDataPtr)GetWindowExtra(ParentWindow(h))) /* Visible names by default */ Local(Int2) vn_num; Local(GraphicDataPtr)vn_gd; #if _WIN #pragma argsused #endif Local(void) vn_EnumVariables(LisT List, CharPtr VarName, Int2 Dim) { Char buf[100]; if (vn_num>=3) return; StrCpy(buf,VarName); if (Dim>1) StrCat(buf,"[0]"); vn_gd->Axis[vn_num].Funcs[0].pFunc=StringSave(buf); vn_num++; } ClassMember(void) BuildDefaultDescription(WinComDataPtr wcd) { GraphicDataPtr gd; DrawAttr da; Int2 i,j; wcd->WinTitle=StringSave(DEFAULT_TITLE); if (!wcd->Private) wcd->Private=MemNew(sizeof(GraphicData)); gd=(GraphicDataPtr)wcd->Private; gd->FuncNum=1; /* number of V-curves */ gd->FuncCur=0; /* the 1st is the current */ for (i=0; iAxis); i++) { gd->Axis[i].pMin=StringSave("0"); gd->Axis[i].pMax=StringSave("1"); gd->Axis[i].Funcs=MemNew(ARRAYSIZE(AxisFunc,1)); gd->Axis[i].pTick=StringSave("0"); /* default: choose tick automatically */ for (j=0; jAxis[0].Prop); j++) gd->Axis[i].Prop[j]=TRUE; /* All on by default except for ...*/ gd->Axis[i].bTick=FALSE; gd->Axis[i].bAxis=FALSE; gd->Axis[i].bProj=FALSE; gd->Axis[i].Funcs[0].FuncKind=0; /* Simple */ } vn_gd=gd; for (vn_num=i=0; iAxis) && vn_num<3; i++) EnumVariables(NULL,i,vn_EnumVariables); gd->Attr=MemNew(ARRAYSIZE(FuncAttr,1)); da.color=wcd->Foreground; da.width=2; da.style=-1; /* don't join; when negated - solid line */ gd->Attr[0].Point=da; gd->Attr[0].Trace=da; gd->Options.Shift=da; da.style=1; /* Solid */ gd->Attr[0].Path=da; gd->Options.Flags=0; gd->Options.Reserve=0; gd->SpecialPoints=BSNew(0); gd->pTheta=StringSave("45"); gd->pPhi=StringSave("45"); } ClassMember(void) ReadDescription(WinComDataPtr wcd, DataLibPtr arch){ GraphicDataPtr gd; Int2 i,j,un; if (!wcd->Private) wcd->Private=MemNew(sizeof(GraphicData)); gd=(GraphicDataPtr)wcd->Private; DataLibRead(arch,(CharPtr)&gd->FuncNum,sizeof(gd->FuncNum)); DataLibRead(arch,(CharPtr)&gd->FuncCur,sizeof(gd->FuncCur)); for (i=0; iAxis); i++) { for (j=0; jAxis[i].pText); j++) if (!FuncIndex(j)) gd->Axis[i].pText[j]=DataLibReadVRecord(arch,NULL); gd->Axis[i].Funcs=MemNew(ARRAYSIZE(AxisFunc,gd->FuncNum)); for (j=0; jFuncNum; j++) gd->Axis[i].Funcs[j].pFunc=DataLibReadVRecord(arch,NULL); DataLibRead(arch,(CharPtr)gd->Axis[i].Prop,sizeof(gd->Axis[i].Prop)); } gd->Attr=MemNew(ARRAYSIZE(FuncAttr,gd->FuncNum)); for (i=0; iFuncNum; i++) { DataLibRead(arch,(CharPtr)&gd->Attr[i].Point,sizeof(DrawAttr)); DataLibRead(arch,(CharPtr)&gd->Attr[i].Trace,sizeof(DrawAttr)); DataLibRead(arch,(CharPtr)&gd->Attr[i].Path,sizeof(DrawAttr)); } DataLibRead(arch,(CharPtr)&gd->Options,sizeof(gd->Options)); for (i=0; ipAngle); i++) gd->pAngle[i]=DataLibReadVRecord(arch,NULL); gd->SpecialPoints=BSNew(0); DataLibRead(arch,(CharPtr)&un,sizeof(un)); gd->UndoNum=un ? un-1 : 0; if (un) { gd->UndoBuf=MemNew(ARRAYSIZE(UndoElem,UNDODEPTH)); DataLibRead(arch,(CharPtr)gd->UndoBuf,ARRAYSIZE(UndoElem,un)); } DataLibRead(arch,(CharPtr)&un,sizeof(un)); gd->UndoRNum=un ? un-1 : 0; if (un) { gd->UndoRBuf=MemNew(ARRAYSIZE(UndoRElem,UNDODEPTH)); DataLibRead(arch,(CharPtr)gd->UndoRBuf,ARRAYSIZE(UndoRElem,un)); } } ClassMember(void) WriteDescription(WinComDataPtr wcd, DataLibPtr arch) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Int2 i,j,un; DataLibWrite(arch,(CharPtr)&gd->FuncNum,sizeof(gd->FuncNum)); DataLibWrite(arch,(CharPtr)&gd->FuncCur,sizeof(gd->FuncCur)); for (i=0; iAxis); i++) { for (j=0; jAxis[i].pText); j++) if (!FuncIndex(j)) { DataLibWriteVRecord(arch,NULL,gd->Axis[i].pText[j], StrLen(gd->Axis[i].pText[j])+1); MemFree(gd->Axis[i].pText[j]); } for (j=0; jFuncNum; j++) { DataLibWriteVRecord(arch,NULL,gd->Axis[i].Funcs[j].pFunc, StrLen(gd->Axis[i].Funcs[j].pFunc)+1); MemFree(gd->Axis[i].Funcs[j].pFunc); } MemFree(gd->Axis[i].Funcs); DataLibWrite(arch,(CharPtr)gd->Axis[i].Prop,sizeof(gd->Axis[i].Prop)); } for (i=0; iFuncNum; i++) { DataLibWrite(arch,(CharPtr)&gd->Attr[i].Point,sizeof(DrawAttr)); DataLibWrite(arch,(CharPtr)&gd->Attr[i].Trace,sizeof(DrawAttr)); DataLibWrite(arch,(CharPtr)&gd->Attr[i].Path,sizeof(DrawAttr)); } MemFree(gd->Attr); DataLibWrite(arch,(CharPtr)&gd->Options,sizeof(gd->Options)); for (i=0; ipAngle); i++) { DataLibWriteVRecord(arch,NULL,gd->pAngle[i],StrLen(gd->pAngle[i])+1); MemFree(gd->pAngle[i]); } BSFree(gd->SpecialPoints); un=gd->UndoBuf ? gd->UndoNum+1 : 0; DataLibWrite(arch,(CharPtr)&un,sizeof(un)); DataLibWrite(arch,(CharPtr)gd->UndoBuf,ARRAYSIZE(UndoElem,un)); MemFree(gd->UndoBuf); un=gd->UndoRBuf ? gd->UndoRNum+1 : 0; DataLibWrite(arch,(CharPtr)&un,sizeof(un)); DataLibWrite(arch,(CharPtr)gd->UndoRBuf,ARRAYSIZE(UndoRElem,un)); MemFree(gd->UndoRBuf); } /******************************************************************** Translation of coordinates. 1. Math3dTo2d. Mathematical coordinates (x,y,z) in 3D space are translated to mathematical coordinates (u,v) in 2D space using orthogonal projection to a plane which is orthogonal to the vector given by {1,Theta,Phi} in the spherical coordinates. 2. Math2dToWin. The rectangle (Min{u},Min{v})-(Max{u},Max{v}) is mapped onto window's drawing area. This is the same as MathToWin for contw2dg. ********************************************************************/ Local(void) Math3dTo2d(FloatHiPtr xyz, FloatHiPtr uv, GraphicDataPtr gd); /* Makes a FloatHi number looking "good" */ #define VZERO 1e-10 /* x printed as '0' if abs(x)INT4_MAX /* Calculates tick value for axes with angle in [-PI/4,PI/4]+[3*PI/4,5*PI/4] */ Local(FloatHi) AutoTickHor(FloatHi min, FloatHi max, Int2 len, FloatHi cosa) { /* Embedded parameter of this part of the ArtificialIntellectX: The minimal horizontal spacing between two numbers. */ #define MININTVL (2*sysCharWidth*cosa) #define NO_MORE_THAN 20 /* No more intervals than this number */ FloatHi d,w; Int2 maxn,power,width,width0,i; Char buf[50]; if (cosa<0) cosa=-cosa; len*=cosa; if (len<0) len=-len; d=max-min; sprintf(buf,"%g",max); len+=StringWidth(buf)>>1; sprintf(buf,"%g",min); len+=StringWidth(buf)>>1; maxn=MIN(len/(StringWidth(buf)+MININTVL),NO_MORE_THAN); if (!maxn) maxn=1; if (OutOfRange(d)) return d/maxn; for (power=0; !IsMultiple10(d); power++) { if (OutOfRange(d)) return d/maxn/pow(10,power); else d*=10; } sprintf(buf,"%g",min); width0=StringWidth(buf)>>1; sprintf(buf,"%g",max); width0+=StringWidth(buf)>>1; for (; maxn; maxn--) { if (IsInteger(d/maxn)) { width=width0+maxn*MININTVL; for (i=1; i=len) break; } if (i==maxn) return d/maxn/pow(10,power); } } /* To be on the safe side. Control may comes here */ return (max-min)/2; #undef MININTVL #undef NO_MORE_THAN } /* Calculates tick value for axes with angle in [PI/4,3*PI/4]+[5*PI/4,7*PI/4] */ Local(FloatHi) AutoTickVert(FloatHi min, FloatHi max, Int2 len, FloatHi sina) { /* Embedded parameter of this part of the ArtificialIntellectZ: The minimal vertical spacing (2*sysLineHeight now). */ #define MININTVL (3*sysLineHeight/2*sina)/* Min allowable interval between lines */ #define NO_MORE_THAN 20 /* No more intervals than this number */ FloatHi d; Int2 maxn,power; if (sina<0) sina=-sina; len*=sina; if (len<0) len=-len; d=max-min; maxn=MIN((len+sysLineHeight)/(sysLineHeight+MININTVL),NO_MORE_THAN); if (!maxn) maxn=1; if (OutOfRange(d)) return d/maxn; for (power=0; !IsMultiple100(d); power++) { if (OutOfRange(d)) return d/maxn/pow(100,power); else d*=100; } for (; maxn; maxn--) { if (IsInteger(d/maxn)) return d/maxn/pow(100,power); } /* To be on the safe side. Control never comes here */ return (max-min)/2; #undef MININTVL #undef NO_MORE_THAN } /* Ensure an angle is in [0..2*PI) */ Local(FloatHi) Angle(FloatHi angle) { angle=fmod(angle,2*PI); if (angle<0) angle+=2*PI; return angle; } /* Ensure an angle is in [0..360] */ Local(FloatHi) NormilizeAngle(FloatHi angle) { angle=fmod(angle,360); if (angle<0) angle+=360; return angle; } /* Check limits along axis */ Local(void) CheckLimits(WinComDataPtr wcd) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; FloatHi min,max,tick,d,thetaphi; Int2 axis,angle; for (axis=0; axisAxis); axis++) { min=max=tick=0; /* for a case sscanf fails */ (ComputeExpr(gd->Axis[axis].pMin,&min) | /* not || */ ComputeExpr(gd->Axis[axis].pMax,&max) | /* not || */ ComputeExpr(gd->Axis[axis].pTick,&tick) ? Disable : Enable) (gd->teAxis[axis].prompt); gd->RAxis[axis].Tick=tick; d=max-min; if (d<0) { gd->RAxis[axis].Max=min; gd->RAxis[axis].Min=max; } else if (d==0) { gd->RAxis[axis].Min=min; gd->RAxis[axis].Max=min+1; } else { gd->RAxis[axis].Min=min; gd->RAxis[axis].Max=max; } } for (angle=0; anglepAngle); angle++) { thetaphi=45; /* default, used when error */ (ComputeExpr(gd->pAngle[angle],&thetaphi) ? Disable : Enable) (gd->teAngle[angle].prompt); thetaphi=PI*thetaphi/180; /* to radians */ gd->Options.Angle[angle]=Angle(thetaphi); } } #if _UNIX #define HOFF 1 /* difference from Windows: right and bottom are included */ #define VOFF 1 #else #define HOFF 0 #define VOFF 0 #endif /* Compute Deltas for MathToWin. */ Local(void) GetNumbers(WinComDataPtr wcd) { FloatHi xyz[3],uv[2]; Int2 i,j,k; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; /* As the user might set wrong min and/or max. we'll better check them */ CheckLimits(wcd); /* All axes */ /* Consts for 3D->2D translation: sin/cos of angles */ gd->sinTheta=sin(gd->Options.Theta); gd->cosTheta=cos(gd->Options.Theta); gd->sinPhi=sin(gd->Options.Phi); gd->cosPhi=cos(gd->Options.Phi); /* Consts for 2D->Win translation: Min/Max in mathematical 2D space (u,v) */ gd->uMin=gd->vMin=DBL_MAX; gd->uMax=gd->vMax=-DBL_MAX; for (i=0; i<2; i++) { xyz[0]=gd->RAxis[0].Limits[i]; for (j=0; j<2; j++) { xyz[1]=gd->RAxis[1].Limits[j]; for (k=0; k<2; k++) { xyz[2]=gd->RAxis[2].Limits[k]; Math3dTo2d(xyz,uv,gd); if (gd->uMin>uv[0]) gd->uMin=uv[0]; if (gd->uMaxuMax=uv[0]; if (gd->vMin>uv[1]) gd->vMin=uv[1]; if (gd->vMaxvMax=uv[1]; } } } /* Consts for 2D->Win translation: Deltas */ gd->DeltaU=(gd->Slate.right-1+HOFF-gd->Slate.left)/ (gd->uMax-gd->uMin); gd->DeltaV=(gd->Slate.top-gd->Slate.bottom+1-VOFF)/ (gd->vMax-gd->vMin); } /* Converts 2D mathematical coordinates (u,v) to window coordinates */ #define SM 20 Local(Int2) Math2dToWinU(FloatHi u, GraphicDataPtr gd) { FloatHi d; d=gd->Slate.left+gd->DeltaU*(u-gd->uMin); if (dSlate.left-SM; if (d>INT2_MAX) d=gd->Slate.right+SM; return round(d); } Local(Int2) Math2dToWinV(FloatHi v, GraphicDataPtr gd) { FloatHi d; d=gd->Slate.bottom-1+VOFF+gd->DeltaV*(v-gd->vMin); if (dSlate.top-SM; if (d>INT2_MAX) d=gd->Slate.bottom+SM; return round(d); } #undef SM /* Converts 3D math coords (x,y,z) to 2D math coords (u,v) */ #define x xyz[0] #define y xyz[1] #define z xyz[2] #define u uv[0] #define v uv[1] Local(void) Math3dTo2d(FloatHiPtr xyz, FloatHiPtr uv, GraphicDataPtr gd) { /* From TraX manual: u=x*gd->cosPhi+y*gd->sinPhi; v=(y*gd->cosPhi-x*gd->sinPhi)*gd->cosTheta+z*gd->sinTheta; */ u=-x*gd->sinPhi+y*gd->cosPhi; v=-(x*gd->cosPhi+y*gd->sinPhi)*gd->cosTheta+z*gd->sinTheta; } #undef x #undef y #undef z #undef u #undef v /* Converts 3D math coords (x,y,z) to window coords */ /* Has side effect: it leavs 2D point in global uv */ Local(FloatHi) uv[2]; /* intermediate point (on plane) from last call to Math3dToWin */ Local(void) Math3dToWin(FloatHi x, FloatHi y, FloatHi z, PointPtr pt, GraphicDataPtr gd) { FloatHi xyz[3]; xyz[0]=x; xyz[1]=y; xyz[2]=z; Math3dTo2d(xyz,uv,gd); pt->x=Math2dToWinU(uv[0],gd); pt->y=Math2dToWinV(uv[1],gd); } /* Converts window coordinates to 2D mathematical coordinates (u,v) */ Local(FloatHi) WinToMath2dU(Int2 x, GraphicDataPtr gd) { return (x-gd->Slate.left)/gd->DeltaU+gd->uMin; } Local(FloatHi) WinToMath2dV(Int2 y, GraphicDataPtr gd) { return (y-(gd->Slate.bottom-1+VOFF))/gd->DeltaV+gd->vMin; } #if MOUSE /* Converts window coordinates to mathematical coordinates */ Local(FloatHi) WinToMathX(Int2 x, GraphicDataPtr gd) { return gd->RAxis[0].Min+(x-gd->Slate.left)/gd->DeltaX; } Local(FloatHi) WinToMathY(Int2 y, GraphicDataPtr gd) { return gd->RAxis[1].Min+(y-gd->Slate.bottom+1-VOFF)/gd->DeltaY; } #endif /* MOUSE */ Local(Boolean) DrawLabel(WinComDataPtr wcd, Int2 axis, RectPtr pr); /* For the p1->p2 vector returns the displacement from p2 of the rectangle bounding the text attached to that mathematical point (scale number). The displacement is along the vector and does not depend on |p2-p1|. IMPORTANT: the displacement is for the upper left corner (0<=alpha<=PI/2) or bottom left corner (PI/2<=alpha<=PI). */ Local(FloatHi) DeltaR(PoinT p1, PoinT p2, FloatHi width, FloatHi height) { FloatHi alpha,d,sina,cosa,dR1,dR2; Int2 q; d=sqrt(pow(p1.x-p2.x,2)+pow(p1.y-p2.y,2)); sina=-(p2.y-p1.y)/d; cosa=(p2.x-p1.x)/d; /* Get the angle */ if (sina<=0) if (cosa<0) alpha=acos(-cosa); else alpha=PI+asin(sina); else alpha=acos(cosa); /* now 0<=alpha<=PI */ switch (q=alpha/(PI/4)) { case 0: /* 0<=alpha0) { *psin=-(p2.y-p1.y)/d; *pcos=(p2.x-p1.x)/d; if (*psin<=0) { *psin=-*psin; *pcos=-*pcos; } } else *psin=*pcos=0; return d; } /* Makes calculations needed to draw scales */ Local(void) CalculateScales(WinComDataPtr wcd) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; FloatHi xystep,zstep,xy,xymax,z,zmax,l,sina,cosa,e,ew,x,y; FloatHi width,height; RecT r; PoinT pt; Int2 i,wmax; Int2 ul,ut,ur,ub; Int2 ax; Boolean checknums[3]={FALSE,FALSE,FALSE}; Boolean checklab[3]={FALSE,FALSE,FALSE}; Boolean hc=gd->Hardcopy; /* is hardcopy requested for this window */ Boolean bc=gd->Axis[0].bScale || gd->Axis[0].bBox; Char buf[50]; SelectFont(SystemFont); ul=ut=ur=ub=0; if (bc) { if (hc) { fprintf(gd->HardFile,"/zAXIS {%g %g %g %g} def\n", gd->lhc[0].u,gd->lhc[0].v, gd->lhc[1].u,gd->lhc[1].v); for (ax=0; ax<2; ax++) /* 0-X, 1-Y */ fprintf(gd->HardFile,"/%cAXIS {%g %g %g %g} def\n","xy"[ax], gd->xyhc[ax][0].u,gd->xyhc[ax][0].v, gd->xyhc[ax][1].u,gd->xyhc[ax][1].v); } if (gd->Axis[0].bScale) { ub+=sysLineHeight+2*sysDescent; ut+=sysLineHeight+2*sysDescent; } else { ul=ur=sysCharWidth/2; ut=ub=sysLineHeight/2; } width=0; if (gd->Axis[0].bScale) { /* Z-axis */ if (!EqualPt(gd->l[0],gd->l[1])) checknums[2]=TRUE; zstep=gd->RAxis[2].Tick; if (zstep<=0 || zstep>gd->RAxis[2].Max-gd->RAxis[2].Min) zstep=AutoTickVert(gd->RAxis[2].Min,gd->RAxis[2].Max, gd->l[0].y+VOFF-gd->l[1].y,1.0); /* 1.0=sin(PI/2) */ gd->RAxis[2].Step=zstep; zmax=dtos(buf,"%g",gd->RAxis[2].Max); /* round it, if necessary */ if (hc) { fprintf(gd->HardFile,"/zNUMS {["); x=gd->RAxis[0].Limits[gd->ilx]; y=gd->RAxis[1].Limits[gd->ily]; } for (i=0; (z=dtos(buf,"%g",i*zstep+gd->RAxis[2].Min), z<=zmax); i++) { if (widthHardFile,"[%g %g (%s)]",uv[0],uv[1],buf); } if (i>100) break; /* if ymax-ymin is very large and step is specified */ } if (hc) fprintf(gd->HardFile,"]} def\n"); } width+=sysCharWidth; if (gd->Axis[0].bFunc) { checklab[2]=DrawLabel(wcd,3+2,&r); /* Z(2), don't draw(3) */ width+=r.right-r.left; } ul+=width; if (gd->Axis[0].bScale) { /* XY-axes */ for (ax=0; ax<2; ax++) { /* 0-X, 1-Y */ if (EqualPt(gd->xy[ax][0],gd->xy[ax][1])) continue; checknums[ax]=TRUE; xystep=gd->RAxis[ax].Tick; l=CalculateSinCos(gd->xy[ax][0],gd->xy[ax][1],&sina,&cosa); if (xystep<=0 || xystep>gd->RAxis[ax].Max-gd->RAxis[ax].Min) { xystep=ABS(gd->xy[ax][1].y-gd->xy[ax][0].y)xy[ax][1].x-gd->xy[ax][0].x) ? AutoTickHor (gd->RAxis[ax].Min,gd->RAxis[ax].Max,l,cosa) : AutoTickVert(gd->RAxis[ax].Min,gd->RAxis[ax].Max,l,sina); } gd->RAxis[ax].Step=xystep; xymax=dtos(buf,"%g",gd->RAxis[ax].Max); /* round it, if necessary */ height=ABS(cosa)*sysDescent+sysLineHeight; gd->xywidth[ax]=0; if (hc) { fprintf(gd->HardFile,"/%cFL %i def\n","xy"[ax],(int)(gd->xybottom[ax] && (ABS(sina)!=1))); fprintf(gd->HardFile,"/%cNUMS {[","xy"[ax]); } for (i=0; (xy=dtos(buf,"%g",i*xystep+gd->RAxis[ax].Min), xy<=xymax); i++) { width=ABS(sina)*sysCharWidth/4+StringWidth(buf); e=gd->xy[ax][0].x+(xy-gd->RAxis[ax].Min)/(gd->RAxis[ax].Max-gd->RAxis[ax].Min)* (gd->xy[ax][1].x-gd->xy[ax][0].x)+ cosa*DeltaR(gd->xy[ax][0],gd->xy[ax][1],width,height); ew=e+width-(gd->r[0].x+ur); if (ew>0) ur+=ew; ew=gd->l[0].x-ul-e; if (ew>0) ul+=ew; wmax=width*sina+height*ABS(cosa); if (gd->xywidth[ax]xywidth[ax]=wmax; if (hc) { e=(i*gd->RAxis[ax].Step)/(gd->RAxis[ax].Max-gd->RAxis[ax].Min); fprintf(gd->HardFile,"[%g %g (%s)]", gd->xyhc[ax][0].u+e*(gd->xyhc[ax][1].u-gd->xyhc[ax][0].u), gd->xyhc[ax][0].v+e*(gd->xyhc[ax][1].v-gd->xyhc[ax][0].v), buf); } if (i>100) break; /* if xmax-xmin is very large and step is specified */ } if (hc) fprintf(gd->HardFile,"]} def\n"); } } else { gd->xywidth[0]=gd->xywidth[1]=0; if (hc) for (ax=0; ax<2; ax++) { /* 0-X, 1-Y */ if (EqualPt(gd->xy[ax][0],gd->xy[ax][1])) continue; CalculateSinCos(gd->xy[ax][0],gd->xy[ax][1],&sina,&cosa); fprintf(gd->HardFile,"/%cFL %i def\n","xy"[ax],(int)(gd->xybottom[ax] && (ABS(sina)!=1))); fprintf(gd->HardFile,"/xNUMS {[]} def\n/yNUMS {[]} def\n/zNUMS {[]} def\n"); } } if (gd->Axis[0].bFunc) { /* XY labels */ for (ax=0; ax<2; ax++) { /* 0-X, 1-Y */ checklab[ax]=DrawLabel(wcd,3+ax,&r); /* X/Y(ax), don't draw(3) */ ew=(gd->l[0].x-ul)-r.left; if (ew>0) ul+=ew; ew=r.right-(gd->r[0].x+ur); if (ew>0) ur+=ew; ew=((gd->xybottom[ax] ? MIN(gd->xy[1-ax][0].y,gd->xy[1-ax][1].y) : MIN(gd->xy[ax][0].y,gd->xy[ax][1].y))-ut)-r.top; if (ew>0) ut+=ew; ew=r.bottom-((gd->xybottom[ax] ? MAX(gd->xy[ax][0].y,gd->xy[ax][1].y) : MIN(gd->xy[1-ax][0].y,gd->xy[1-ax][1].y))+ub); if (ew>0) ub+=ew; } } ur+=sysCharWidth/4; } else { ul=ur=sysCharWidth/2; ut=ub=sysLineHeight/2; } if (gd->Axis[0].bAxis && gd->Axis[0].bFunc && !bc) { RecT r,rr,rl[3],ra[3]; for (i=0; i<3; i++) { checklab[i]=DrawLabel(wcd,3+i,rl+i); /* X/Y/Z(i), don't draw(3) */ if (!checklab[i]) ra[i]=rl[i]; } UnionRect(rl+0,rl+1,&r); UnionRect(rl+2,&r,&r); if (checklab[0]) LoadRect(ra+0,gd->xa[0].x,gd->xa[0].y,gd->xa[1].x,gd->xa[1].y); if (checklab[1]) LoadRect(ra+1,gd->ya[0].x,gd->ya[0].y,gd->ya[1].x,gd->ya[1].y); if (checklab[2]) LoadRect(ra+2,gd->za[0].x,gd->za[0].y,gd->za[1].x,gd->za[1].y); UnionRect(ra+0,ra+1,&rr); UnionRect(ra+2,&rr,&rr); ew=(rr.left-ul)-r.left; if (ew>0) ul+=ew; ew=(rr.top-ut)-r.top; if (ew>0) ut+=ew; ew=r.right-(rr.right+ur); if (ew>0) ur+=ew; ew=r.bottom-(rr.bottom+ub); if (ew>0) ub+=ew; if (hc) { if (checklab[0]) fprintf(gd->HardFile,"/xAXIS {%g %g %g %g} def\n", gd->xahc[0].u,gd->xahc[0].v, gd->xahc[1].u,gd->xahc[1].v); if (checklab[1]) fprintf(gd->HardFile,"/yAXIS {%g %g %g %g} def\n", gd->yahc[0].u,gd->yahc[0].v, gd->yahc[1].u,gd->yahc[1].v); if (checklab[2]) fprintf(gd->HardFile,"/zAXIS {%g %g %g %g} def\n", gd->zahc[0].u,gd->zahc[0].v, gd->zahc[1].u,gd->zahc[1].v); } } UpsetRect(&gd->Slate,ul,ut,ur,ub); gd->Slate.right--; gd->Slate.right+=HOFF; gd->Slate.bottom--; gd->Slate.bottom+=VOFF; if (hc) { fprintf(gd->HardFile,"/LABTYPE %i def %% 1-box,0-axes\n",(int)bc); fprintf(gd->HardFile,"/GP?MW { [0 0 0 0] /MARGINS [0 0 0 0] def\n20 dict begin\n/GP?M [0 0 0 0] def\n"); if (gd->Axis[0].bScale) for (i=0; iHardFile,"%cCheckNums\n","xyz"[i]); if (gd->Axis[0].bFunc) for (i=0; iHardFile,"%cCheckLab\n","xyz"[i]); fprintf(gd->HardFile,"end SETMARGINS} bind def\n/GP?M GP?MW def\n\n"); } } #undef HOFF #undef VOFF Local(void) lRefreshScale(WinComDataPtr wcd) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Select(gd->paPanel); /* Recalulate scales */ GetPosition(gd->paPanel,&gd->Slate); CalculateScales(wcd); /* Update panel */ Redraw(gd->paPanel); } /* Refresh scales after user pressed invisible DefaultButton */ Callback(void) RefreshScale(ButtoN b) { WinComDataPtr wcd=GetComDataC(b); lRefreshScale(wcd); UndoRecord(wcd); UndoRRecord(wcd); } Callback(void) ActProc(TexT t) { SetTitle(t,""); /* ignore everything */ } Callback(void) SelectProc(TexT t) { size_t l; l=TextLength(t); SelectText(t,(Int2)l,(Int2)l); } /* Limits SpeedBar common callback */ Callback(void) LimitsProc(TexT t) { WinComDataPtr wcd=GetComDataC(t); GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Int2 i,j; for (i=0; iteAxis); i++) for (j=0; jteAxis[i].teLimits); j++) if (t==gd->teAxis[i].teLimits[j]) { GetTitleAndSave(t,&gd->Axis[i].pText[j]); GetNumbers(wcd); return; } } /* Angles SpeedBar common callback */ Callback(void) AnglesProc(TexT t) { WinComDataPtr wcd=GetComDataC(t); GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Int2 i; for (i=0; iteAngle); i++) if (t==gd->teAngle[i].teAngle) { GetTitleAndSave(t,&gd->pAngle[i]); GetNumbers(wcd); return; } } #if SCROLL_ANGLES /* Angles SpeedBar common callback */ #if _WIN #pragma argsused #endif Callback(void) AnglesBarProc(BaR b, GraphiC graphic, Int2 new, Int2 old) { WinComDataPtr wcd=GetComDataC(b); GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; FloatHi a; CharPtr p; size_t l; Int2 i; for (i=0; iteAngle); i++) if (b==gd->teAngle[i].baAngle) { l=TextLength(gd->teAngle[i].teAngle)+10; p=MemNew(l); GetTitle(gd->teAngle[i].teAngle,p,l); sscanf(p,"%lg",&a); a+=new-old; sprintf(p,"%g",NormilizeAngle(a)); SetTitle(gd->teAngle[i].teAngle,p); MemFree(p); GetTitleAndSave(gd->teAngle[i].teAngle,&gd->pAngle[i]); CorrectBarValue(b,1); GetNumbers(wcd); lRefreshScale(wcd); return; } } #endif /* SCROLL_ANGLES */ /* Get rectangle surrounding axis's lable and draw it */ /* Puts it to *pr (if pr!=NULL) */ /* Does not draw if axis>=3 */ /* Returns FALSE if label cannot be drawn */ Local(Boolean) DrawLabel(WinComDataPtr wcd, Int2 axis, RectPtr pr) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; #define MAXCHAR (Int2)20 FloatHi sina,cosa; RecT r,rw; PoinT p1,p2; CharPtr p; Int2 width,d; Int2 x,y; Char c; Boolean hc=gd->Hardcopy; /* Hardcopy */ Boolean dontdraw=axis>=3; Boolean noaxis; Boolean box=gd->Axis[0].bScale || gd->Axis[0].bBox; if (dontdraw) axis-=3; SelectFont(SystemFont); if (!pr) pr=&rw; x=(gd->Slate.left+gd->Slate.right)>>1; y=(gd->Slate.top+gd->Slate.bottom)>>1; LoadRect(pr,x,y,x,y); /* default */ GetPosition(gd->paPanel,&r); p=gd->Axis[axis].Funcs[gd->FuncCur].pFunc; width=(StrLen(p)<=MAXCHAR) ? StringWidth(p) : TextWidth(p,MAXCHAR); switch (axis) { case 0: /* X */ case 1: /* Y */ if (gd->Axis[0].bAxis && !box) { if (axis==0) { p1=gd->xa[0]; p2=gd->xa[1]; noaxis=!gd->xay; } else { p1=gd->ya[0]; p2=gd->ya[1]; noaxis=!gd->yay; } if (noaxis || EqualPt(p1,p2)) return FALSE; else { FloatHi d,dr; FloatHi w=(width+sysCharWidth)/2,h=(sysLineHeight+sysDescent)/2; Int2 x,y; /* don't call CalculateSinCos: it reduces angle to [0,PI] */ d=sqrt(pow(p1.x-p2.x,2)+pow(p1.y-p2.y,2)); sina=(p1.y-p2.y)/d; cosa=(p2.x-p1.x)/d; dr=w*ABS(cosa)+h*ABS(sina); x=p2.x+dr*cosa; y=p2.y-dr*sina; if (dontdraw) LoadRect(pr,x-w,y-h,x+w,y+h); else LoadRect(pr,x-width/2,y-sysLineHeight/2,x+width/2,y+sysLineHeight/2); } } else { if (EqualPt(gd->xy[axis][0],gd->xy[axis][1])) return FALSE; CalculateSinCos(gd->xy[axis][0],gd->xy[axis][1],&sina,&cosa); if (sina==0) cosa=gd->xybottom[axis] ? 1 : -1; p1=gd->xy[axis][0]; AddPt(gd->xy[axis][1],&p1); MultPt(&p1,0.5); LoadPt(&p2,sina*gd->xywidth[axis],cosa*gd->xywidth[axis]); AddPt(p2,&p1); p1.x+=sina*sysCharWidth/2; if (gd->xybottom[axis] && ABS(sina)!=1) LoadRect(pr,p1.x,p1.y,p1.x+width,p1.y+sysLineHeight); else LoadRect(pr,p1.x,p1.y-sysLineHeight,p1.x+width,p1.y); } break; case 2: /* Z */ if (gd->Axis[0].bAxis && !box) { p1=gd->za[0]; p2=gd->za[1]; if (!gd->zay || EqualPt(p1,p2)) return FALSE; else { pr->left=p1.x-width/2; pr->right=p1.x+width/2; if (p1.y>p2.y) pr->top=p2.y-(sysLineHeight+sysDescent); else pr->top=p2.y; pr->bottom=pr->top+sysLineHeight; } } else { d=((gd->l[0].y+gd->l[1].y)>>1)-sysLineHeight/2; LoadRect(pr,r.left,d, r.left+width+sysCharWidth/2,d+sysLineHeight); OffsetRect(pr,sysCharWidth/2,0); } break; } if (dontdraw) { if (hc) fprintf(gd->HardFile,"/%cLAB (%.*s) def\n","xyz"[axis],(int)MAXCHAR,p); return TRUE; } if (StrLen(p)>MAXCHAR) { c=p[MAXCHAR]; p[MAXCHAR]='\0'; } else c='\0'; ColorSet((gd->FuncNum?gd->Attr:gd->SaveAttr)[gd->FuncCur].Point.color); lString(pr->left,pr->bottom-sysDescent,p); if (hc) fprintf(gd->HardFile,"%cDrawLab\n","xyz"[axis]); if (c) p[MAXCHAR]=c; return TRUE; #undef MAXCHAR } /* Redraws labels */ Local(void) RedrawLabels(WinComDataPtr wcd, Int2 incr) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; RecT rold[3],rnew; Int2 i; Select(gd->paPanel); for (i=0; i<3; i++) DrawLabel(wcd,i,rold+i); gd->FuncCur+=incr; for (i=0; i<3; i++) { DrawLabel(wcd,i,&rnew); UnionRect(&rnew,rold+i,&rnew); InvalRect(&rnew); } Update(); } /*----------------------------------------------*/ /* Palette SpeedBar support (in Graphic window) */ #if MYSWITCH Callback(void) PalNumProc(GraphiC sw, Int2 newval, Int2 oldval) { #else Callback(void) PalNumProc(SwitcH sw, Int2 newval, Int2 oldval) { #endif Int2 i; WinComDataPtr wcd=GetComDataC(sw); GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; RedrawLabels(wcd,newval-oldval); /* thsi sets gd->FuncCur */ for (i=0; iAxis); i++) SetTitle(gd->teAxis[i].prompt,gd->Axis[i].Funcs[gd->FuncCur].pFunc); Redraw(gd->paSample); } /* Draw palette */ Callback(void) PalDrawProc(PaneL pnl) { RecT r; Int2 w,i,n; Select(pnl); GetPosition(pnl,&r); n=ColorNumber(); if (!(w=(r.right-r.left)/n)) w=1; for (i=0; iPrivate; FuncAttr Attr; RecT r; Color col; Select(pnl); GetPosition(pnl,&r); col=floor((pt.x-r.left)/((r.right-r.left)/ColorNumber())); Attr=gd->Attr[gd->FuncCur]; /* to simplify */ if (Attr.Trace.style>0 && Attr.Trace.color==Attr.Point.color) Attr.Trace.color=col; if (Attr.Path.style>0 && Attr.Path.color==Attr.Point.color) Attr.Path.color=col; Attr.Point.color=col; gd->Attr[gd->FuncCur]=Attr; Redraw(gd->paSample); } Callback(void) PalSampProc(PaneL pnl) { WinComDataPtr wcd=GetComDataC(pnl); GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; RecT r; Select(pnl); GetPosition(pnl,&r); ColorSet(gd->Attr[gd->FuncCur].Point.color); PaintRect(&r); } /*-----------------------------------------------------*/ /* Graphic panel callbacks: draw, click, drag, release */ Local(Int2) ves[4][4][2]={ /* vertical edges: left-front-right-back */ {{1,0},{1,1},{0,1},{0,0}}, /* I quadrant */ {{1,1},{0,1},{0,0},{1,0}}, /* II quadrant */ {{0,1},{0,0},{1,0},{1,1}}, /* III quadrant */ {{0,0},{1,0},{1,1},{0,1}} /* IV quadrant */ }; /* used to find out X and Y edges for scaling in the window */ typedef struct { /* 0-left,1-front,2-right,3-back */ Char x1,x2,y1,y2,xbottom; } edgesXY; Local(edgesXY) edgesxy[4][4]={ /* Theta x Phi */ /* Theta: I quadrant */ {{2,1,3,2,1},{2,3,2,1,0},{1,2,2,3,1},{3,2,1,2,0}}, /* Theta: II quadrant */ {{2,1,3,2,0},{2,3,2,1,1},{1,2,2,3,0},{3,2,1,2,1}}, /* Theta: III quadrant */ {{2,3,1,2,0},{2,1,2,3,1},{3,2,2,1,0},{1,2,3,2,1}}, /* Theta: IV quadrant */ {{2,3,1,2,1},{2,1,2,3,0},{3,2,2,1,1},{1,2,3,2,0}} }; Local(Boolean) ZeroIn(Int2 i, GraphicDataPtr gd) { return gd->RAxis[i].Min*gd->RAxis[i].Max<=0; } Local(void) hcSpLine(Point2dPtr pt1, Point2dPtr pt2, GraphicDataPtr gd) { fprintf(gd->HardFile,"%g %g %g %g GSLINE\n",pt1->u,pt1->v,pt2->u,pt2->v); } Local(void) BoundingBox(Boolean draw, GraphicDataPtr gd) { PointPtr pp[4]; Point2dPtr pphc[4]; Int2 qv,qh; /* quadrants where Theta and Phi are */ Int2 i,ix,iy,tx,ty; Boolean Hc=gd->Hardcopy; Boolean hc=draw && Hc; qh=Angle(gd->Options.Phi)/(PI/2); qv=Angle(gd->Options.Theta)/(PI/2); ix=qv; iy=qh; /* Vertical edges */ gd->ilx=ves[qh][0][0]; gd->ily=ves[qh][0][1]; gd->irx=ves[qh][2][0]; gd->iry=ves[qh][2][1]; if ((qv==2) || (qv==3)) qh=(qh+2)%4; gd->ifx=ves[qh][1][0]; gd->ify=ves[qh][1][1]; gd->ibx=ves[qh][3][0]; gd->iby=ves[qh][3][1]; /* Top/Bottom surface */ gd->usurface=(qv==0) || (qv==3); /* Compute window coordinates of vertical edges */ for (i=0; i<2; i++) { Math3dToWin(gd->RAxis[0].Limits[gd->ibx], gd->RAxis[1].Limits[gd->iby], gd->RAxis[2].Limits[i],gd->b+i,gd); gd->bhc[i].u=uv[0]; gd->bhc[i].v=uv[1]; Math3dToWin(gd->RAxis[0].Limits[gd->ifx], gd->RAxis[1].Limits[gd->ify], gd->RAxis[2].Limits[i],gd->f+i,gd); gd->fhc[i].u=uv[0]; gd->fhc[i].v=uv[1]; Math3dToWin(gd->RAxis[0].Limits[gd->ilx], gd->RAxis[1].Limits[gd->ily], gd->RAxis[2].Limits[i],gd->l+i,gd); gd->lhc[i].u=uv[0]; gd->lhc[i].v=uv[1]; Math3dToWin(gd->RAxis[0].Limits[gd->irx], gd->RAxis[1].Limits[gd->iry], gd->RAxis[2].Limits[i],gd->r+i,gd); gd->rhc[i].u=uv[0]; gd->rhc[i].v=uv[1]; } /* Eges for scaling */ if (gd->Axis[0].bScale || gd->Axis[0].bBox || gd->Axis[0].bAxis) { tx=(int)((Boolean)edgesxy[ix][iy].xbottom != (qv==0 || qv==1)); ty=1-tx; /* Set win coords */ pp[0]=gd->l; /* the order must be as in edgesXY */ pp[1]=gd->f; pp[2]=gd->r; pp[3]=gd->b; gd->xy[0][0]=pp[edgesxy[ix][iy].x1][tx]; gd->xy[0][1]=pp[edgesxy[ix][iy].x2][tx]; gd->xy[1][0]=pp[edgesxy[ix][iy].y1][ty]; gd->xy[1][1]=pp[edgesxy[ix][iy].y2][ty]; gd->xybottom[0]=(Boolean)edgesxy[ix][iy].xbottom; gd->xybottom[1]=!gd->xybottom[0]; /* Set 2d coords */ pphc[0]=gd->lhc; /* the order must be as in edgesXY */ pphc[1]=gd->fhc; pphc[2]=gd->rhc; pphc[3]=gd->bhc; gd->xyhc[0][0]=pphc[edgesxy[ix][iy].x1][tx]; gd->xyhc[0][1]=pphc[edgesxy[ix][iy].x2][tx]; gd->xyhc[1][0]=pphc[edgesxy[ix][iy].y1][ty]; gd->xyhc[1][1]=pphc[edgesxy[ix][iy].y2][ty]; } if (gd->Axis[0].bAxis) { /* X */ gd->xay=ZeroIn(1,gd) && ZeroIn(2,gd); if (gd->xay) for (i=0; i<2; i++) { Math3dToWin(gd->RAxis[0].Limits[i],0,0,gd->xa+i,gd); gd->xahc[i].u=uv[0]; gd->xahc[i].v=uv[1]; } /* Y */ gd->yay=ZeroIn(0,gd) && ZeroIn(2,gd); if (gd->yay) for (i=0; i<2; i++) { Math3dToWin(0,gd->RAxis[1].Limits[i],0,gd->ya+i,gd); gd->yahc[i].u=uv[0]; gd->yahc[i].v=uv[1]; } /* Z */ gd->zay=ZeroIn(0,gd) && ZeroIn(1,gd); if (gd->zay) for (i=0; i<2; i++) { Math3dToWin(0,0,gd->RAxis[2].Limits[i],gd->za+i,gd); gd->zahc[i].u=uv[0]; gd->zahc[i].v=uv[1]; } } if (draw) { /* Back vertical edge */ /* Front vertical edge */ DrawLine(gd->f[0],gd->f[1]); /* Left vertical edge */ DrawLine(gd->l[0],gd->l[1]); /* Right vertical edge */ DrawLine(gd->r[0],gd->r[1]); /* Hardcopy */ if (hc) { fprintf(gd->HardFile,"/GBBOX {\n"); hcSpLine(gd->fhc+0,gd->fhc+1,gd); hcSpLine(gd->lhc+0,gd->lhc+1,gd); hcSpLine(gd->rhc+0,gd->rhc+1,gd); } /* edges from the upper surface */ if (gd->usurface) { DrawLine(gd->l[1],gd->b[1]); DrawLine(gd->l[1],gd->f[1]); DrawLine(gd->r[1],gd->b[1]); DrawLine(gd->r[1],gd->f[1]); if (hc) { hcSpLine(gd->lhc+1,gd->bhc+1,gd); hcSpLine(gd->lhc+1,gd->fhc+1,gd); hcSpLine(gd->rhc+1,gd->bhc+1,gd); hcSpLine(gd->rhc+1,gd->fhc+1,gd); } } else { DrawLine(gd->l[1],gd->f[1]); DrawLine(gd->r[1],gd->f[1]); if (hc) { hcSpLine(gd->lhc+1,gd->fhc+1,gd); hcSpLine(gd->rhc+1,gd->fhc+1,gd); } } /* edges from the bottom surface */ if (gd->usurface) { DrawLine(gd->l[0],gd->f[0]); DrawLine(gd->r[0],gd->f[0]); if (hc) { hcSpLine(gd->lhc+0,gd->fhc+0,gd); hcSpLine(gd->rhc+0,gd->fhc+0,gd); } } else { DrawLine(gd->l[0],gd->b[0]); DrawLine(gd->l[0],gd->f[0]); DrawLine(gd->r[0],gd->b[0]); DrawLine(gd->r[0],gd->f[0]); if (hc) { hcSpLine(gd->lhc+0,gd->bhc+0,gd); hcSpLine(gd->lhc+0,gd->fhc+0,gd); hcSpLine(gd->rhc+0,gd->bhc+0,gd); hcSpLine(gd->rhc+0,gd->fhc+0,gd); } } /* Hardcopy */ if (hc) fprintf(gd->HardFile,"} bind def\n"); } } Callback(void) DrawProc(PaneL panel) { WinComDataPtr wcd=GetComDataC(panel); GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; FloatHi xy,x,y,z,xymax,zmax,d; FloatHi sina,cosa,asina,acosa,dR,dv,dh; FloatHi w,h; DrawAttr attr; RecT r; PoinT pt,pt1; Int2 i; Int2 ax; Boolean scale; Boolean hc; /* is hardcopy requested for this window */ Boolean bbox=gd->Axis[0].bScale || gd->Axis[0].bAxis || gd->Axis[0].bBox || gd->Axis[0].bProj; Char buf[50]; Select(panel); #ifdef INENTRYX /* Always draw ==> never return! */ /* Were we asked to ignore? */ if (wcd->flags&WFL_DONT_REDRAW) { /* Yes, we were */ return; } #endif #if _WIN /* Windows NT: without this doesn't redraw the whole panel after resize */ if (wcd->flags&WFL_RESIZE) ResetClip(); #endif /* _WIN */ /* To block fetching and dispatching Expose events for other panels in the window caused by call to Disable/Enable made from GetNumbers() */ ProcessUpdatesFirst(FALSE); SelectFont(SystemFont); hc=gd->Hardcopy; scale=!(gd->flags&DONT_SCALE); if (scale) { gd->Hardcopy=FALSE; GetPosition(panel,&gd->Slate); /* first GetNumbers&CalculateScales call does not take into account scales, if any */ GetNumbers(wcd); if (bbox) BoundingBox(FALSE,gd); CalculateScales(wcd); GetNumbers(wcd); GetPosition(panel,&gd->Slate); if (bbox) BoundingBox(FALSE,gd); if (!(wcd->flags&WFL_DONT_REDRAW)) gd->Hardcopy=hc; CalculateScales(wcd); GetNumbers(wcd); gd->Hardcopy=hc; } /* Clear the panel */ ColorSet(wcd->Background); GetPosition(panel,&r); PaintRect(&r); InvertColors(); attr.width=1; attr.style=1; /* solid */ attr.color=wcd->Foreground; SetCurrentPen(&attr); MoveTo(r.left,r.top); LineTo(r.right,r.top); if (bbox) BoundingBox(FALSE,gd); /*** if (hc) fprintf(gd->HardFile,"GFRAME\n");***/ /* Scales */ if (gd->Axis[0].bScale) { /* Z */ if (!EqualPt(gd->l[0],gd->l[1])) { DrawLine(gd->l[0],gd->l[1]); if (hc) hcSpLine(gd->lhc+0,gd->lhc+1,gd); zmax=dtos(buf,"%g",gd->RAxis[2].Max); /* round it, if necessary */ x=dtos(buf,"%g",gd->RAxis[0].Limits[gd->ilx]); /* round it, if necessary */ y=dtos(buf,"%g",gd->RAxis[1].Limits[gd->ily]); /* round it, if necessary */ d=sqrt(pow(gd->f[0].x-gd->l[0].x,2)+pow(gd->f[0].y-gd->l[0].y,2)); if (d) { dv=(gd->f[0].y-gd->l[0].y)/d; dh=(gd->f[0].x-gd->l[0].x)/d; } else dv=dh=0; for (i=0; (z=dtos(buf,"%g",i*gd->RAxis[2].Step+gd->RAxis[2].Min),z<=zmax); i++) { Math3dToWin(x,y,z,&pt,gd); /* leavs 2D point in uv[] */ lString(gd->Slate.left-StringWidth(buf)-(sysCharWidth/4), pt.y+(sysAscent>>1),buf); lLine(pt.x,pt.y,pt.x+(sysCharWidth/2)*dh,pt.y+(sysCharWidth/2)*dv); if (i>100) break; /* if zmax-zmin is very large and step is specified */ } if (hc) fprintf(gd->HardFile,"/zSD {%g %g %g %g} def\nzDrawNums\n", gd->lhc[0].u,gd->lhc[0].v, gd->fhc[0].u,gd->fhc[0].v); } /* X and Y */ for (ax=0; ax<2; ax++) { if (EqualPt(gd->xy[ax][0],gd->xy[ax][1])) continue; DrawLine(gd->xy[ax][0],gd->xy[ax][1]); if (hc) hcSpLine(gd->xyhc[ax]+0,gd->xyhc[ax]+1,gd); xymax=dtos(buf,"%g",gd->RAxis[ax].Max); /* round it, if necessary */ CalculateSinCos(gd->xy[ax][0],gd->xy[ax][1],&sina,&cosa); asina=ABS(sina); acosa=ABS(cosa); w=asina*sysCharWidth/4; h=acosa*sysDescent; pt=gd->r[0]; if (EqualPt(gd->xy[ax][0],gd->f[0]) || EqualPt(gd->xy[ax][0],gd->f[1]) || EqualPt(gd->xy[ax][1],gd->f[0]) || EqualPt(gd->xy[ax][1],gd->f[1]) ) pt1=gd->r[1]; else pt1=gd->f[0]; dv=pt.y-pt1.y; dh=pt.x-pt1.x; d=(dh||dv) ? (sysCharWidth/2)/sqrt((FloatHi)dh*dh+(FloatHi)dv*dv) : 0; dv*=d; dh*=d; dv=ABS(dv); if (gd->xybottom[ax]) dv=-dv; dh=-ABS(dh); for (i=0; (xy=dtos(buf,"%g",i*gd->RAxis[ax].Step+gd->RAxis[ax].Min),xy<=xymax); i++) { pt=gd->xy[ax][1]; SubPt(gd->xy[ax][0],&pt); /* pt=x2-x1 */ MultPt(&pt,(i*gd->RAxis[ax].Step)/(gd->RAxis[ax].Max-gd->RAxis[ax].Min)); AddPt(gd->xy[ax][0],&pt); if (gd->xybottom[ax] && asina!=1) { dR=DeltaR(gd->xy[ax][0],gd->xy[ax][1],w+StringWidth(buf),sysLineHeight); lString(pt.x+cosa*dR+w,pt.y-(sina*dR-sysLineHeight),buf); } else { dR=DeltaR(gd->xy[ax][0],gd->xy[ax][1],w+StringWidth(buf),h+sysLineHeight); lString(pt.x+cosa*dR+w,pt.y-(sina*dR)-h,buf); } lLine(pt.x,pt.y,pt.x+dh,pt.y+dv); if (i>100) break; /* if xmax-xmin is very large and step is specified */ } if (hc) { pt1.x=pt.x+100*dh; pt1.y=pt.y+100*dv; fprintf(gd->HardFile,"/%cSD {%g %g %g %g} def\n","xy"[ax], WinToMath2dU(pt.x,gd),WinToMath2dV(pt.y,gd), WinToMath2dU(pt1.x,gd),WinToMath2dV(pt1.y,gd)); fprintf(gd->HardFile,"%cDrawNums\n","xy"[ax]); } } } /* Draw axes */ if (gd->Axis[0].bAxis) { /* X */ if (gd->xay) { DrawLine(gd->xa[0],gd->xa[1]); if (hc) hcSpLine(gd->xahc+0,gd->xahc+1,gd); } /* Y */ if (gd->yay) { DrawLine(gd->ya[0],gd->ya[1]); if (hc) hcSpLine(gd->yahc+0,gd->yahc+1,gd); } /* Z */ if (gd->zay) { DrawLine(gd->za[0],gd->za[1]); if (hc) hcSpLine(gd->zahc+0,gd->zahc+1,gd); } } /* Draw bounding box */ if (gd->Axis[0].bBox) { BoundingBox(TRUE,gd); if (hc) fprintf(gd->HardFile,"GBBOX\n\n"); } /* Axes names */ if (gd->Axis[0].bFunc) for (i=0; iAxis); i++) DrawLabel(wcd,i,NULL); /* Unblock fetching and dispatching Expose events */ ProcessUpdatesFirst(TRUE); } Local(void) DrawMarqueeBox(PaneL panel) { WinComDataPtr wcd=GetComDataC(panel); GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Select(panel); ColorSet(wcd->Foreground); BoundingBox(TRUE,gd); /* gd->Hardcopy==FLASE! */ } Callback(void) ClickProc(PaneL panel, PoinT pt) { WinComDataPtr wcd=GetComDataC(panel); GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; gd->ptClick.x=-100; if (ccd.Computing) { /* Computing is in progress - ignore */ return; } if (PtInRect(pt,&gd->Slate)) { ResetClip(); gd->ptClick=pt; gd->bDrag=FALSE; gd->saveTheta=gd->Options.Theta; gd->savePhi=gd->Options.Phi; } } Callback(void) DragProc(PaneL panel, PoinT pt) { WinComDataPtr wcd=GetComDataC(panel); GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; FloatHi f[2]; RecT r; Int2 i; Char buf[20]; if (gd->ptClick.x<0) return; /* This check ensures a call was made not due to activating the window by mouse (Windows: if another window is active then the first mouse click results to call to drag callback) */ if (PtInRect(pt,&gd->Slate)) { if (gd->bDrag) { InvertMode(); DrawMarqueeBox(panel); f[0]=gd->saveTheta+(pt.y-gd->ptClick.y)*2*PI/(gd->Slate.top-gd->Slate.bottom+1); f[1]=gd->savePhi+(pt.x-gd->ptClick.x)*2*PI/(gd->Slate.left-gd->Slate.right+1); for (i=0; i<2; i++) { sprintf(buf,"%g",NormilizeAngle(f[i]*180/PI)); if (gd->Axis[0].bAngles) SetTitle(gd->teAngle[i].teAngle,buf); MemFree(gd->pAngle[i]); gd->pAngle[i]=StringSave(buf); } GetNumbers(wcd); } else { gd->bDrag=TRUE; ColorSet(wcd->Background); GetPosition(panel,&r); PaintRect(&r); ColorSet(wcd->Foreground); } InvertMode(); DrawMarqueeBox(panel); } } Callback(void) ReleaseProc(PaneL panel, PoinT pt) { WinComDataPtr wcd=GetComDataC(panel); GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; #ifdef MOUSE_PICK FloatHi x; FloatHiPtr vp; Uint2 id; Uint1 loc_class; #endif FilePtr curvePtr; Int2 spNum; PoinT spCoord; Int2 i; Char buf[20]; Boolean goon; if (gd->ptClick.x<0) return; /* click was outside of drawing rectangle */ if (gd->bDrag) { /* Drag was called - change scales */ InvertMode(); DrawMarqueeBox(panel); if (PtInRect(pt,&gd->Slate)) { /* Change angles */ RefreshScale(gd->buRefr); } else { /* Release outside the Slate, don't change */ gd->Options.Theta=gd->saveTheta; gd->Options.Phi=gd->savePhi; for (i=0; i<2; i++) { sprintf(buf,"%g",NormilizeAngle(gd->Options.Angle[i]*180/PI)); if (gd->Axis[0].bAngles) SetTitle(gd->teAngle[i].teAngle,buf); MemFree(gd->pAngle[i]); gd->pAngle[i]=StringSave(buf); } } GetNumbers(wcd); Redraw(gd->paPanel); } else { /* Click-Hold-Release at the same place - select a point */ /* 1. Look if a special point was pointed out */ BSSeek(gd->SpecialPoints,0,SEEK_SET); goon=TRUE; while (goon && BSRead(gd->SpecialPoints,&curvePtr,sizeof(curvePtr))) { while (goon) { BSRead(gd->SpecialPoints,&spNum,sizeof(spNum)); if (spNum==-1) break; BSRead(gd->SpecialPoints,&spCoord,sizeof(spCoord)); if (PtNearSpecial(pt,spCoord)) goon=FALSE; } } BSSeek(gd->SpecialPoints,0,SEEK_END); if (!goon) { if (SetSpecialPoint(curvePtr,spNum)) return; } #ifdef MOUSE_PICK /* 2. Try to set coordinates of initial point */ if (FBStatus(-1) && gd->flags&MOUSE_PICK) if (gd->FuncNum==1) { goon=TRUE; for (i=0; iAxis); i++) if (gd->Axis[i].Funcs[0].FuncKind==0) { switch(i) { case 0: x=WinToMathX(pt.x,gd); break; case 1: x=WinToMathY(pt.y,gd); break; } /*** loc_class=ClassGlobToLoc(ClassPtr[gd->Axis[i].Funcs[0].Func.Simple.IndirectIndex].Id);***/ loc_class=0; if (GetClassNameAndId(gd->Axis[i].Funcs[0].Func.Simple.IndirectIndex,NULL,&id)) loc_class=ClassGlobToLoc(id); if (loc_class) { vp=GetLocalClassVector(loc_class); if (vp) { vp=(FloatHiPtr)((CharPtr)vp+gd->Axis[i].Funcs[0].Func.Simple.Offset); *vp=x; goon=FALSE; } } } if (!goon) { UpdateInitPoint(); InvalidateBifData(); LockMenus(); if (gd->flags&MOUSE_IMMF) Forward(0); if (gd->flags&MOUSE_IMMB) Backward(0); UnlockMenus(); return; } } #endif /* MOUSE_PICK */ Beep(); } } Local(void) SetCallbacks(GraphicDataPtr gd, Boolean set) { if (set) SetPanelClick(gd->paPanel,ClickProc,DragProc,NULL,ReleaseProc); else SetPanelClick(gd->paPanel,NULL,NULL,NULL,NULL); } ClassMember(void) CreateControls(WinComDataPtr wcd) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; WindoW w; TexT t; #if SCROLL_ANGLES BaR b; #endif /* SCROLL_ANGLES */ RecT r; PoinT pt,pt1; PaneL pnl; int numwidth; Int2 i,j,width,width1,panelw,panelh,spc; Boolean lims; w=wcd->Win; /* Create a button that refreshes scales and place it outside the panel */ /* Then create a DialogText to allow keyboard input during computations and in suspend mode (see GraphicGInt) */ GetNextPosition(w,&pt); LoadPt(&pt1,-100,-100); SetNextPosition(w,pt1); gd->buRefr=DefaultButton(w,"",RefreshScale); gd->teAct=HiddenText(w,"",1,ActProc,NULL,NULL); Hide(gd->teAct); #if _WIN #ifdef WIN32 pt.y++; #else pt.y--; #endif #endif SetNextPosition(w,pt); /* Sizes */ panelw=wcd->Width; panelh=wcd->Height; /* Create Limits/Angles SpeedBar */ for (i=0; iAxis); i++) { gd->teAxis[i].prompt=NULL; for (j=0; jteAxis[0].teLimits); j++) gd->teAxis[i].teLimits[j]=NULL; } for (i=0; iteAngle); i++) { gd->teAngle[i].prompt=NULL; gd->teAngle[i].teAngle=NULL; } if (gd->Axis[0].bLimits || gd->Axis[0].bAngles) { gd->grLimits=CreateHiddenGroup(w,20,0,0); Hide(gd->grLimits); SetGroupMargins(gd->grLimits,0,0); SetGroupSpacing(gd->grLimits,spc=1,0); sscanf(GetParamString(SECTION,"NUMWIDTH"),"%i",&numwidth); for (i=0; iAxis)+2; i++) { lims=iAxis); /* FALSE => angles */ GetNextPosition(gd->grLimits,&pt); pt.x+=sysCharWidth/2; SetNextPosition(gd->grLimits,pt); if (lims&&gd->Axis[0].bLimits) { /* Width of prompt */ for (width=j=0; jFuncNum; j++) { width1=StringWidth(gd->Axis[i].Funcs[j].pFunc); if (widthAxis[i].bTick ? StringWidth(":")+numwidth*sysCharWidth : 0) > panelw ) Break(gd->grLimits); /* Abs/Ord prompt */ gd->teAxis[i].prompt= StaticPrompt(gd->grLimits,gd->Axis[i].Funcs[gd->FuncCur].pFunc,width,dialogTextHeight,NULL,'r'); /* Min */ t=DialogText(gd->grLimits,gd->Axis[i].pMin,numwidth,LimitsProc); SetTextSelect(t,SelectProc,NULL); gd->teAxis[i].teLimits[0]=t; /* .. */ StaticPrompt(gd->grLimits,"..",0,dialogTextHeight,NULL,'l'); /* Max */ t=DialogText(gd->grLimits,gd->Axis[i].pMax,numwidth,LimitsProc); SetTextSelect(t,SelectProc,NULL); gd->teAxis[i].teLimits[1]=t; /* NO func */ /* Tick */ if (gd->Axis[i].bTick) { /* : */ StaticPrompt(gd->grLimits,":",0,dialogTextHeight,NULL,'l'); t=DialogText(gd->grLimits,gd->Axis[i].pTick,numwidth,LimitsProc); SetTextSelect(t,SelectProc,NULL); gd->teAxis[i].teLimits[3]=t; } continue; } if ((!lims)&&gd->Axis[0].bAngles) { j=i-DIM(gd->Axis); /* 0 - theta, 1 - phi */ SelectFont(SymFont); width=StringWidth(THETA_STR); width1=StringWidth(PHI_STR); width=MAX(width,width1); SelectFont(SystemFont); if (2*sysCharWidth+pt.x+ 2*spc+width+ numwidth*sysCharWidth > panelw ) Break(gd->grLimits); /* Angle prompt */ gd->teAngle[j].prompt= StaticPrompt(gd->grLimits,j==0 ? THETA_STR : PHI_STR,width,dialogTextHeight,SymFont,'l'); /* Angle value */ t=DialogText(gd->grLimits,gd->pAngle[j],numwidth,AnglesProc); SetTextSelect(t,SelectProc,NULL); gd->teAngle[j].teAngle=t; #if SCROLL_ANGLES GetNextPosition(gd->grLimits,&pt); pt.x-=spc; SetNextPosition(gd->grLimits,pt); b=ScrollBar(gd->grLimits,0,1,AnglesBarProc); SetRange(b,1,1,2); CorrectBarValue(b,1); AlignObjects(ALIGN_VERTICAL,(HANDLE)b,(HANDLE)t,NULL); gd->teAngle[j].baAngle=b; #endif /* SCROLL_ANGLES */ continue; } } Show(gd->grLimits); GetPosition(gd->grLimits,&r); panelh-=r.bottom-r.top; } else gd->grLimits=NULL; /* Create Palette SpeedBar */ if (gd->Options.Flags&GWIN_PALETTE) { gd->grPalette=CreateHiddenGroup(w,20,0,0); SetGroupMargins(gd->grPalette,sysCharWidth/2,0); SetGroupSpacing(gd->grPalette,sysCharWidth/2,0); if (gd->FuncNum>1) { #if MYSWITCH gd->swNum=SwitchCreate(gd->grPalette,gd->FuncNum,PalNumProc); SwitchSetValue(gd->swNum,gd->FuncCur+1); Redraw(gd->swNum); #else gd->swNum=LeftRightSwitch(gd->grPalette,TRUE,PalNumProc); SetSwitchParams(gd->swNum,gd->FuncCur+1,gd->FuncNum); #endif GetPosition(gd->grPalette,&r); /* current width of the group */ } else LoadRect(&r,0,0,0,sysLineHeight); pnl=SimplePanel(gd->grPalette,panelw-(r.right-r.left)-2*sysCharWidth,r.bottom-r.top,PalDrawProc); Redraw(pnl); SetPanelClick(pnl,PalSelProc,NULL,NULL,NULL); gd->paSample=SimplePanel(gd->grPalette,sysCharWidth,r.bottom-r.top,PalSampProc); Redraw(gd->paSample); GetPosition(gd->grPalette,&r); panelh-=r.bottom-r.top+1; } else gd->grPalette=NULL; /* Compute dimensions of drawing rectangle in a panel (will be created later) */ GetNextPosition(w,&pt); LoadRect(&gd->Slate,pt.x,pt.y,pt.x+panelw-1,pt.y+panelh-1); /* Create panel for drawing */ gd->paPanel=SimplePanel(w,panelw,panelh,DrawProc); SetCallbacks(gd,TRUE); /* Process Scale */ /* first GetNumbers&CalculateScales call does not take scales into account, if any */ r=gd->Slate; GetNumbers(wcd); CalculateScales(wcd); GetNumbers(wcd); gd->Slate=r; CalculateScales(wcd); Redraw(gd->paPanel); gd->InitLevel=0; UndoRecord(wcd); UndoRRecord(wcd); } ClassMember(void) RemoveControls(WinComDataPtr wcd) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Hide(gd->grLimits); Hide(gd->grPalette); Remove(gd->buRefr); Remove(gd->teAct); Remove(gd->grLimits); Remove(gd->grPalette); Remove(gd->paPanel); } #if _WIN #pragma argsused #endif ClassMember(void) ManageControls(WinComDataPtr wcd, Boolean enable) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; (enable ? Enable : Disable)(gd->grLimits); (enable ? Enable : Disable)(gd->grPalette); /* Don't Enable/Disable gd->paPanel to avoid multiple redraws after Enable */ SetCallbacks(gd,enable); } ClassMember(void) BuildMenu(WinComDataPtr wcd) { MenuItemPtr ip; Int2 i; wcd->MenuDesc.Menu=ip=MemNew(sizeof(GraphicMenu)); wcd->MenuDesc.Num=DIM(GraphicMenu); wcd->MenuDesc.Lock=0; wcd->MenuDesc.Texts=Text; MemCopy(ip,GraphicMenu,sizeof(GraphicMenu)); for (i=0; iMenuDesc.Num; i++) { if (ip[i].Title==FORWARD_I) { ip[i].Action=Forward; ip[i].EnableDisable=FBStatus; continue; } if (ip[i].Title==BACKWARD_I) { ip[i].Action=Backward; ip[i].EnableDisable=FBStatus; continue; } if (ip[i].Title==EXTEND_I) { ip[i].Action=Extend; ip[i].EnableDisable=ExtendStatus; continue; } if (ip[i].Title==REDRAWD_I) { /*** ip[i].Action=RedrawDiagram;***/ ip[i].EnableDisable=RedrawDStatus; continue; } if (ip[i].Title==REDRAWC_I) { /*** ip[i].Action=RedrawCurve;***/ ip[i].EnableDisable=RedrawCStatus; continue; } if (ip[i].Title==FITD_I) { ip[i].EnableDisable=RedrawDStatus; continue; } if (ip[i].Title==FITC_I) { ip[i].EnableDisable=RedrawCStatus; continue; } if (ip[i].Title==HARDCOPY_I) { ip[i].EnableDisable=HardcopyStatus; continue; } if (ip[i].Title==HIDE_I) { ip[i].Action=HideWin; continue; } if (ip[i].Title==CURVEATR_I) { ip[i].EnableDisable=ExtendStatus; continue; } } SymFont=ParseFont(GetParamString(SFS_HELP,"FORMM_FONT")); } #if _WIN #pragma argsused #endif ClassMember(void) NewInitPoint(WinComDataPtr wcd) { /* nothing */ } ClassMember(void) ClearWindow(WinComDataPtr wcd) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Redraw(gd->paPanel); BSFree(gd->SpecialPoints); gd->SpecialPoints=BSNew(0); UndoRecord(wcd); UndoRRecord(wcd); } ClassMember(Boolean) SimpleFunctions(WinComDataPtr wcd) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Int2 i,j; Boolean res=TRUE,gdim1=TRUE; for (i=0; iAxis); i++) for (j=0; jFuncNum; j++) { if (res && !ParseName(gd->Axis[i].Funcs[j].pFunc,NULL,NULL)) res=FALSE; gd->Axis[i].Funcs[j].Gdim=GdimEq1(gd->Axis[i].Funcs[j].pFunc); if (!gd->Axis[i].Funcs[j].Gdim) gdim1=FALSE; } if (gdim1) wcd->flags|=WFL_GDIM1; else wcd->flags&=~WFL_GDIM1; return res; } Local(void) WinFuncName(CharPtr buf, int axis, int funcnum, Uint1 unique) { sprintf(buf,"_3d%c%i_%i","xyz"[axis],funcnum,(int)unique); } ClassMember(void) PutFunctions(WinComDataPtr wcd, FILE PNTR Source, Int2Ptr LineNum) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; CharPtr p; int i,j; Char buf[15]; for (i=0; iAxis); i++) for (j=0; jFuncNum; j++) if (!ParseName(gd->Axis[i].Funcs[j].pFunc,NULL,NULL)) { WinFuncName(buf,i,j,wcd->Unique); SetParam("TMP","TMP",WIN_HEAD); /* Force replacement */ p=GetParamString("TMP","TMP"); /* of symbolical references */ p=(CharPtr)TSPrintf(p,buf); /* func name */ fputs(CountLinesAndErase_r(p,'\n',LineNum),Source); fputs(gd->Axis[i].Funcs[j].pFunc,Source); SetParam("TMP","TMP",WIN_TAIL); /* Force replacement */ p=GetParamString("TMP","TMP"); /* of symbolical references */ fputs(CountLinesAndErase_r(p,'\n',LineNum),Source); } } ClassMember(void) SetFunctions(WinComDataPtr wcd, LibHandle hWinLib) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; int i,j; Char buf[15]; for (i=0; iAxis); i++) for (j=0; jFuncNum; j++) if (ParseName(gd->Axis[i].Funcs[j].pFunc, &gd->Axis[i].Funcs[j].Func.Simple.IndirectIndex, &gd->Axis[i].Funcs[j].Func.Simple.Offset)) { gd->Axis[i].Funcs[j].FuncKind=0; } else { gd->Axis[i].Funcs[j].FuncKind=1; /*** sprintf(buf,"_%c%i_%i","ao"[i],j,(int)pwd->Unique);***/ WinFuncName(buf,i,j,wcd->Unique); gd->Axis[i].Funcs[j].Func.General.FloatFunc=hWinLib ? (WinFloatValue)LibraryFuncAddress(hWinLib,buf) : NULL; } } ClassMember(void) ExportDescription(WinComDataPtr wcd, DataLibPtr arch, FILE PNTR out) { GraphicDataPtr gd; Int2 i,j; ReadDescription(wcd,arch); /* also allocates private data area */ gd=(GraphicDataPtr)wcd->Private; fprintf(out," func=%i cur=%i\n",(int)gd->FuncNum,(int)gd->FuncCur); for (i=0; iAxis); i++) { for (j=0; jAxis[i].pText); j++) if (!FuncIndex(j)) fprintf(out," %s\n",gd->Axis[i].pText[j]); for (j=0; jFuncNum; j++) fprintf(out," %s\n", gd->Axis[i].Funcs[j].pFunc); fprintf(out," "); for (j=0; jAxis[i].Prop); j++) fprintf(out,"%i ",(int)gd->Axis[i].Prop[j]); fprintf(out,"\n"); } for (i=0; iFuncNum; i++) { fprintf(out," point=(%li,%i,%i) trace=(%li,%i,%i) path=(%li,%i,%i)\n", ColorOut(gd->Attr[i].Point.color),(int)gd->Attr[i].Point.width,(int)gd->Attr[i].Point.style, ColorOut(gd->Attr[i].Trace.color),(int)gd->Attr[i].Trace.width,(int)gd->Attr[i].Trace.style, ColorOut(gd->Attr[i].Path.color),(int)gd->Attr[i].Path.width,(int)gd->Attr[i].Path.style); } fprintf(out," options=(%li,%i,%i,%i,%i)\n", ColorOut(gd->Options.Shift.color), (int)gd->Options.Shift.width, (int)gd->Options.Shift.style, (int)gd->Options.Flags, (int)gd->Options.Reserve); fprintf(out," Theta,Phi\n"); for (i=0; ipAngle); i++) fprintf(out," %s\n",gd->pAngle[i]); fprintf(out," Sundo=%i\n",(int)gd->UndoNum); for (i=0; iUndoNum; i++) fprintf(out," %g %g %g %g %g %g\n", gd->UndoBuf[i].xMin,gd->UndoBuf[i].xMax, gd->UndoBuf[i].yMin,gd->UndoBuf[i].yMax, gd->UndoBuf[i].zMin,gd->UndoBuf[i].zMax); fprintf(out," Rundo=%i\n",(int)gd->UndoRNum); for (i=0; iUndoRNum; i++) fprintf(out," %g %g\n", gd->UndoRBuf[i].theta,gd->UndoRBuf[i].phi); WriteDescription(wcd,NULL); /* free mem only */ MemFree(gd); } ClassMember(void) ImportDescription(WinComDataPtr wcd, DataLibPtr arch, FILE PNTR in) { GraphicData gd; long col1,col2,col3; int i1,i2,i3,j1,j2,j3,k2,k3; Int2 i,j; Char buf[PAR_BUF]; MemFill(&gd,0,sizeof(gd)); wcd->Private=&gd; fscanf(in," func=%i cur=%i\n",&i1,&i2); gd.FuncNum=(Int2)i1; gd.FuncCur=(Int2)i2; for (i=0; iPrivate; Int2 funcnum; Int2 i; DrawAttr Point,Trace,Path; if (from) BSRead(from,&funcnum,sizeof(funcnum)); else funcnum=gd->FuncNum; if (to) BSWrite(to,&funcnum,sizeof(funcnum)); else DataLibWrite(dgm,(CharPtr)&funcnum,sizeof(funcnum)); for (i=0; iAttr[i].Point; Trace=gd->Attr[i].Trace; Path=gd->Attr[i].Path; } if (to) { BSWrite(to,&Point,sizeof(Point)); BSWrite(to,&Trace,sizeof(Trace)); BSWrite(to,&Path,sizeof(Path)); } else { DataLibWrite(dgm,(CharPtr)&Point,sizeof(Point)); DataLibWrite(dgm,(CharPtr)&Trace,sizeof(Trace)); DataLibWrite(dgm,(CharPtr)&Path,sizeof(Path)); } } if (!from && freemem) { gd->Attr=MemFree(gd->Attr); gd->FuncNum=0; } } ClassMember(void) RestoreAttr(WinComDataPtr wcd, DataLibPtr dgm, ByteStorePtr from, ByteStorePtr to, Boolean skip) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; DrawAttr Point,Trace,Path; Int2 i,n; if (from) BSRead(from,&n,sizeof(gd->FuncNum)); else DataLibRead(dgm,(CharPtr)&n,sizeof(gd->FuncNum)); /* no of attr stored */ if (!skip && !to && !gd->FuncNum) { gd->Attr=MemNew(ARRAYSIZE(FuncAttr,n)); gd->FuncNum=n; } if (to) BSWrite(to,&n,sizeof(gd->FuncNum)); for (i=0; iFuncNum) { gd->Attr[i].Point=Point; if (gd->Attr[i].Trace.style<=0 && Trace.style>0) { /* Switching from "don't join" to "join" */ gd->joinpath=TRUE; } gd->Attr[i].Trace=Trace; if (gd->Attr[i].Path.style<=0 && Path.style>0) { /* Switching from "don't join" to "join" */ gd->Attr[i].flags|=PATH_CHANGE; gd->joinpath=TRUE; } gd->Attr[i].Path=Path; } } } #if _WIN #pragma argsused #endif ClassMember(void) ExportAttr(WinComDataPtr wcd, DataLibPtr dgm, FILE PNTR out) { DrawAttr Point,Trace,Path; Int2 i,n; DataLibRead(dgm,(CharPtr)&n,sizeof(n)); /* no of attr stored */ fprintf(out," %i:\n",(int)n); for (i=0; iPrivate; gd->SaveFuncNum=gd->FuncNum; gd->SaveAttr=MemNew(ARRAYSIZE(FuncAttr,gd->FuncNum)); MemCopy(gd->SaveAttr,gd->Attr,ARRAYSIZE(FuncAttr,gd->FuncNum)); if (freemem) { gd->Attr=MemFree(gd->Attr); gd->FuncNum=0; } } ClassMember(void) PopAttr(WinComDataPtr wcd) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; MemFree(gd->Attr); gd->FuncNum=gd->SaveFuncNum; gd->Attr=MemNew(ARRAYSIZE(FuncAttr,gd->FuncNum)); MemCopy(gd->Attr,gd->SaveAttr,ARRAYSIZE(FuncAttr,gd->FuncNum)); MemFree(gd->SaveAttr); } ClassMember(void) SpecialAction(WinComDataPtr wcd, VisualSpecAction vsa) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Point3d x; Int2 i,j; RecT r; PoinT pt1,pt2; DrawAttr attr; Select(gd->paPanel); for (j=0; jFuncNum; j++) switch (vsa) { case VSA_RESET: gd->Axis[0].Funcs[j].Eip=DBL_MAX; break; case VSA_ERASE: if (gd->Axis[0].Funcs[j].Eip==DBL_MAX) break; for (i=0; iRAxis); i++) x[i]=gd->Axis[i].Funcs[j].Eip; gd->Axis[0].Funcs[j].Eip=DBL_MAX; goto draw; case VSA_DRAW: /* Compute functions along axes and convert their values to window coordinates */ for (i=0; iRAxis); i++) if (gd->Axis[i].Funcs[j].FuncKind) /* function */ x[i]=gd->Axis[i].Funcs[j].Func.General.FloatFunc(IndirectValues); else /* simple */ x[i]=*(FloatHiPtr)((CharPtr)*IndirectValues[gd->Axis[i].Funcs[j].Func.Simple.IndirectIndex]+ gd->Axis[i].Funcs[j].Func.Simple.Offset); for (i=0; iRAxis); i++) gd->Axis[i].Funcs[j].Eip=x[i]; draw:; InvertMode(); GetPosition(gd->paPanel,&r); InsetRect(&r,1,1); ClipRect(&r); attr.width=1; attr.style=1; /* solid */ attr.color=wcd->Foreground; SetCurrentPen(&attr); Math3dToWin(gd->RAxis[0].Min,x[1],x[2],&pt1,gd); Math3dToWin(gd->RAxis[0].Max,x[1],x[2],&pt2,gd); lLine(pt1.x,pt1.y,pt2.x,pt2.y); Math3dToWin(x[0],gd->RAxis[1].Min,x[2],&pt1,gd); Math3dToWin(x[0],gd->RAxis[1].Max,x[2],&pt2,gd); lLine(pt1.x,pt1.y,pt2.x,pt2.y); Math3dToWin(x[0],x[1],gd->RAxis[2].Min,&pt1,gd); Math3dToWin(x[0],x[1],gd->RAxis[2].Max,&pt2,gd); lLine(pt1.x,pt1.y,pt2.x,pt2.y); CopyMode(); ResetClip(); break; } } ClassMember(void) FreeCurveData(WinComDataPtr wcd, FilePtr curvefp) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Int4 pos,len; ByteStorePtr bp=gd->SpecialPoints; FilePtr fp; PoinT pt; Int2 pn; BSSeek(bp,0,SEEK_SET); while (pos=BSTell(bp), BSRead(bp,&fp,len=sizeof(fp))) { while (1) { BSRead(bp,&pn,sizeof(pn)); len+=sizeof(pn); if (pn==-1) break; BSRead(bp,&pt,sizeof(pt)); len+=sizeof(pt); } if (fp==curvefp) { BSSeek(bp,pos,SEEK_SET); BSDelete(bp,len); /* Don't break here: there is/are more if the curve was extended */ } } BSSeek(bp,0,SEEK_END); } ClassMember(void) GInit(WinComDataPtr wcd) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Int2 i; Boolean hc=gd->Hardcopy; if (gd->flags&FIT_IN_PROGRESS) return; gd->joinpath=FALSE; for (i=0; iFuncNum; i++) { if (gd->Attr[i].Path.style>0) gd->joinpath=TRUE; /* We must always allocate memory for PrevPath&CurPath because gd->Attr[i].Path.style may be changed at a special point during a pause or while redrawing */ gd->Attr[i].PrevPath=MemNew(sizeof(Point3d)); gd->Attr[i].CurPath=MemNew(sizeof(Point3d)); gd->Attr[i].PrevNum=gd->Attr[i].CurNum=1; } /* Mark beginning of curve */ if (CurCurve) BSWrite(gd->SpecialPoints,&ccd.CurrentCurvePtr,sizeof(ccd.CurrentCurvePtr)); /* Disable all speed bar controls */ if (!gd->InitLevel++) { Disable(gd->grLimits); Show(gd->teAct); } if (hc) fprintf(gd->HardFile,"\n%%BeginCurve: %s\n",DiagramLib.DirName); } ClassMember(void) GTerm(WinComDataPtr wcd) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Int2 i; Boolean hc=gd->Hardcopy; if (gd->flags&FIT_IN_PROGRESS) return; for (i=0; iFuncNum; i++) { /* See the comment in GInit */ gd->Attr[i].PrevPath=MemFree(gd->Attr[i].PrevPath); gd->Attr[i].CurPath=MemFree(gd->Attr[i].CurPath); } if (CurCurve) { Int2 m1=-1; BSWrite(gd->SpecialPoints,&m1,sizeof(m1)); } /* Enable all speed bar controls */ if (!--gd->InitLevel) { Enable(gd->grLimits); Hide(gd->teAct); } if (hc) fprintf(gd->HardFile,"%%EndCurve: %s\n",DiagramLib.DirName); } Local(void) GraphicSwap(GraphicDataPtr gd, Int2 i) { Int2 n; Point3dPtr p; p=gd->Attr[i].PrevPath; n=gd->Attr[i].PrevNum; gd->Attr[i].PrevPath=gd->Attr[i].CurPath; gd->Attr[i].PrevNum=gd->Attr[i].CurNum; gd->Attr[i].CurPath=p; gd->Attr[i].CurNum=n; } ClassMember(void) MInit(WinComDataPtr wcd) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; RecT r; div_t divt; Int2 i; if (gd->flags&FIT_IN_PROGRESS) return; if (gd->Options.Flags&GWIN_CLEAR) { UseWindow(wcd->Win); Select(gd->paPanel); Solid(); WidePen(1); /* just for Mac and Motif */ r=gd->Slate; InsetRect(&r,1,1); ClipRect(&r); gd->flags|=DONT_SCALE; DrawProc(gd->paPanel); gd->flags&=~DONT_SCALE; } if (gd->joinpath && !(wcd->flags&WFL_G1)) { if (ccd.curveDimG*ccd.curvePrevDimG) { divt=div(MAX(ccd.curveDimG,ccd.curvePrevDimG), MIN(ccd.curveDimG,ccd.curvePrevDimG)); gd->Q=divt.quot; gd->Qs=MIN(ccd.curveDimG,ccd.curvePrevDimG)-(gd->Q1s=divt.rem); } else wcd->flags|=WFL_G1; /* don't join (as for the first M-point) */ } for (i=0; iFuncNum; i++) { if (gd->Attr[i].flags&PATH_CHANGE) GraphicSwap(gd,i); if (gd->Attr[i].Path.style>0) { if (ccd.curveDimG>gd->Attr[i].CurNum) { gd->Attr[i].CurPath=MemMore(gd->Attr[i].CurPath,ARRAYSIZE(Point3d,ccd.curveDimG)); gd->Attr[i].CurNum=ccd.curveDimG; } } } /*** gd->flags&=~PATH_CHANGE;***/ } ClassMember(void) MTerm(WinComDataPtr wcd) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Int2 i; if (gd->flags&FIT_IN_PROGRESS) return; for (i=0; iFuncNum; i++) if (gd->Attr[i].Path.style>0) { GraphicSwap(gd,i); } } Local(GraphicDataPtr) Gd; /* used only by functions called by MProcess */ Local(Boolean) CheckJoinPoints(Int2 pointNum, Int2 joinNum, Int2Ptr curLeft) { Int2 i,j; Boolean rc=FALSE; for (i=0; i=ccd.curveDimG) { if (!--*curLeft) { Gd->JoinIndex=Gd->PrevNum-1; /* JoinIndex must be in [0..ccd.curvePrevDimG-1] */ Gd->JoinNum=joinNum; rc=TRUE; } } else Gd->PrevNum++; if (ccd.curvePrevDimG>=ccd.curveDimG) Gd->PrevNum+=joinNum; else for (j=0; jJoinIndex=Gd->PrevNum-2; /* JoinIndex must be in [0..ccd.curvePrevDimG-1] */ Gd->JoinNum=1; rc=TRUE; break; } } return rc; } /* There are Qs points where Q lines fork or merge and Q1s points where Q+1 lines fork or merge */ Local(Boolean) GetJoinParams(Int2 Qs, Int2 Q1s, Int2 side, Int2Ptr curLeft) { Int2 qa,qb; /* check terminal conditions */ if (Qs==0) return CheckJoinPoints(Q1s,Gd->Q+1,curLeft); if (Q1s==0) return CheckJoinPoints(Qs,Gd->Q,curLeft); qa=Qs>>1; qb=Q1s>>1; /* left part */ if (GetJoinParams(qa,qb,0,curLeft)) return TRUE; /* in between */ if (Qs&1) if (Q1s&1) { if (CheckJoinPoints(1,Gd->Q+side,curLeft)) return TRUE; if (CheckJoinPoints(1,Gd->Q+1-side,curLeft)) return TRUE; } else { if (CheckJoinPoints(1,Gd->Q,curLeft)) return TRUE; } else if (Q1s&1) if(CheckJoinPoints(1,Gd->Q+1,curLeft)) return TRUE; /* right part */ return GetJoinParams(qa,qb,1,curLeft); } Local(FloatHi) mpt[2]; Local(PoinT) wpt; Local(void) hcLine(FloatHiPtr ptprev, FloatHiPtr pt) { fprintf(Gd->HardFile,"%g %g %g %g LINE\n",pt[0],pt[1],ptprev[0],ptprev[1]); } Local(void) hcPoint(FloatHiPtr pt) { fprintf(Gd->HardFile,"%g %g POINT\n",pt[0],pt[1]); } Local(Boolean) DrawClippedLine(Point3d xb, Point3d xe) { Point3d x1,x2; FloatHi u1[2],u2[2],al,ar,Al,Ar; PoinT pt1,pt2; Int2 i; #ifdef QQQ Point3d xw; Int2 j; MemCopy(x1,xb,sizeof(Point3d)); MemCopy(x2,xe,sizeof(Point3d)); for (i=0; iRAxis); i++) { if (x1[i]>x2[i]) { MemCopy(xw,x1,sizeof(Point3d)); MemCopy(x1,x2,sizeof(Point3d)); MemCopy(x2,xw,sizeof(Point3d)); } if (x2[i]RAxis[i].Min || x1[i]>Gd->RAxis[i].Max) return FALSE; /* nothing to draw */ if (x1[i]RAxis[i].Min) x1[i]=Gd->RAxis[i].Min; if (x2[i]>Gd->RAxis[i].Max) x2[i]=Gd->RAxis[i].Max; } Math3dTo2d(x1,u1,Gd); pt1.x=Math2dToWinU(u1[0],Gd); pt1.y=Math2dToWinV(u1[1],Gd); Math3dTo2d(x2,u2,Gd); pt2.x=Math2dToWinU(u2[0],Gd); pt2.y=Math2dToWinV(u2[1],Gd); lLine(pt1.x,pt1.y,pt2.x,pt2.y); if (Gd->Hardcopy) hcLine(u1,u2); return TRUE; /* draw [x1,x2] */ #endif /* QQQ */ for (i=0,Al=0,Ar=1; iRAxis); i++) { if (xb[i]==xe[i]) { if (Gd->RAxis[i].Min<=xb[i] && xb[i]<=Gd->RAxis[i].Max) { al=0; ar=1; } else { return FALSE; } } else { al=(Gd->RAxis[i].Min-xe[i])/(xb[i]-xe[i]); ar=(Gd->RAxis[i].Max-xe[i])/(xb[i]-xe[i]); if (al>ar) {FloatHi aw=al; al=ar; ar=aw;} } if (al>Al) Al=al; if (arRAxis); i++) { x1[i]=Al*xb[i]+(1-Al)*xe[i]; x2[i]=Ar*xb[i]+(1-Ar)*xe[i]; } Math3dTo2d(x1,u1,Gd); pt1.x=Math2dToWinU(u1[0],Gd); pt1.y=Math2dToWinV(u1[1],Gd); Math3dTo2d(x2,u2,Gd); pt2.x=Math2dToWinU(u2[0],Gd); pt2.y=Math2dToWinV(u2[1],Gd); lLine(pt1.x,pt1.y,pt2.x,pt2.y); if (Gd->Hardcopy) hcLine(u1,u2); return TRUE; } else return FALSE; } Local(Boolean) Point3dIn(Point3d x) { Int2 i; for (i=0; iRAxis); i++) if (x[i]RAxis[i].Min || x[i]>Gd->RAxis[i].Max) return FALSE; /* out of limits */ Math3dTo2d(x,mpt,Gd); wpt.x=Math2dToWinU(mpt[0],Gd); wpt.y=Math2dToWinV(mpt[1],Gd); return TRUE; } ClassMember(void) MProcess(WinComDataPtr wcd) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Point3d x,xw; RecT r; Int2 i,j,k,b,curNum; Boolean hc=gd->Hardcopy; /* TRUE if Hardcopy is in progress */ Boolean hcm; Select(gd->paPanel); r=gd->Slate; InsetRect(&r,1,1); ClipRect(&r); Gd=gd; if ((gd->flags&FIT_IN_PROGRESS)==0) if (gd->joinpath && !(wcd->flags&WFL_G1)) if (ccd.curvePrevDimG==ccd.curveDimG) { gd->JoinIndex=curveCurNum-1; gd->JoinNum=1; } else { gd->PrevNum=1; curNum=curveCurNum; GetJoinParams(gd->Qs,gd->Q1s,0,&curNum); } for (j=0; jFuncNum; j++) { /* Compute functions along axes and convert their values to window coordinates */ for (i=0; iRAxis); i++) { if (gd->Axis[i].Funcs[j].FuncKind) /* function */ x[i]=gd->Axis[i].Funcs[j].Func.General.FloatFunc(IndirectValues); else /* simple */ x[i]=*(FloatHiPtr)((CharPtr)*IndirectValues[gd->Axis[i].Funcs[j].Func.Simple.IndirectIndex]+ gd->Axis[i].Funcs[j].Func.Simple.Offset); if (x[i]==NOUPDATE) goto cont_end; } if (gd->flags&FIT_IN_PROGRESS) { for (i=0; iRAxis); i++) { if (x[i]RAxis[i].FitMin) gd->RAxis[i].FitMin=x[i]; if (x[i]>gd->RAxis[i].FitMax) gd->RAxis[i].FitMax=x[i]; } continue; } /* Join current point with previous one(s) along a path */ if (gd->Attr[j].Path.style>0) { if (!(wcd->flags&WFL_G1) && !(gd->Attr[j].flags&PATH_CHANGE)) for (i=0; iJoinNum; i++) { SetCurrentPen(&gd->Attr[j].Path); DrawClippedLine(gd->Attr[j].PrevPath[i+gd->JoinIndex],x); if (Point3dIn(gd->Attr[j].PrevPath[i+gd->JoinIndex])) { SetCurrentPen(&gd->Attr[j].Point); if (ccd.pointPrevType) { DrawSpecialPoint(wpt.x,wpt.y,ccd.pointPrevType,wcd->Background,FALSE); } else { lPoint(wpt.x,wpt.y); if (hc) hcPoint(mpt); } } } else gd->Attr[j].flags&=~PATH_CHANGE; MemCopy(gd->Attr[j].CurPath[curveCurNum-1],x,sizeof(x)); } /* Join current point with the previous one along a trace */ if (gd->Attr[j].Trace.style>0 && !(wcd->flags&WFL_M1)) { SetCurrentPen(&gd->Attr[j].Trace); for (k=0; kRAxis); k++) xw[k]=gd->Axis[k].Funcs[j].Wcoord; DrawClippedLine(x,xw); if (Point3dIn(xw)) { SetCurrentPen(&gd->Attr[j].Point); if (ccd.pointType && !ccd.lastPoint) { DrawSpecialPoint(wpt.x,wpt.y,ccd.pointType,wcd->Background,FALSE); } else { lPoint(wpt.x,wpt.y); if (hc) hcPoint(mpt); } } } /* Join current point with the previous one along a shift */ if (gd->Options.Shift.style>0 && j) { SetCurrentPen(&gd->Options.Shift); for (k=0; kRAxis); k++) xw[k]=gd->Axis[k].Funcs[j-1].Wcoord; DrawClippedLine(x,xw); if (Point3dIn(xw)) { SetCurrentPen(&gd->Attr[j-1].Point); if (ccd.pointType && !ccd.lastPoint) { DrawSpecialPoint(wpt.x,wpt.y,ccd.pointType,wcd->Background,FALSE); } else { lPoint(wpt.x,wpt.y); if (hc) hcPoint(mpt); } } } /* Plot the current point */ if (Point3dIn(x)) { SetCurrentPen(&gd->Attr[j].Point); if (ccd.pointType && !ccd.lastPoint) { for (k=b=0; kAxis); k++) b+=gd->Axis[k].Funcs[j].Gdim; if ((b>=2) || curveCurNum==(ccd.curveDimG>>1)) { FloatHi mptw[2]; PoinT wptw; for (k=0; kRAxis); k++) xw[k]=gd->Axis[k].Funcs[j].Wcoord; Math3dTo2d(xw,mptw,gd); wptw.x=Math2dToWinU(mptw[0],gd); wptw.y=Math2dToWinV(mptw[1],gd); SpecialPointPrev(wpt.x-wptw.x, wpt.y-wptw.y, mpt[0]-mptw[0], mpt[1]-mptw[1], gd->DeltaU, gd->DeltaV ); } if (hc) { hcm=IsMarker(ccd.pointType); if (hcm) fprintf(gd->HardFile,"/MARKER%i {newpath\n",(int)gd->hcMarkerNo); } DrawSpecialPoint(wpt.x,wpt.y,ccd.pointType,wcd->Background,TRUE); if (hc) { if (hcm) fprintf(gd->HardFile,"} bind def\nMARKER%i\n",(int)gd->hcMarkerNo++); } if (CurCurve) { BSWrite(gd->SpecialPoints,&ccd.CurrentSpecialPoint,sizeof(ccd.CurrentSpecialPoint)); BSWrite(gd->SpecialPoints,&wpt,sizeof(wpt)); } } else { lPoint(wpt.x,wpt.y); if (hc) hcPoint(mpt); } if (gd->Axis[0].bProj) { /* projections to 'invisible' surfaces */ FloatHi t; DrawAttr da=gd->Attr[j].Point; SetCurrentPen(&da); for (k=0; kRAxis); k++) { MemCopy(xw,x,sizeof(Point3d)); switch (k) { case 0: t=gd->RAxis[0].Limits[gd->ibx]; break; case 1: t=gd->RAxis[1].Limits[gd->iby]; break; case 2: t=gd->RAxis[2].Limits[gd->usurface ? 0:1]; break; } xw[k]=t; Point3dIn(xw); lPoint(wpt.x,wpt.y); if (hc) hcPoint(mpt); } } } /* Store previous coordinates */ for (k=0; kRAxis); k++) gd->Axis[k].Funcs[j].Wcoord=x[k]; cont_end:; } } Local(void) hcSetColor(FILE PNTR hcStream, CharPtr cmd) { Uint1 r,g,b; DecodeColor(GetColor(),&r,&g,&b); fprintf(hcStream,"%g %g %g %s",r/255.0,g/255.0,b/255.0,cmd); } ClassMember(void) hcPen(WinComDataPtr wcd, DrawAttrPtr attr) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; fprintf(gd->HardFile,"%i %i PEN\n",(int)attr->width,(int)attr->style); hcSetColor(gd->HardFile,"COLOR\n"); } ClassMember(void) hcString(WinComDataPtr wcd, CharPtr str, float PNTR hardcopy) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Int2 i; fprintf(gd->HardFile,"(%s)",str); for (i=0; i<6; ) fprintf(gd->HardFile," %g",hardcopy[i++]); fprintf(gd->HardFile," %g %g STRMARKER\n",mpt[0],mpt[1]); } ClassMember(void) hcPaintOval(WinComDataPtr wcd, RectPtr r) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; fprintf(gd->HardFile,"%g %g %g ",mpt[0],mpt[1],(r->right-r->left)/2.0); hcSetColor(gd->HardFile,"PAINTCIRCLE\n"); } ClassMember(void) hcFrameOval(WinComDataPtr wcd, RectPtr r) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; fprintf(gd->HardFile,"%g %g %g ",mpt[0],mpt[1],(r->right-r->left)/2.0); hcSetColor(gd->HardFile,"FRAMECIRCLE\n"); } Local(void) hcPoly(GraphicDataPtr gd, Int2 num, PointPtr poly, CharPtr oper) { Int2 i,wx,wy; for (i=num-1; i>=0; i--) { if (i) { wx=poly[i].x-poly[i-1].x; wy=-(poly[i].y-poly[i-1].y); } else { wx=poly[0].x-Math2dToWinU(mpt[0],gd); wy=-(poly[0].y-Math2dToWinV(mpt[1],gd)); } fprintf(gd->HardFile," %i %i",(int)wx,(int)wy); } fprintf(gd->HardFile," %i %g %g ",(int)num,mpt[0],mpt[1]); hcSetColor(gd->HardFile,oper); } ClassMember(void) hcPaintPoly(WinComDataPtr wcd, Int2 num, PointPtr poly) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; hcPoly(gd,num,poly,"PAINTPOLY\n"); } ClassMember(void) hcFramePoly(WinComDataPtr wcd, Int2 num, PointPtr poly) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; hcPoly(gd,num,poly,"FRAMEPOLY\n"); } /******************/ /* Menu callbacks */ /*---------------------------------------*/ /* Menu callback: Redraw current diagram */ #if _WIN #pragma argsused #endif Callback(void) lRedrawD(Int2 indx) { WinComDataPtr wcd=GetComDataI; DeactivateWindows(wcd); RedrawDiagram(0); ActivateWindows(); } /*-------------------------------------*/ /* Menu callback: Redraw current curve */ #if _WIN #pragma argsused #endif Callback(void) lRedrawC(Int2 indx) { WinComDataPtr wcd=GetComDataI; DeactivateWindows(wcd); RedrawCurve(0); ActivateWindows(); } /*---------------------------------*/ /* Menu callback: Clear the window */ #if _WIN #pragma argsused #endif Callback(void) lClear(Int2 indx) { ClearWindow(GetComDataI); } /*-----------------------------------*/ /* Menu callbacks: Fit diagram/curve */ #define PERCENT 2.5 /* of margins */ Local(void) Fit(Boolean diagram) { WinComDataPtr wcd=GetComDataI; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; TexT t; FloatHi d; Int2 i,j; MsgAnswer anstick; Boolean asktick=TRUE; Boolean change=FALSE; Char buf[30]; DeactivateWindows(wcd); /* freeze others */ for (i=0; iRAxis); i++) { gd->RAxis[i].FitMin=DBL_MAX; gd->RAxis[i].FitMax=-DBL_MAX; } gd->flags|=FIT_IN_PROGRESS; if (diagram) RedrawDiagram(0); else RedrawCurve(0); gd->flags^=FIT_IN_PROGRESS; UseWindow(wcd->Win); for (i=0; iRAxis); i++) if (gd->RAxis[i].FitMin!=DBL_MAX && gd->RAxis[i].FitMin!=gd->RAxis[i].FitMax) { change=TRUE; d=(gd->RAxis[i].FitMax-gd->RAxis[i].FitMin)/100*PERCENT; gd->RAxis[i].Min=gd->RAxis[i].FitMin-d; gd->RAxis[i].Max=gd->RAxis[i].FitMax+d; /* Update controls, see LimitsProc */ for (j=0; j<2; j++) { /* 0 - Min, 1 - Max */ sprintf(buf,"%g",gd->RAxis[i].Limits[j]); MemFree(gd->Axis[i].pText[j]); gd->Axis[i].pText[j]=StringSave(buf); t=gd->teAxis[i].teLimits[j]; if (t) SetTitle(t,buf); } /* Ticks */ if (gd->RAxis[i].Tick>0) { if (asktick) { asktick=FALSE; anstick=Message(MSG_YN, "Fit has found non-zero tick value.\n" "Set it to zero?\n" "(to allow Content to determine it)"); } if (anstick==ANS_YES) { gd->RAxis[i].Tick=0; MemFree(gd->Axis[i].pTick); gd->Axis[i].pTick=StringSave("0"); t=gd->teAxis[i].teLimits[3]; if (t) SetTitle(t,"0"); } } GetNumbers(wcd); } if (change) { lRefreshScale(wcd); ClearWindow(wcd); if (diagram) RedrawDiagram(0); else RedrawCurve(0); } ActivateWindows(); /* melt others */ } #undef PERCENT #if _WIN #pragma argsused #endif Callback(void) lFitDiagram(Int2 indx) { Fit(TRUE); } #if _WIN #pragma argsused #endif Callback(void) lFitCurve(Int2 indx) { Fit(FALSE); } /*---------------------------*/ /* Menu callback: Undo scale */ Local(void) UndoRecord(WinComDataPtr wcd) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Int2 i,n=gd->UndoNum; if (gd->UndoBuf) { if (gd->UndoBuf[n].xMin!=gd->RAxis[0].Min || gd->UndoBuf[n].xMax!=gd->RAxis[0].Max || gd->UndoBuf[n].yMin!=gd->RAxis[1].Min || gd->UndoBuf[n].yMax!=gd->RAxis[1].Max || gd->UndoBuf[n].zMin!=gd->RAxis[2].Min || gd->UndoBuf[n].zMax!=gd->RAxis[2].Max) { if (n==UNDODEPTH-1) for (i=0; iUndoBuf[i]=gd->UndoBuf[i+1]; else n++; } else return; } else { gd->UndoBuf=MemNew(ARRAYSIZE(UndoElem,UNDODEPTH)); n=0; } gd->UndoBuf[n].xMin=gd->RAxis[0].Min; gd->UndoBuf[n].xMax=gd->RAxis[0].Max; gd->UndoBuf[n].yMin=gd->RAxis[1].Min; gd->UndoBuf[n].yMax=gd->RAxis[1].Max; gd->UndoBuf[n].zMin=gd->RAxis[2].Min; gd->UndoBuf[n].zMax=gd->RAxis[2].Max; gd->UndoNum=n; SetStatusOfItems(&wcd->MenuDesc); } #if _WIN #pragma argsused #endif Callback(void) lUndoScale(Int2 index) { WinComDataPtr wcd=GetComDataI; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; UndoElem ue; Int2 i,j,n; Char b[20]; n=gd->UndoNum; /* n>0! see UndoScale_Status */ ue=gd->UndoBuf[n]; for (i=n; i; i--) gd->UndoBuf[i]=gd->UndoBuf[i-1]; gd->UndoBuf[0]=ue; gd->RAxis[0].Min=gd->UndoBuf[n].xMin; gd->RAxis[0].Max=gd->UndoBuf[n].xMax; gd->RAxis[1].Min=gd->UndoBuf[n].yMin; gd->RAxis[1].Max=gd->UndoBuf[n].yMax; gd->RAxis[2].Min=gd->UndoBuf[n].zMin; gd->RAxis[2].Max=gd->UndoBuf[n].zMax; for (i=0; iRAxis); i++) { for (j=0; j<2; j++) { sprintf(b,"%g",gd->RAxis[i].Limits[j]); MemFree(gd->Axis[i].pText[j]); gd->Axis[i].pText[j]=StringSave(b); } if (gd->Axis[i].bLimits) for (j=0; j<2; j++) SetTitle(gd->teAxis[i].teLimits[j],gd->Axis[i].pText[j]); } lRefreshScale(wcd); } #if _WIN #pragma argsused #endif Callback(Boolean) lUndoScale_Status(Int2 index) { WinComDataPtr wcd=GetComDataI; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; return gd->UndoNum>0; } /*----------------------------*/ /* Menu callback: Undo rotate */ Local(void) UndoRRecord(WinComDataPtr wcd) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Int2 i,n=gd->UndoRNum; if (gd->UndoRBuf) { if (gd->UndoRBuf[n].theta!=gd->Options.Theta || gd->UndoRBuf[n].phi!=gd->Options.Phi) { if (n==UNDODEPTH-1) for (i=0; iUndoRBuf[i]=gd->UndoRBuf[i+1]; else n++; } else return; } else { gd->UndoRBuf=MemNew(ARRAYSIZE(UndoRElem,UNDODEPTH)); n=0; } gd->UndoRBuf[n].theta=gd->Options.Theta; gd->UndoRBuf[n].phi=gd->Options.Phi; gd->UndoRNum=n; SetStatusOfItems(&wcd->MenuDesc); } #if _WIN #pragma argsused #endif Callback(void) lUndoRotate(Int2 index) { WinComDataPtr wcd=GetComDataI; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; UndoRElem ue; FloatHi angle; Int2 i,n; Char b[20]; n=gd->UndoRNum; /* n>0! see UndoRotate_Status */ ue=gd->UndoRBuf[n]; for (i=n; i; i--) gd->UndoRBuf[i]=gd->UndoRBuf[i-1]; gd->UndoRBuf[0]=ue; gd->Options.Theta=gd->UndoRBuf[n].theta; gd->Options.Phi=gd->UndoRBuf[n].phi; for (i=0; i<2; i++) { angle=i==0 ? gd->Options.Theta : gd->Options.Phi; angle*=180/PI; sprintf(b,"%g",angle); MemFree(gd->pAngle[i]); gd->pAngle[i]=StringSave(b); if (gd->Axis[0].bAngles) SetTitle(gd->teAngle[i].teAngle,gd->pAngle[i]); } lRefreshScale(wcd); } #if _WIN #pragma argsused #endif Callback(Boolean) lUndoRotate_Status(Int2 index) { WinComDataPtr wcd=GetComDataI; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; return gd->UndoRNum>0; } /*----------------------------------*/ /* Menu callback: Layout dialog box */ typedef struct { WinComDataPtr Com; /* Common data for all classes of windows */ Color Colors[2]; /* colors */ struct { CharPtr PNTR pTrace; /* to array of ptrs to all V-functions along the axis */ Boolean Prop[8]; /* must be == to DIM(GraphicWindow.Axis.Prop) */ TexT teText[4]; #define teMin teText[0] /* Min */ #define teMax teText[1] /* Max */ #define teFunc teText[2] /* V-Func (currently available for editing) */ #define teTick teText[3] /* Tick */ ButtoN cbProp[8]; /* must be == to DIM(GraphicWindow.Axis.Prop) */ } Axis[3]; struct { TexT teText; #define teTheta Angle[0].teText #define tePhi Angle[1].teText } Angle[2]; /* 0 - theta, 1 - phi */ FuncAttrPtr Attr; /* to array of points,traces,paths atributes */ Int2 CurPair; /* current V-function pair */ Int2 NumPair; /* number of pairs */ TexT Title; /* WinTitle */ TexT teInsertTo; /* text for insertion */ ButtoN buDelFun; BaR scBar; /* scroll bar for V-func pair selection */ PrompT ptFuncNum; /* ordinal no of functions pair indicator */ GrouP grAttrOf; /* 'Set attributes of' group */ ButtoN buAttrOf[4]; /* 0-points, 1-paths, 2-traces, 3-shifts */ GrouP grStyle; /* Group for join: no/solid/dotted */ GrouP grWidth; /* Group for width: 0-9 */ ButtoN buColor; /* Button for set color */ ButtoN cbClear; /* 'Clear before each point' button */ ButtoN cbPalette; /* 'Show palette in window' */ PaneL paSample; /* Panel to display a sample of window */ PaneL paLimits,paPalette,paDraw; /* and its superimposed parts */ /* Fields related to attributes of current curve */ #if MYSWITCH Switch swSegment; /* Current curve's attrs: 'segment numer' SwitcH */ #else SwitcH swSegment; /* Current curve's attrs: 'segment numer' SwitcH */ #endif PrompT prFrom; /* types of endpoints for current segment */ PrompT prTo; #if MYSWITCH Switch swAttr; /* current attributes (CurPair) */ #else SwitcH swAttr; /* current attributes (CurPair) */ #endif Int2 spnum,spcur; /* number of special points and current */ DataLibPosPtr splist; /* list of DataLib ptrs to special points */ ByteStorePtr PNTR spbs; /* ByteStorePtrs for attrs for all curve's segments */ /* End of fields related to attributes of current curve */ Int2 SampleHeight; ShowOptions Options; Uint1 Kind; /* options of: 0-current, 1-layout, 2-current curve */ Boolean Recompile; /* set to TRUE if a window function has been changed */ Uint1 Lock; /* to prevent recursion in SampleProc */ } LayoutData, PNTR LayoutDataPtr; #define GetLayoutData(h) ((LayoutDataPtr)GetWindowExtra(ParentWindow(h))) Local(Boolean) StdPrmt=TRUE; /* Creates a StaticPrompt */ Local(PrompT) CreatePrompt(GrouP g, Int2 key) { return StaticPrompt(g,key>=0 ? Text[key] : "",0,StdPrmt ? dialogTextHeight : 0,NULL,'l'); } /* The current V-function has been changed */ Callback(void) FuncChanged(TexT t) { LayoutDataPtr layout=GetLayoutData(t); Int2 i; layout->Recompile=TRUE; for (i=0; iAxis); i++) if (t==layout->Axis[i].teFunc) { GetTitleAndSave(t,&layout->Axis[i].pTrace[layout->CurPair]); break; } } Callback(void) NamesListProc(LisT l, Int2 var) { LayoutDataPtr layout=GetLayoutData(l); CharPtr p; CharPtr t; size_t len; Int2 b,e; if (layout->teInsertTo) { p=StringSave(((CharPtr PNTR)GetObjectExtra(l))[var-1]); len=TextLength(layout->teInsertTo)+StrLen(p)+1; t=MemNew(len); GetTitle(layout->teInsertTo,t,len); TextSelectionRange(layout->teInsertTo,&b,&e); StrCpy(t,p); b=0; SetTitle(layout->teInsertTo,t); len=b+StrLen(p); SelectText(layout->teInsertTo,(Int2)len,(Int2)len); MemFree(t); MemFree(p); FuncChanged(layout->teInsertTo); /* inform it text has been changed */ } } /* Just set teInsert for NamesListProc (see above)*/ Callback(void) MarkSelection(TexT t) { LayoutDataPtr layout=GetLayoutData(t); layout->teInsertTo=t; } Local(void) ShowGrAttributes(LayoutDataPtr layout, Int2 i) { DrawAttrPtr pda; switch (i) { case 0: pda=&layout->Attr[layout->CurPair].Point; break; case 1: pda=&layout->Attr[layout->CurPair].Path; break; case 2: pda=&layout->Attr[layout->CurPair].Trace; break; case 3: pda=&layout->Options.Shift; break; default: return; } SetValue(layout->grStyle,MAX(pda->style,0)+1); SetValue(layout->grWidth,pda->width+1); #if _WIN if (pda->width>1 && pda->style>1) { /* only solid in such cases */ pda->style=1; SetValue(layout->grStyle,pda->style+1); Beep(); } #endif /* _WIN */ if (i) Enable(layout->grStyle); else Disable(layout->grStyle); if (i==0 || pda->style>0) { Enable(layout->grWidth); Enable(layout->buColor); } else { Disable(layout->grWidth); Disable(layout->buColor); } } /* Show current curve's attributes */ Local(void) ShowAttributes(LayoutDataPtr layout, Boolean redraw) { Char buf[8]; Int2 i,j; switch (layout->Kind) { case 0: /* current */ case 2: /* curve */ if (layout->Kind==0) { /* current */ for (i=0; iAxis); i++) SetTitle(layout->Axis[i].teFunc,layout->Axis[i].pTrace[layout->CurPair]); } ShowGrAttributes(layout,GetValue(layout->grAttrOf)-1); if (layout->Kind==0) { /* current */ CorrectBarValue(layout->scBar,layout->CurPair); SelectText(layout->teInsertTo=layout->Axis[0].teFunc,0,0); (layout->NumPair>1 ? Enable : Disable)(layout->buAttrOf[3]); /* shifts */ SetStatus(layout->cbClear,(Boolean)(layout->Options.Flags&GWIN_CLEAR)); } else { #if MYSWITCH SwitchSetParams(layout->swAttr,layout->CurPair+1,layout->NumPair); #else SetSwitchParams(layout->swAttr,layout->CurPair+1,layout->NumPair); #endif } (layout->NumPair>1 && !ccd.Computing ? Enable : Disable)(layout->buDelFun); if (layout->NumPair>99) StrCpy(buf,"**/**"); else sprintf(buf,"%i/%i",layout->CurPair+1,layout->NumPair); SetTitle(layout->ptFuncNum,buf); break; case 1: /* axes */ for (i=0; iAxis); i++) { for (j=0; jAxis[i].Prop); j++) SetStatus(layout->Axis[i].cbProp[j],layout->Axis[i].Prop[j]); (layout->Axis[i].Prop[0] ? Enable : Disable)(layout->Axis[i].cbProp[1]); /* Tick depends on Limits */ } SetStatus(layout->cbPalette,(Boolean)(layout->Options.Flags&GWIN_PALETTE)); break; } if (redraw) Redraw(layout->paSample); } /* Add/Del functions button callbacks */ Local(void) AddFunProc(ButtoN bu) { LayoutDataPtr layout=GetLayoutData(bu); WinComDataPtr wcd=layout->Com; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; DrawAttr dattr; Int2 i; for (i=0; iAxis); i++) { layout->Axis[i].pTrace=MemMore(layout->Axis[i].pTrace,ARRAYSIZE(CharPtr,layout->NumPair+1)); layout->Axis[i].pTrace[layout->NumPair]=StringSave("?"); } layout->Attr=MemMore(layout->Attr,ARRAYSIZE(FuncAttr,layout->NumPair+1)); dattr.color=wcd->Foreground; dattr.width=2; dattr.style=-1; layout->Attr[layout->NumPair].Point=dattr; layout->Attr[layout->NumPair].Trace=dattr; dattr.style=1; layout->Attr[layout->NumPair].Path=dattr; if (layout->Kind==0) { /* current */ layout->Recompile=TRUE; CorrectBarMax(layout->scBar,layout->NumPair); } else { /* curve */ gd->Attr=MemMore(gd->Attr,ARRAYSIZE(FuncAttr,layout->NumPair+1)); gd->FuncNum++; } layout->CurPair=layout->NumPair++; ShowAttributes(layout,TRUE); } Local(void) DelFunProc(ButtoN bu) { LayoutDataPtr layout=GetLayoutData(bu); WinComDataPtr wcd=layout->Com; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Int2 i; /* it is always layout->NumPair>1; otherwise the button is hidden */ if (layout->NumPair<=1) { /* It is quite possible (in UNIX at least): press AddFunction twice and then QUICKLY press DelFunction three times. */ return; } layout->NumPair--; for (i=0; iAxis); i++) { MemFree(layout->Axis[i].pTrace[layout->CurPair]); MemMove(&layout->Axis[i].pTrace[layout->CurPair], &layout->Axis[i].pTrace[layout->CurPair+1], ARRAYSIZE(CharPtr,layout->NumPair-layout->CurPair)); layout->Axis[i].pTrace=MemMore(layout->Axis[i].pTrace,ARRAYSIZE(CharPtr,layout->NumPair)); } MemMove(layout->Attr+layout->CurPair,layout->Attr+layout->CurPair+1, ARRAYSIZE(FuncAttr,layout->NumPair-layout->CurPair)); layout->Attr=MemMore(layout->Attr,ARRAYSIZE(FuncAttr,layout->NumPair)); if (layout->NumPair==layout->CurPair) layout->CurPair--; if (layout->Kind==0) { /* current */ layout->Recompile=TRUE; } else { /* curve */ gd->Attr=MemMore(gd->Attr,ARRAYSIZE(FuncAttr,layout->NumPair)); gd->FuncNum--; } ShowAttributes(layout,TRUE); if (layout->Kind==0) { /* current */ CorrectBarMax(layout->scBar,layout->NumPair-1); /* ShowAttributes() decreased scBar value */ } } #if _WIN #pragma argsused #endif /* V-func pair scroll bar callback */ Callback(void) SelFuncPairProc(BaR bar, GraphiC graphic, Int2 new, Int2 old) { LayoutDataPtr layout; if (new!=old) { layout=GetLayoutData(bar); layout->CurPair=new; ShowAttributes(layout,TRUE); } } /* Palette/Clear common callback */ Callback(void) PCCProc(ButtoN bu) { LayoutDataPtr layout=GetLayoutData(bu); Uint1 fl; if (bu==layout->cbPalette) fl=GWIN_PALETTE; if (bu==layout->cbClear) fl=GWIN_CLEAR; if (GetStatus(bu)) layout->Options.Flags|=fl; else layout->Options.Flags&=~fl; Redraw(layout->paSample); } /* cbClear checkbox callback */ #define ClearProc PCCProc /* cbPalette checkbox callback */ #define ShowPaletteProc PCCProc /* grAttrOf callback */ #if _WIN #pragma argsused #endif Callback(void) SetAttrOfProc(GrouP gr) { LayoutDataPtr layout=GetLayoutData(gr); ShowAttributes(layout,FALSE); } /* grWidth callback */ Callback(void) WidthProc(GrouP grWidth) { LayoutDataPtr layout=GetLayoutData(grWidth); Uint1 width; width=(Uint1)GetValue(grWidth)-1; switch (GetValue(layout->grAttrOf)) { case 1: /* Points */ layout->Attr[layout->CurPair].Point.width=width; break; case 2: /* Paths */ layout->Attr[layout->CurPair].Path.width=width; break; case 3: /* Traces */ layout->Attr[layout->CurPair].Trace.width=width; break; case 4: /* Shifts */ layout->Options.Shift.width=width; break; } ShowAttributes(layout,TRUE); } /* grStyle callback */ Callback(void) StyleProc(GrouP grStyle) { LayoutDataPtr layout=GetLayoutData(grStyle); Int1 style; style=(Int1)GetValue(grStyle)-1; switch (GetValue(layout->grAttrOf)) { case 1: /* Points - impossible */ break; case 2: /* Paths */ layout->Attr[layout->CurPair].Path.style=style; break; case 3: /* Traces */ layout->Attr[layout->CurPair].Trace.style=style; break; case 4: /* Shifts */ layout->Options.Shift.style=style; break; } ShowAttributes(layout,TRUE); } /* cbProp[1-8] callback */ Callback(void) PropProc(ButtoN bu) { LayoutDataPtr layout=GetLayoutData(bu); Int2 i=0,j; for (j=0; jAxis[i].Prop); j++) if (bu==layout->Axis[i].cbProp[j]) { layout->Axis[i].Prop[j]=GetStatus(bu); ShowAttributes(layout,TRUE); break; } } #define LimitProc PropProc /* Draw palette */ Local(void) PaletteProc(PaneL pnl) { RecT r; Int2 w,i,n; Select(pnl); GetPosition(pnl,&r); n=ColorNumber(); if (!(w=(r.right-r.left)/n)) w=1; for (i=0; iAxis); i++) { if (layout->Axis[0].bLimits) { r.left=off; off+=StringWidth(StrCpy(Buf,layout->Axis[i].pTrace[layout->CurPair]))+2; r.right=off; DrawString(&r,Buf,'l',FALSE); for (j=0; j<4; j++) { if (FuncIndex(j)) continue; if (j==3 && !layout->Axis[0].bTick) continue; r.left=off; off+=StringWidth(SampLims[i][j])+(sysCharWidth/4); r.right=off; DrawString(&r,SampLims[i][j],'c',FALSE); FrameRect(&r); off+=2; } off+=sysCharWidth/2; } } for (i=0; iAngle); i++) { if (layout->Axis[0].bAngles) { r.left=off; SelectFont(SymFont); off+=StringWidth(StrCpy(Buf,i==0 ? THETA_STR : PHI_STR))+2; r.right=off; DrawString(&r,Buf,'l',FALSE); SelectFont(SystemFont); r.left=off; off+=StringWidth(SampAngs[i])+(sysCharWidth/4); r.right=off; DrawString(&r,SampAngs[i],'c',FALSE); FrameRect(&r); off+=sysCharWidth/2; } } } #define SamplePaletteProc PaletteProc #define D3 1 /* 'new' i.e. true 3D sample */ #define GPN 5 /* number of G-points */ #define MPN 10 /* number of M-points in the first G-point */ #define MPR 1.0/(GPN) /* radius of M-points in the first G-point */ #define MPRI 1.0/(GPN) /* increment of radius */ #if D3 Local(FloatHi) SampleXval,SampleYval,SampleZval; Local(FloatHi) SampleC[3],SampleR[3]; #if _WIN #pragma argsused #endif Entry(FloatHi) SampleXaxis(FloatHiPtr PNTR PNTR ptr) { return SampleXval; } #if _WIN #pragma argsused #endif Entry(FloatHi) SampleYaxis(FloatHiPtr PNTR PNTR ptr) { return SampleYval; } #if _WIN #pragma argsused #endif Entry(FloatHi) SampleZaxis(FloatHiPtr PNTR PNTR ptr) { return SampleZval; } #else /* D3 */ Local(Int2) Ox,Oy,Dx,Dy; #endif /* D3 */ #define GATHER 0 /* setting to 1 will create data file */ #if GATHER #include FILE *deb; #endif typedef struct {FloatLo cos,sin;} fPair; #if D3 Local(fPair) Data[1][MPN+1]={ { {1,0}, {0.809204,0.587528}, {0.309623,0.950859}, {-0.308108,0.951351}, {-0.808267,0.588815}, {-0.999999,0.00159255}, {-0.810139,-0.586238}, {-0.311137,-0.950365}, {0.306593,-0.951841}, {0.807329,-0.590102}, {0.999995,-0.00318509} } }; #else /* D3 */ Local(fPair) Data[GPN][MPN+1]={ { {1,0}, {0.809204,0.587528}, {0.309623,0.950859}, {-0.308108,0.951351}, {-0.808267,0.588815}, {-0.999999,0.00159255}, {-0.810139,-0.586238}, {-0.311137,-0.950365}, {0.306593,-0.951841}, {0.807329,-0.590102}, {0.999995,-0.00318509} }, { {0.951106,0.308866}, {0.588172,0.808736}, {0.000796274,1}, {-0.586883,0.809672}, {-0.950613,0.31038}, {-0.951596,-0.30735}, {-0.589459,-0.807798}, {-0.00238894,-0.999997}, {0.585593,-0.810606}, {0.950117,-0.311893}, {0.952085,0.305834} }, { {0.809204,0.587528}, {0.309623,0.950859}, {-0.308108,0.951351}, {-0.808267,0.588815}, {-0.999999,0.00159255}, {-0.810139,-0.586238}, {-0.311137,-0.950365}, {0.306593,-0.951841}, {0.807329,-0.590102}, {0.999995,-0.00318509}, {0.811072,0.584947} }, { {0.588172,0.808736}, {0.000796274,1}, {-0.586883,0.809672}, {-0.950613,0.31038}, {-0.951596,-0.30735}, {-0.589459,-0.807798}, {-0.00238894,-0.999997}, {0.585593,-0.810606}, {0.950117,-0.311893}, {0.952085,0.305834}, {0.590745,0.806859} }, { {0.309623,0.950859}, {-0.308108,0.951351}, {-0.808267,0.588815}, {-0.999999,0.00159255}, {-0.810139,-0.586238}, {-0.311137,-0.950365}, {0.306593,-0.951841}, {0.807329,-0.590102}, {0.999995,-0.00318509}, {0.811072,0.584947}, {0.31265,0.949868} } }; #endif /* D3 */ #if D3 Local(void) GetCoord(Int2 Gp, Int2 Mp) { #else Local(void) GetCoord(Int2 Gp, Int2 Mp, Int2Ptr x, Int2Ptr y) { #endif #if GATHER FloatLo fi; fi=(1.57*Gp/GPN+6.28*Mp/MPN); *x=Ox+Dx*(MPR+Gp*MPRI)*cos(fi); *y=Oy+Dy*(MPR+Gp*MPRI)*sin(fi); fprintf(deb,"%2i %2i %g %g\n",Gp,Mp,cos(fi),sin(fi)); #else /* GATHER */ #if D3 FloatLo fr=pow(MPR+Gp*MPRI,0.5); SampleXval=SampleC[0]+SampleR[0]*fr*Data[0][Mp].cos; SampleYval=SampleC[1]+SampleR[1]*fr*Data[0][Mp].sin; /*** SampleZval=pow(SampleXval-SampleC[0],2)-pow(SampleYval-SampleC[1],2)-SampleC[2];***/ SampleZval=(SampleC[2]-SampleR[2])+(Gp*MPRI)*2*SampleR[2]; #else /* D3 */ *x=Ox+Dx*(MPR+Gp*MPRI)*Data[Gp][Mp].cos; *y=Oy+Dy*(MPR+Gp*MPRI)*Data[Gp][Mp].sin; #endif /* D3 */ #endif /* GATHER */ } Local(void) CopyFromWork(WinComDataPtr wcd, LayoutDataPtr layout); Callback(void) SampleDrawProc(PaneL paDraw) { LayoutDataPtr layout=GetLayoutData(paDraw); WinComData foolwcd; GraphicData foolgd; #if D3 #else /* D3 */ DrawAttr flowers; FuncAttr Attr; Int2 ix,iy,ox,oy; #endif /* D3 */ WindoW attrwin=ParentWindow(paDraw); VoidPtr saveExtra=GetWindowExtra(attrwin); RecT r; Int2 Kind; Int2 i,j; Boolean Recompile; Select(paDraw); GetPosition(paDraw,&r); /* Use GraphDrawProc and VisualizerGPoint to draw the Sample */ /* 1. Fool GraphDrawProc before call */ MemFill(&foolwcd,0,sizeof(WinComData)); MemFill(&foolgd,0,sizeof(GraphicData)); foolwcd.Private=&foolgd; /* 2. Fill in foolwcd from layout */ Recompile=layout->Recompile; layout->Recompile=TRUE; Kind=layout->Kind; layout->Kind=0; CopyFromWork(&foolwcd,layout); layout->Kind=Kind; layout->Recompile=Recompile; MemMove(&foolwcd.Colors,layout->Colors,sizeof(foolwcd.Colors)); for (i=0; iAttr[layout->CurPair]; foolgd.FuncNum=1; foolwcd.flags|=WFL_G1; GInit(&foolwcd); for (j=0; j>1; Oy=(r.bottom+r.top)>>1; Dx=(r.right-r.left+1)>>1; Dy=(r.bottom-r.top+1)>>1; Attr=layout->Attr[layout->CurPair]; flowers.color=layout->Foreground; flowers.width=1; flowers.style=1; #if GATHER deb=fopen("deb","wt"); #endif for (j=0; jOptions.Flags&GWIN_CLEAR) { SetCurrentPen(&flowers); DrawProc(paDraw); } /* Join current point with the previous one along a trace */ if (Attr.Trace.style>0 && IsDimGMore1()) { SetCurrentPen(&Attr.Trace); ix=Dx*(MPR+j*MPRI); iy=Dy*(MPR+j*MPRI); LoadRect(&r,Ox-ix-1,Oy-iy-1,Ox+ix+1,Oy+iy+1); FrameOval(&r); } SetCurrentPen(&Attr.Point); for (i=0; i0) { if (j) { GetCoord(j-1,i,&ox,&oy); SetCurrentPen(&Attr.Path); lLine(ix,iy,ox,oy); SetCurrentPen(&Attr.Point); lPoint(ox,oy); } } /* It is not clear how to illustrate 'join along shift' */ /* Plot the current point */ lPoint(ix,iy); } } #endif /* D3 */ /* 5. Restore everything. This does not write but frees memory only */ WriteDescription(&foolwcd,NULL); SetWindowExtra(attrwin,saveExtra,NULL); #if GATHER fclose(deb); #endif } Callback(void) SampleProc(PaneL sample) { LayoutDataPtr layout=GetLayoutData(sample); RecT r; Int2 y; Int2 j; if (layout->Lock) return; layout->Lock=1; Hide(layout->paDraw); Hide(layout->paPalette); Hide(layout->paLimits); GetPosition(sample,&r); y=r.top; j=layout->SampleHeight; /* Limits sample */ if (layout->Axis[0].bLimits || layout->Axis[0].bAngles) { GetPosition(layout->paLimits,&r); r.bottom+=y-r.top; r.top=y; SetPosition(layout->paLimits,&r); Show(layout->paLimits); j-=r.bottom-r.top; y+=r.bottom-r.top; } /* Palette sample */ if (layout->Options.Flags&GWIN_PALETTE) { GetPosition(layout->paPalette,&r); r.bottom+=y-r.top; r.top=y; SetPosition(layout->paPalette,&r); Show(layout->paPalette); j-=r.bottom-r.top; /*** y+=r.bottom-r.top;***/ } /* Draw sample */ GetPosition(layout->paDraw,&r); r.top=r.bottom-j; SetPosition(layout->paDraw,&r); Show(layout->paDraw); layout->Lock=0; } Callback(void) SetFGColor(ButtoN bt) { LayoutDataPtr layout=GetLayoutData(bt); layout->Foreground=ColorAsk(layout->Foreground); ShowAttributes(layout,TRUE); } Callback(void) SetBGColor(ButtoN bt) { LayoutDataPtr layout=GetLayoutData(bt); layout->Background=ColorAsk(layout->Background); ShowAttributes(layout,TRUE); } /* Activate/Deactivate segment (called be Copy To/From Work and switch callback). */ Local(void) ActivateSegment(LayoutDataPtr layout, Int2 s) { WinComDataPtr wcd=layout->Com; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Int2 i,k; Pointtype ptype; /* local code of the type of a special point */ layout->spcur=s; BSSeek(layout->spbs[s-1],0,SEEK_SET); RestoreVisualAttr(&DiagramLib,layout->spbs[s-1],NULL); if (!gd->FuncNum) { /* This window was created AFTER the active curve was stored/edited */ gd->FuncNum=gd->SaveFuncNum; gd->Attr=MemNew(ARRAYSIZE(FuncAttr,gd->FuncNum)); MemMove(gd->Attr,gd->SaveAttr,ARRAYSIZE(FuncAttr,gd->FuncNum)); } layout->NumPair=gd->FuncNum; layout->CurPair=0; /* Copy V-functions (for show sample only!) */ for (i=0; iAxis); i++) { layout->Axis[i].pTrace=MemNew(ARRAYSIZE(CharPtr,layout->NumPair)); for (k=0; kNumPair; k++) layout->Axis[i].pTrace[k]=StringSave(k>=gd->SaveFuncNum ? "?" : gd->Axis[i].Funcs[k].pFunc); } #if MYSWITCH SwitchSetParams(layout->swAttr,1,layout->NumPair); #else SetSwitchParams(layout->swAttr,1,layout->NumPair); #endif /* Copy attributes of V-functions */ layout->Attr=MemNew(ARRAYSIZE(FuncAttr,layout->NumPair)); MemMove(layout->Attr,gd->Attr,ARRAYSIZE(FuncAttr,layout->NumPair)); /* Show endpoints' type */ if (s==1) SetTitle(layout->prFrom,Text[FP_P]); else { DataLibSeek(&DiagramLib,layout->splist+s-2); DataLibRead(&DiagramLib,(CharPtr)&ptype,sizeof(ptype)); SetTitle(layout->prFrom,GetSPname(ptype,TRUE)); } if (s==layout->spnum) SetTitle(layout->prTo,Text[LP_P]); else { DataLibSeek(&DiagramLib,layout->splist+s-1); DataLibRead(&DiagramLib,(CharPtr)&ptype,sizeof(ptype)); SetTitle(layout->prTo,GetSPname(ptype,TRUE)); } } Local(void) DeactivateSegment(LayoutDataPtr layout, Int2 s) { WinComDataPtr wcd=layout->Com; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Int2 i,k; BSFree(layout->spbs[s-1]); layout->spbs[s-1]=BSNew(0); MemMove(gd->Attr,layout->Attr,ARRAYSIZE(FuncAttr,layout->NumPair)); for (i=0; iAxis); i++) if (layout->Axis[i].pTrace) { for (k=0; kNumPair; k++) MemFree(layout->Axis[i].pTrace[k]); layout->Axis[i].pTrace=MemFree(layout->Axis[i].pTrace); } layout->Attr=MemFree(layout->Attr); SaveVisualAttr(&DiagramLib,NULL,layout->spbs[s-1],FALSE); } /* Segment number callback */ #if MYSWITCH Callback(void) SegmentProc(GraphiC sw, Int2 new, Int2 old) { #else Callback(void) SegmentProc(SwitcH sw, Int2 new, Int2 old) { #endif LayoutDataPtr layout=GetLayoutData(sw); DeactivateSegment(layout,old); ActivateSegment(layout,new); ShowAttributes(layout,TRUE); } #define AddAttrProc AddFunProc #define DelAttrProc DelFunProc /* Attributes number callback */ #if _WIN #pragma argsused #endif #if MYSWITCH Local(void) AttrProc(GraphiC sw, Int2 new, Int2 old) { #else Local(void) AttrProc(SwitcH sw, Int2 new, Int2 old) { #endif LayoutDataPtr layout=GetLayoutData(sw); layout->CurPair=new-1; ShowAttributes(layout,TRUE); } /* Copy visual attributes to/from layout work area and free it */ Local(void) CopyToWork(LayoutDataPtr layout, WinComDataPtr wcd) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Int2 i,k; if (layout->Kind==2) { /* attribs of active curve */ PushVisualAttr(TRUE); /* will be restored in GraphicFreeAttributes */ DataLibSavePos(&DiagramLib); ReadSPList(&layout->spnum,&layout->splist); #if MYSWITCH SwitchSetParams(layout->swSegment,1,layout->spnum); #else SetSwitchParams(layout->swSegment,1,layout->spnum); #endif ReadVAList(layout->spnum+1,&layout->spbs); ActivateSegment(layout,1); } else { /* Get memory for local editable copies of attributes */ layout->NumPair=gd->FuncNum; layout->CurPair=gd->FuncCur; /* Copy attributes of V-functions */ layout->Attr=MemNew(ARRAYSIZE(FuncAttr,layout->NumPair)); MemMove(layout->Attr,gd->Attr,ARRAYSIZE(FuncAttr,layout->NumPair)); /* Copy V-functions */ for (i=0; iAxis); i++) { layout->Axis[i].pTrace=MemNew(ARRAYSIZE(CharPtr,layout->NumPair)); for (k=0; kNumPair; k++) layout->Axis[i].pTrace[k]=StringSave(gd->Axis[i].Funcs[k].pFunc); } } for (i=0; iAxis); i++) MemMove(layout->Axis[i].Prop,gd->Axis[i].Prop,sizeof(layout->Axis[i].Prop)); /* Copy general attributes */ MemMove(layout->Colors,wcd->Colors,sizeof(layout->Colors)); layout->Options=gd->Options; } Local(void) CopyFromWork(WinComDataPtr wcd, LayoutDataPtr layout) { GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; Int2 i,j,k; Char Buf[PAR_BUF]; if (layout->Kind==2) { /* attribs of active curve */ /* First save current segment's attributes to spbs[...] */ DeactivateSegment(layout,layout->spcur); /* Now save to DiagramLib */ WriteVAList(layout->spnum+1,layout->spbs); return; } if (layout->Recompile) { /* a func was changed */ /* free old pair descriptors */ for (i=0; iAxis); i++) { for (k=0; kFuncNum; k++) MemFree(gd->Axis[i].Funcs[k].pFunc); MemFree(gd->Axis[i].Funcs); } MemFree(gd->Attr); /* Create new ones */ gd->FuncNum=layout->NumPair; for (i=0; iAxis); i++) { gd->Axis[i].Funcs=MemNew(ARRAYSIZE(AxisFunc,gd->FuncNum)); for (k=0; kFuncNum; k++) { StrTrim(layout->Axis[i].pTrace[k]); if (StrLen(layout->Axis[i].pTrace[k])==0) { CharPtr name; Int2 dim; MemFree(layout->Axis[i].pTrace[k]); GetNameAndDim(0,1,&name,&dim); sprintf(Buf,"%s%s",name,dim==1 ? "" : "[0]"); layout->Axis[i].pTrace[k]=StringSave(Buf); Warning("VI_EMPTY",Buf); } gd->Axis[i].Funcs[k].pFunc=StringSave(layout->Axis[i].pTrace[k]); } } gd->Attr=MemNew(ARRAYSIZE(FuncAttr,gd->FuncNum)); } MemMove(gd->Attr,layout->Attr,ARRAYSIZE(FuncAttr,gd->FuncNum)); for (i=0; iAxis); i++) MemMove(gd->Axis[i].Prop,layout->Axis[i].Prop,sizeof(gd->Axis[i].Prop)); gd->FuncCur=layout->CurPair; switch (layout->Kind) { case 0: /* current */ case 2: /* curve */ break; case 1: /* axes */ GetTitleAndSave(layout->Title,&wcd->WinTitle); for (i=0; iAxis); i++) for (j=0; jAxis[i].pText); j++) if (!FuncIndex(j)) GetTitleAndSave(layout->Axis[i].teText[j],&gd->Axis[i].pText[j]); for (i=0; ipAngle); i++) GetTitleAndSave(layout->Angle[i].teText,&gd->pAngle[i]); break; } /* Copy general attributes */ MemMove(wcd->Colors,layout->Colors,sizeof(wcd->Colors)); gd->Options=layout->Options; } Local(void) FreeWork(LayoutDataPtr layout) { Int2 i,k; if (layout->Kind==2) { FreeSPList(layout->spnum,layout->splist); FreeVAList(layout->spnum,layout->spbs); PopVisualAttr(); DataLibRestorePos(&DiagramLib); } for (i=0; iAxis); i++) if (layout->Axis[i].pTrace) { for (k=0; kNumPair; k++) MemFree(layout->Axis[i].pTrace[k]); MemFree(layout->Axis[i].pTrace); } MemFree(layout->Attr); } Local(void) CreateSampleGroup(GrouP parent, Int2 width, Int2 height) { LayoutDataPtr layout=GetLayoutData(parent); GrouP g; Int2 h; g=CreateNormalGroup(parent,0,0,Text[SAMPLE_WIN]); layout->SampleHeight=height; layout->paSample=SimplePanel(g,1,1,SampleProc); SelectFont(SymFont); h=LineHeight(); SelectFont(SystemFont); h=MAX(h,sysLineHeight); Hide(layout->paLimits=SimplePanel(g,width,h,SampleLimitsProc)); Hide(layout->paPalette=SimplePanel(g,width,sysLineHeight,SamplePaletteProc)); Hide(layout->paDraw=SimplePanel(g,width,height,SampleDrawProc)); } /* Cancel callback */ Callback(void) LayoutCancel(ButtoN bt) { LayoutDataPtr layout=GetLayoutData(bt); WinComDataPtr wcd=layout->Com; FreeWork(layout); PopContext(); MemFree(layout); Select(wcd->Win); Remove(ParentWindow(bt)); UnlockMenus(); } /* Ok callback */ Callback(void) LayoutOk(ButtoN bt) { LayoutDataPtr layout=GetLayoutData(bt); WinComDataPtr wcd=layout->Com; /* Remove old controls (they may depend on old options) */ RemoveControls(wcd); /* Get all attributes to wcd */ CopyFromWork(wcd,layout); /* wcd <== layout */ /* Rebuild all */ if (layout->Recompile) wcd->flags|=WFL_FUNC_EDITED; else wcd->flags&=~WFL_FUNC_EDITED; RecreateWindow(wcd); /* Clean up */ LayoutCancel(bt); } /* Help callback */ #if _WIN #pragma argsused #endif Callback(void) LayoutHelp(ButtoN bt) { Help(NULL); } /* Menu callback */ #if _WIN #pragma argsused #endif Callback(void) lLayout(Int2 indx) { WinComDataPtr wcd=GetComDataI; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; LayoutDataPtr layout; WindoW db; GrouP MainGroup,g,gT,gAxes,gA,gS,gColor,gAC; RecT r; Int2 i,j; Char buf[50]; int numwidth,textwidth,lines,linelen; layout=MemNew(sizeof(LayoutData)); layout->Com=wcd; layout->Kind=1; /* Layout of graphic window */ sscanf(Text[SIZES],"%i,%i,(%i,%i)",&numwidth,&textwidth,&lines,&linelen); LockMenus(); /* will not wait */ PushContext(HK_LAYOUTWIN,NULL,Text[WAITATTR_C]); db=FixedWindow(-50,-50,-sysCharWidth,-sysLineHeight,Text[LAYOUT_T],NULL); SetWindowExtra(db,layout,NULL); MainGroup=InitLargeWindow(db); SetGroupSpacing(MainGroup,0,sysLineHeight/2); SetGroupMargins(MainGroup,0,0); g=CreateHiddenGroup(MainGroup,2,0,1); gT=CreateHiddenGroup(g,2,0,1); CreatePrompt(gT,WINTITLE_P); layout->Title=DialogText(gT,wcd->WinTitle,1,NULL); CreatePrompt(g,-1); gS=CreateNormalGroup(g,2,0,Text[SHOWOPT_P]); /* Show in window */ sprintf(buf,"%s..%s",Text[MIN_P],Text[MAX_P]); layout->Axis[0].cbProp[0]=CheckBox(gS,buf,LimitProc); layout->Axis[0].cbProp[1]=CheckBox(gS,Text[TICK_P],PropProc); layout->Axis[0].cbProp[2]=CheckBox(gS,Text[SCALE_P],PropProc); layout->Axis[0].cbProp[3]=CheckBox(gS,Text[FUNC_P],PropProc); layout->Axis[0].cbProp[4]=CheckBox(gS,Text[BOX_P],PropProc); layout->Axis[0].cbProp[5]=CheckBox(gS,Text[AXIS_P],PropProc); layout->Axis[0].cbProp[6]=CheckBox(gS,Text[PROJ_P],PropProc); layout->Axis[0].cbProp[7]=CheckBox(gS,Text[ANGLES_P],PropProc); gAxes=CreateNormalGroup(g,4,0,Text[LIMOFVIS_T]); StdPrmt=FALSE; CreatePrompt(gAxes,-1); CreatePrompt(gAxes,MIN_P); CreatePrompt(gAxes,MAX_P); CreatePrompt(gAxes,TICK_P); StdPrmt=TRUE; for (i=0; iAxis); i++) { CreatePrompt(gAxes,ABS_P+i); for (j=0; jAxis[i].teText); j++) if (!FuncIndex(j)) layout->Axis[i].teText[j]=DialogText(gAxes,gd->Axis[i].pText[j],numwidth,NULL); } AlignObjects(ALIGN_LOWER,(HANDLE)gAxes,(HANDLE)gS,NULL); gAC=CreateHiddenGroup(g,0,2,1); gColor=CreateNormalGroup(gAC,0,-3,Text[COLORS_T]); PushButton(gColor,Text[FG_P],SetFGColor); PushButton(gColor,Text[BG_P],SetBGColor); layout->cbPalette=CheckBox(gColor,Text[SHOWPAL_P],ShowPaletteProc); GetPosition(gColor,&r); gA=CreateNormalGroup(gAC,2,0,Text[ANGLES_P]); for (i=0; iAngle); i++) { StaticPrompt(gA,i==0 ? THETA_STR : PHI_STR,0,dialogTextHeight,SymFont,'l'); layout->Angle[i].teText=DialogText(gA,gd->pAngle[i],numwidth,NULL); } AlignObjects(ALIGN_RIGHT,(HANDLE)gColor,(HANDLE)gA,(HANDLE)gS,NULL); CreateSampleGroup(g,1,5*(r.bottom-r.top)/3); AlignObjects(ALIGN_LOWER,(HANDLE)Parent(layout->paDraw),(HANDLE)gA, NULL); AlignObjects(ALIGN_RIGHT, (HANDLE)layout->Axis[0].teText[3], (HANDLE)layout->paLimits, (HANDLE)layout->paPalette, (HANDLE)layout->paDraw, (HANDLE)layout->Title, NULL); /* Create terminate buttons */ TerminalButtons((WindoW)MainGroup,MainGroup,LayoutOk,LayoutCancel,LayoutHelp); /* Fill in work area with temporary copies of options */ CopyToWork(layout,wcd); /* Show and activate */ ShowAttributes(layout,TRUE); ShowLargeWindow(MainGroup); } /*-----------------------------*/ /* Current attributes callback */ Callback(void) SetGraphicAttrColor(ButtoN bt) { LayoutDataPtr layout=GetLayoutData(bt); ColorPtr cp; switch(GetValue(layout->grAttrOf)) { case 1: /* Points */ cp=&layout->Attr[layout->CurPair].Point.color; break; case 2: /* Path */ cp=&layout->Attr[layout->CurPair].Path.color; break; case 3: /* Trace */ cp=&layout->Attr[layout->CurPair].Trace.color; break; case 4: /* Shift */ cp=&layout->Options.Shift.color; } *cp=ColorAsk(*cp); ShowAttributes(layout,TRUE); } Local(GrouP) OptionsGroup(LayoutDataPtr layout, GrouP parent) { GrouP g,gw; int i; Char b[5]; g=CreateNormalGroup(parent,0,4,Text[ATTR_T]); layout->grAttrOf=gw=CreateNormalGroup(g,2,0,Text[ATTROF_T]); SetAction(gw,(ActnProc)SetAttrOfProc); layout->buAttrOf[0]=RadioButton(gw,Text[POINTS_P]); layout->buAttrOf[1]=RadioButton(gw,Text[PATHS_P]); layout->buAttrOf[2]=RadioButton(gw,Text[TRACES_P]); if (!IsDimGMore1()) Disable(layout->buAttrOf[2]); /* Traces */ if (layout->Kind==0) layout->buAttrOf[3]=RadioButton(gw,Text[SHIFTS_P]); SetValue(gw,1); /* Points */ layout->grStyle=gw=CreateNormalGroup(g,3,0,Text[JOIN_T]); SetAction(gw,(ActnProc)StyleProc); RadioButton(gw,Text[NO_B]); RadioButton(gw,Text[SOLID_B]); RadioButton(gw,Text[DOTTED_B]); layout->grWidth=gw=CreateNormalGroup(g,5,0,Text[WIDTH_P]); SetAction(gw,(ActnProc)WidthProc); for (i=0; i<10; i++) { sprintf(b,"%i",i); RadioButton(gw,b); } PushButton(g,Text[COLOR_B],SetGraphicAttrColor); return g; } Callback(void) lCurrentAtr(Int2 indx) { WinComDataPtr wcd=GetComDataI; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; LayoutDataPtr layout; WindoW db; GrouP MainGroup,g,gA; GrouP gFunctions,gAJB,gB,gSWSC,gSWS,gOptions; ButtoN bu; LisT list=NULL; /* for Kind==2 */ RecT r,rr; CharPtr helpkey; Int2 i,ti; int numwidth,textwidth,lines,linelen; layout=MemNew(sizeof(LayoutData)); layout->Com=wcd; if (GraphicMenu[indx].Title==CURRENTATR_I) { layout->Kind=0; /* Current visual attributes */ helpkey=KH_CURRENTATTR; ti=DRAWATTR_T; } if (GraphicMenu[indx].Title==CURVEATR_I) { layout->Kind=2; /* Curve's visual attributes */ helpkey=KH_CURVEATTR; ti=CURVEATTR_T; } sscanf(Text[SIZES],"%i,%i,(%i,%i)",&numwidth,&textwidth,&lines,&linelen); LockMenus(); /* will not wait */ PushContext(helpkey,NULL,Text[WAITATTR_C]); db=FixedWindow(-50,-50,-sysCharWidth,-sysLineHeight,Text[ti],NULL); SetWindowExtra(db,layout,NULL); MainGroup=InitLargeWindow(db); SetGroupSpacing(MainGroup,0,sysLineHeight/2); SetGroupMargins(MainGroup,0,0); if (layout->Kind==2) { /* attribs of active curve */ Int2 wid; PrompT prm; wid=StringWidth(Text[SEG_P]); i=StringWidth(Text[SPF_P]); if (widswSegment=SwitchCreate(g,10,SegmentProc); #else StaticPrompt(g,Text[SEG_P],wid,0,NULL,'l'); layout->swSegment=LeftRightSwitch(g,TRUE,SegmentProc); #endif StaticPrompt(g,Text[SPF_P],wid,0,NULL,'l'); layout->prFrom=StaticPrompt(g,"",0,0,NULL,'l'); StaticPrompt(g,Text[SPT_P],wid,0,NULL,'l'); layout->prTo=StaticPrompt(g,"",0,0,NULL,'l'); g=CreateHiddenGroup(g,4,0,0); SetGroupMargins(g,0,0); #if MYSWITCH prm=StaticPrompt(g,Text[AN_P],wid,SwitchHeight(),NULL,'l'); layout->swAttr=SwitchCreate(g,10,AttrProc); #else StaticPrompt(g,Text[AN_P],wid,0,NULL,'l'); layout->swAttr=LeftRightSwitch(g,TRUE,AttrProc); #endif bu=PushButton(g,Text[AA_B],AddAttrProc); if (ccd.Computing) Hide(bu); layout->buDelFun=PushButton(g,Text[DA_B],DelAttrProc); GetPosition(bu,&rr); i=rr.bottom-rr.top; GetPosition(layout->swAttr,&r); i=(i-r.bottom+r.top)/2; if (i>0) { OffsetRect(&r,0,i-(r.top-rr.top)); SetPosition(layout->swAttr,&r); GetPosition(prm,&r); OffsetRect(&r,0,i-(r.top-rr.top)); SetPosition(prm,&r); } } else { /* V-functions group */ gFunctions=CreateNormalGroup(MainGroup,-2,0,Text[CURVES_P]); gAJB=CreateHiddenGroup(gFunctions,0,3,1); gA=CreateHiddenGroup(gAJB,3,0,0); SetGroupSpacing(gA,0,0); CreatePrompt(gA,ABS_P); layout->Axis[0].teFunc=DialogText(gA,"",textwidth,FuncChanged); SetTextSelect(layout->Axis[0].teFunc,MarkSelection,NULL); layout->scBar=ScrollBar(gA,0,1,SelFuncPairProc); CorrectBarMax(layout->scBar,gd->FuncNum-1); /* [0..FuncNum-1] */ CreatePrompt(gA,ORD_P); layout->Axis[1].teFunc=DialogText(gA,"",textwidth,FuncChanged); SetTextSelect(layout->Axis[1].teFunc,MarkSelection,NULL); StaticPrompt(gA,"",0,0,NULL,'l'); /* filler */ CreatePrompt(gA,APP_P); layout->Axis[2].teFunc=DialogText(gA,"",textwidth,FuncChanged); SetTextSelect(layout->Axis[2].teFunc,MarkSelection,NULL); gB=CreateHiddenGroup(gAJB,2,0,1); bu=PushButton(gB,Text[ADDFUN_B],AddFunProc); if (ccd.Computing) Hide(bu); layout->buDelFun=PushButton(gB,Text[DELFUN_B],DelFunProc); GetPosition(gAJB,&r); i=r.right-r.left; GetPosition(layout->buDelFun,&rr); i-=rr.right-rr.left; GetPosition(bu,&rr); i-=rr.right-rr.left; if (i>0) { i/=3; GetPosition(bu,&r); OffsetRect(&r,i-GetGroupSM("hmx"),0); SetPosition(bu,&r); GetPosition(layout->buDelFun,&r); OffsetRect(&r,2*i-GetGroupSM("hsx"),0); SetPosition(layout->buDelFun,&r); } else { Int2 n; GetPosition(layout->buDelFun,&r); GetPosition(layout->scBar,&rr); i=r.right-rr.right; GetPosition(layout->scBar,&r); OffsetRect(&r,i,0); SetPosition(layout->scBar,&r); for (n=0; nAxis); n++) { GetPosition(layout->Axis[n].teFunc,&r); r.right+=i; SetPosition(layout->Axis[n].teFunc,&r); } } layout->ptFuncNum=CreatePrompt(gAJB,FUNCNUM_P); GetPosition(gAJB,&r); i=r.bottom-r.top-sysLineHeight-2*GetGroupSM("nmy"); list=CreateNamesList(gFunctions,linelen,i/sysLineHeight,NamesListProc,NULL); } /* Graphic options and sample */ gSWSC=CreateHiddenGroup(MainGroup,2,0,0); gSWS=OptionsGroup(layout,gSWSC); GetPosition(Parent(gSWS),&r); i=r.bottom-r.top-2*GetGroupSM("nmy")-sysLineHeight; CreateSampleGroup(gSWSC,i,i); if (layout->Kind==0) { gOptions=CreateNormalGroup(MainGroup,0,2,Text[OPTIONS_P]); layout->cbClear=CheckBox(gOptions,Text[CLEAR_P],ClearProc); AlignObjects(ALIGN_RIGHT,(HANDLE)gFunctions,(HANDLE)gOptions,NULL); } else { AlignObjects(ALIGN_RIGHT,(HANDLE)layout->prFrom, (HANDLE)layout->prTo, (HANDLE)MainGroup, NULL); } AlignObjects(ALIGN_RIGHT,(HANDLE)layout->paLimits,(HANDLE)layout->paPalette,(HANDLE)layout->paDraw, (HANDLE)Parent(list), NULL); AlignObjects(ALIGN_LOWER,(HANDLE)layout->Axis[2].teFunc,(HANDLE)layout->scBar,NULL); /* Create terminate buttons */ TerminalButtons((WindoW)MainGroup,MainGroup,LayoutOk,LayoutCancel,LayoutHelp); /* Fill in work area with temporary copies of options */ CopyToWork(layout,wcd); /* Show and activate */ ShowAttributes(layout,TRUE); ShowLargeWindow(MainGroup); } /*-----------------------------*/ /* Curve's attributes callback */ Callback(void) lCurveAtr(Int2 indx) { lCurrentAtr(indx); } /*-------------------*/ /* Hardcopy callback */ typedef struct { WindoW wParent; TexT File; /* 'File name' prompt */ LisT Font; /* 'Font' list */ LisT Size; /* 'Size' list */ TexT Width_; TexT Height_; PopuP Unit; TexT LineWidthFactor; TexT CurveWidthFactor; TexT MarkerFactor; ButtoN Color; #if _UNIX ButtoN Preview; /* 'Preview' checkbox */ ButtoN Print; #endif Int2 oldunit; } hcOptData, PNTR hcOptDataPtr; #define MINSIZE 8 #define MAXSIZE 16 Callback(void) HardcopyCancel(ButtoN b) { WindoW optwin; hcOptDataPtr data; optwin=ParentWindow(b); data=(hcOptDataPtr)GetWindowExtra(optwin); Select(data->wParent); MemFree(data); Remove(optwin); UnlockMenus(); PopContext(); } Local(float) hcPageWidth, hcPageHeight; /* in Postscript's default units (1/72 of inch) */ Local(float) hcLineWidthFactor,hcCurveWidthFactor,hcMarkerFactor; Local(Int2) hcFontCur=1, hcFontSize=12; Local(Boolean) hcColor; /* whether to honor colors in hardcopy */ Local(float) hcUnitMult[]={72/25.4,72/2.54,72/1.0}; /* Hardcopy: PostScript */ Local(Char) hc_Header[]= "%%!PS-Adobe-3.0\n" "%%%%Creator: Content "VERSION"\n" "%%%%CreationDate: %s\n" "%%%%Pages:1\n" "%%%%BoundingBox: 0 0 %g %g\n" "%%%%EndComments\n\n" ; Local(Char) hc_ProcDef[]= "%%%%BeginProlog\n" "%%%%BeginResource: graphics\n\n" "%%margin[i]=v: [lm rm tm bm] i v PUT4 [lm rm tm bm]\n" "/PUT4 {\n" " 3 -1 roll aload pop\n" " 4 6 index 1 add neg roll\n" " 4 index exch pop 4 6 index 1 add roll\n" " 4 array astore exch pop exch pop\n" " } bind def\n\n" "%% PageWidth: - GPW hcPageWidth\n" "/GPW %g def\n" "%% PageHeight: - GPH hcPageHeight\n" "/GPH %g def\n" "%% MathXmin&MathXmax\n" "/GMXMINW %g def\n/GMXMAXW %g def\n" "%% MathYmin&MathYmax\n" "/GMYMINW %g def\n/GMYMAXW %g def\n" "%% MathWidth: - GMW Xmax-Xmin\n" "/GMWW {GMXMAXW GMXMINW sub} def\n" "/GMW GMWW def\n" "%% MathHeight: - GMH Ymax-Ymin\n" "/GMHW {GMYMAXW GMYMINW sub} def\n" "/GMH GMHW def\n" "%% CurveWidth: devwidth GCWIDTH userwidth\n" "/GCWIDTH {%g mul dup idtransform pop} bind def\n" "%% LineWidth: devwidth GLWIDTH userwidth\n" "/GLWIDTH {%g mul dup idtransform pop} bind def\n" "%% MarkerScale: userscale GMSCALE userscale\n" "/GMSCALE {%g mul 2 div} bind def\n" "%% Colors\n" "/ISCOLORW {systemdict /setrgbcolor known %s and} bind def\n" "/ISCOLOR ISCOLORW def\n" "/BWCOLOR 0 def\n" "/BWSWAP {/BWCOLOR 1 BWCOLOR sub def} bind def\n\n" "%% SetMathSpace: - GSETMATH oldmatrix\n" "/GSETMATH {matrix currentmatrix\n" " [ GPW GPLM sub GPRM sub GMW div 0 0" " GPH GPTM sub GPBM sub GMH div" " 3 index 1 index\n" " GMYMINW mul neg GPBM add exch GMXMINW mul neg GPLM add exch] \n" " matrix currentmatrix matrix concatmatrix setmatrix\n" " } bind def\n" "%% PageLeftMargin: - GPLM plm\n" "/GPLM {GP?M 0 get} bind def\n" "%% PageRightMargin: - GPRM prm\n" "/GPRM {GP?M 1 get} bind def\n" "%% PageTopMargin: - GPTM ptm\n" "/GPTM {GP?M 2 get} bind def\n" "%% PageBottomMargin: - GPBM pbm\n" "/GPBM {GP?M 3 get} bind def\n" "%% Set margins to 0: - MARGINS -\n" "/MARGINS [0 0 0 0] def\n" "%% Increase margins: inc INCxM -\n" "/INCLM {MARGINS 0 get add MARGINS 0 3 -1 roll put} bind def\n" "/INCRM {MARGINS 1 get add MARGINS 1 3 -1 roll put} bind def\n" "/INCTM {MARGINS 2 get add MARGINS 2 3 -1 roll put} bind def\n" "/INCBM {MARGINS 3 get add MARGINS 3 3 -1 roll put} bind def\n" "%% Union rect with page: l r t b CHECKM -\n" "/CHECKM {\n" " MARGINS 3 get add dup 0 lt {neg INCBM}{pop} ifelse\n" " MARGINS 2 get GPH add sub dup 0 gt {INCTM}{pop} ifelse\n" " MARGINS 1 get GPW add sub dup 0 gt {INCRM}{pop} ifelse\n" " MARGINS 0 get add dup 0 lt {neg INCLM}{pop} ifelse\n" " } bind def\n" "%% Blank margins (~2mm)\n" "/BM 5.67 def\n" "%% Set margins: [lm rm tm bm] SETMARGINS [lm rm tm bm]\n" "/SETMARGINS {\n" " 0 MARGINS 0 get BM add PUT4\n" " 1 MARGINS 1 get BM add PUT4\n" " 2 MARGINS 2 get BM add PUT4\n" " 3 MARGINS 3 get BM add PUT4\n" " } bind def\n" "%% xb yb xe ye CalcSinCos sin cos\n" "/CalcSinCos {\n" "COSSIN 2 copy dup mul exch dup mul add 0 gt\n" "{dup 0 le {neg exch neg exch} if} if\n" "exch\n" "} bind def\n" "%% xb yb xe ye [[x1 y1 (s1)]...] TextDiameter diameter\n" "/TextDiameter {\n" "5 1 roll CalcSinCos 3 -1 roll 0 exch\n" "{2 get stringwidth pop 3 index abs HGAP mul add\n" "GSTDHD 4 index abs mul add\n" "4 index 4 index abs GSPW\n" "2 copy lt {exch} if pop}\n" "forall\n" "3 1 roll pop pop\n" "} bind def\n" "%% DeltaR width height xb yb xe ye DeltaR dR\n" "/DeltaR {\n" "COSSIN\n" "dup 0 le {neg exch neg 1 add}\n" "{exch 1 add} ifelse\n" "dup dup mul 2 index dup mul add 0 eq {pop pop 180}{atan 2 mul} ifelse\n" "dup 45 div truncate 4 2 roll\n" "2 index 0 eq {pop 2 div neg 0} if\n" "2 index 1 eq {exch pop 0 exch 2 div} if\n" "2 index 2 eq {exch pop 2 div neg 0} if\n" "2 index 3 eq {pop 0 exch 2 div} if\n" "2 index 4 eq { pop 2 div dup} if\n" "1 index sub 4 -2 roll exch 45 div exch sub mul add\n" "} bind def\n" "%% Offset xb yb xe ye [[x y (s)]...] Offset xb yb xe ye [[x+dR*cos y+dR*sin (s)]...]\n" "/Offset {\n" "5 1 roll 4 copy CalcSinCos exch 0 8 -1 roll\n" "{exch 1 add exch\n" "aload 4 2 roll GSETMATH 3 1 roll moveto setmatrix currentpoint 4 -2 roll astore\n" "dup 2 get stringwidth pop 2 index 3 add index abs HGAP mul add\n" "GSTDHD 4 index 6 add index abs mul add\n" "3 index 9 add -4 roll 4 copy 11 index 13 add 4 roll DeltaR\n" "dup 3 index 4 add index mul exch 3 index 3 add index mul\n" "3 -1 roll aload pop 5 1 roll 3 -1 roll add 4 1 roll add 3 1 roll\n" "3 array astore exch\n" "} forall\n" "array astore 3 1 roll pop pop\n" "} bind def\n" "%% flag xb yb xe ye [[x1 y1 (s1)]...] CheckNums\n" "/CheckNums {\n" "Offset 6 1 roll CalcSinCos 4 -1 roll\n" "{dup 2 get stringwidth pop 3 index abs HGAP mul add\n" "GSTDHD 4 index abs mul add 3 2 roll aload pop pop\n" "%%fl=2: to the left\n" "6 index 2 eq {1 index 4 index sub 2 index 6 2 roll exch pop\n" "3 -1 roll pop exch 2 copy add 3 1 roll pop\n" "GSTDHD exch pop add} if\n" "%%fl=1: below\n" "6 index 1 eq {GSTDHD exch pop 5 index abs mul sub\n" " exch 5 index abs HGAP mul add\n" " dup 5 -1 roll add 4 2 roll dup 3 -1 roll sub} if\n" "%%fl=0: above\n" "6 index 0 eq {GSTDHD exch pop 5 index abs mul add\n" " exch 5 index abs HGAP mul add\n" " dup 5 -1 roll add 4 2 roll dup 3 -1 roll add exch} if\n" "CHECKM\n" "} forall\n" "pop pop pop\n" "} bind def\n" "%% flag xb yb xe ye [[x1 y1 (s1)]...] DrawNums -\n" "/DrawNums {\n" "Offset 6 1 roll CalcSinCos 4 -1 roll\n" "{dup 2 get stringwidth pop 3 index abs HGAP mul add\n" "GSTDHD 4 index abs mul add 3 2 roll aload pop 8 1 roll\n" "%%fl=2: to the left\n" "6 index 2 eq {1 index 4 index sub 2 index 6 2 roll exch pop\n" "3 -1 roll pop exch 2 copy add 3 1 roll pop\n" "GSTDHD exch pop add} if\n" "%%fl=1: below\n" "6 index 1 eq {GSTDHD exch pop 5 index abs mul sub\n" " exch 5 index abs HGAP mul add\n" " dup 5 -1 roll add 4 2 roll dup 3 -1 roll sub} if\n" "%%fl=0: above\n" "6 index 0 eq {GSTDHD exch pop 5 index abs mul add\n" " exch 5 index abs HGAP mul add\n" " dup 5 -1 roll add 4 2 roll dup 3 -1 roll add exch} if\n" "newpath\n" "3 1 roll pop pop\n" "moveto\n" "4 -1 roll\n" "show\n" "stroke\n" "} forall\n" "pop pop pop\n" "} bind def\n" "%% CheckLab: (lab) flag xb yb xe ye [[x1 y1 (s1)]...] CheckLab -\n" "/CheckLab {\n" "Offset 5 1 roll 4 copy 9 -1 roll TextDiameter\n" "5 1 roll 4 copy CalcSinCos\n" "7 index 2 ne {1 index 0 eq {pop pop 5 index 1 eq {1}{-1} ifelse 0 exch} if} if\n" "9 2 roll 4 copy exch 4 -1 roll add 2 div 3 1 roll add 2 div 8 index\n" "3 array astore 1 array astore Offset\n" "5 1 roll pop pop pop pop aload pop aload pop pop exch\n" "3 index 2 eq {2 index 7 index mul sub exch} if\n" "3 index 1 eq {2 index 7 index mul abs add exch 2 index 6 index abs mul sub} if\n" "3 index 0 eq {2 index 7 index mul abs add exch 2 index 6 index abs mul add} if\n" "3 -1 roll pop 4 -1 roll stringwidth pop\n" "5 index abs HGAP mul add\n" "GSTDHD 6 index abs mul add\n" "4 index 2 eq {\n" "4 -1 roll GSTDW 2 div sub 4 1 roll\n" "3 index 2 index sub 5 1 roll exch pop 1 index add exch} if\n" "4 index 1 eq {\n" " 4 2 roll GSTDHD exch pop dup 7 index abs mul add sub\n" " exch 6 index abs HGAP mul add exch 4 2 roll\n" " exch 3 index add 3 1 roll 1 index sub neg} if\n" "4 index 0 eq {\n" " 4 2 roll GSTDHD exch pop dup 7 index abs mul add add\n" " exch 6 index abs HGAP mul add exch 4 2 roll\n" " exch 3 index add 3 1 roll 1 index add exch} if\n" "CHECKM pop pop pop\n" "} bind def\n" "%% DrawLab: (lab) flag xb yb xe ye [[x1 y1 (s1)]...] DrawLab -\n" "/DrawLab {\n" "Offset 5 1 roll 4 copy 9 -1 roll TextDiameter\n" "5 1 roll 4 copy CalcSinCos\n" "7 index 2 ne {1 index 0 eq {pop pop 5 index 1 eq {1}{-1} ifelse 0 exch} if} if\n" "9 2 roll 4 copy exch 4 -1 roll add 2 div 3 1 roll add 2 div 8 index\n" "3 array astore 1 array astore Offset\n" "5 1 roll pop pop pop pop aload pop aload pop pop exch\n" "3 index 2 eq {2 index 7 index mul sub exch} if\n" "3 index 1 eq {2 index 7 index mul abs add exch 2 index 6 index abs mul sub} if\n" "3 index 0 eq {2 index 7 index mul abs add exch 2 index 6 index abs mul add} if\n" "3 -1 roll pop 4 -1 roll 6 1 roll 5 index stringwidth pop\n" "5 index abs HGAP mul add\n" "GSTDHD 6 index abs mul add\n" "4 index 2 eq {\n" "4 -1 roll GSTDW 2 div sub 4 1 roll\n" "3 index 2 index sub 5 1 roll exch pop 1 index add exch} if\n" "4 index 1 eq {\n" " 4 2 roll GSTDHD exch pop dup 7 index abs mul add sub\n" " exch 6 index abs HGAP mul add exch 4 2 roll\n" " exch 3 index add 3 1 roll 1 index sub neg} if\n" "4 index 0 eq {\n" " 4 2 roll GSTDHD exch pop dup 7 index abs mul add add\n" " exch 6 index abs HGAP mul add exch 4 2 roll\n" " exch 3 index add 3 1 roll 1 index add exch} if\n" "newpath\n" "3 1 roll pop pop\n" "moveto\n" "pop pop pop\n" "show\n" "stroke\n" "} bind def\n" "%% SD: [[x y(s)]...] xsb ysb xse yse SD -\n" "/SD {\n" "COSSIN 3 2 roll\n" "dup length 2 le\n" "{pop []}\n" "{aload length 1 sub exch pop dup 1 add -1 roll pop 1 sub array astore}\n" "ifelse\n" "{newpath aload pop pop\n" "GSETMATH 3 1 roll moveto setmatrix currentpoint\n" "2 copy moveto\n" "GSTDW 3 div 3 index mul add exch\n" "GSTDW 3 div 4 index mul add exch\n" "lineto stroke} forall\n" "} bind def\n" "%% stdLineHeight: - GSTDHD heigh descent\n" "/GSTDHD {gsave\n" " newpath 0 0 moveto (0) false charpath pathbbox" " exch pop exch sub exch pop\n" " newpath 0 0 moveto (0p) false charpath pathbbox" " exch pop exch sub exch pop 1 index sub\n" " grestore} bind def\n" "%% stdCharWidth: - GSTDW width\n" "/GSTDW {gsave\n" " newpath 0 0 moveto (W) false charpath pathbbox pop exch pop exch sub\n" " grestore} bind def\n" "%% hGap: - HGAP gap\n" "/HGAP {GSTDW 0.3 mul} bind def\n" "%% a b c d GSPW a*c+b*d\n" "/GSPW {" " 2 index mul exch 3 index mul add exch pop exch pop" " } bind def\n" "%% Cos&Sin: x1 y1 x2 y2 COSSIN cos sin\n" "/COSSIN {\n" " 4 2 roll GSETMATH 3 1 roll moveto setmatrix currentpoint\n" " 4 2 roll GSETMATH 3 1 roll moveto setmatrix currentpoint\n" " 2 index sub 4 1 roll exch pop exch sub\n" /* dy dx */ " 2 copy dup mul exch dup mul add sqrt\n" /* dy dx d */ " dup 0 eq {pop pop pop 0 0}{dup 4 1 roll div 3 1 roll exch div} ifelse\n" " } bind def\n" "%% LabA: (lab) xb yb xe ye LabA (lab) l r t b\n" "/LabA {\n" "4 copy COSSIN\n" "6 -2 roll pop pop\n" "4 -2 roll\n" "GSETMATH 3 1 roll moveto setmatrix currentpoint\n" "4 2 roll\n" "2 copy abs exch abs exch\n" "6 index stringwidth pop\n" "GSTDW add 2 div\n" "GSTDHD add 2 div\n" "GSPW\n" "dup\n" "3 index mul\n" "6 -1 roll add\n" "5 1 roll\n" "mul\n" "exch pop add\n" "2 index stringwidth pop 2 div\n" "dup\n" "3 index\n" "sub neg\n" "4 1 roll\n" "3 -1 roll add\n" "exch GSTDHD exch pop 2 div add\n" "dup GSTDHD pop 2 div\n" "dup\n" "4 1 roll\n" "sub 3 1 roll add exch\n" "} bind def\n" "%% CheckLabA: (lab) xb yb xe ye CheckLabA -\n" "/CheckLabA {\n" "LabA CHECKM pop\n" "} bind def\n" "%% DrawLabA: (lab) xb yb xe ye DrawLabA -\n" "/DrawLabA {\n" "LabA 3 1 roll pop pop newpath moveto show stroke\n" "} bind def\n" "%% xCheckNums: - xCheckNums -\n" "/xCheckNums {xFL xAXIS xNUMS CheckNums} def\n" "%% xCheckLab: - xCheckLab -\n" "/xCheckLab {LABTYPE 1 eq {xLAB xFL xAXIS xNUMS CheckLab}{xLAB xAXIS CheckLabA} ifelse} def\n" "%% yCheckNums: - yCheckNums -\n" "/yCheckNums {yFL yAXIS yNUMS CheckNums} def\n" "%% yCheckLab: - yCheckLab -\n" "/yCheckLab {LABTYPE 1 eq {yLAB yFL yAXIS yNUMS CheckLab}{yLAB yAXIS CheckLabA} ifelse} def\n" "%% zCheckNums: - zCheckNums -\n" "/zCheckNums {2 zAXIS zNUMS CheckNums} def\n" "%% zCheckLab: - zCheckLab -\n" "/zCheckLab {LABTYPE 1 eq {zLAB 2 zAXIS zNUMS CheckLab}{zLAB zAXIS CheckLabA} ifelse} def\n" "%% xDrawNums: - xDrawNums -\n" "/xDrawNums { xFL xAXIS xNUMS DrawNums xNUMS xSD SD} bind def\n" "%% yDrawNums: - yDrawNums -\n" "/yDrawNums { yFL yAXIS yNUMS DrawNums yNUMS ySD SD} bind def\n" "%% zDrawNums: - zDrawNums -\n" "/zDrawNums { 2 zAXIS zNUMS DrawNums zNUMS zSD SD} bind def\n" "%% xDrawLab: - xDrawLab -\n" "/xDrawLab {LABTYPE 1 eq {xLAB xFL xAXIS xNUMS DrawLab}{xLAB xAXIS DrawLabA} ifelse} def\n" "%% yDrawLab: - yDrawLab -\n" "/yDrawLab {LABTYPE 1 eq {yLAB yFL yAXIS yNUMS DrawLab}{yLAB yAXIS DrawLabA} ifelse} def\n" "%% zDrawLab: - zDrawLab -\n" "/zDrawLab {LABTYPE 1 eq {zLAB 2 zAXIS zNUMS DrawLab}{zLAB zAXIS DrawLabA} ifelse} def\n" "%% Spec Line: xs ys xe ye GSLINE\n" "/GSLINE {\n" " newpath GSETMATH 5 1 roll moveto lineto setmatrix\n" " 1 GLWIDTH setlinewidth stroke\n" " } bind def\n" "%% Frame: - GFRAME -\n" "/GFRAME {newpath\n" " 0 0 moveto\n" " GPW 0 lineto\n" " GPW GPH lineto\n" " 0 GPH lineto\n" " closepath 1 GLWIDTH setlinewidth gsave stroke grestore clip} bind def\n" "%% SetPen: width style PEN -\n" "/PEN {\n" " 0 setlinecap\n" " dup 0 gt {dup 1 eq {[]}\n" " {dup 2 eq {[0 2 index GCWIDTH 6 mul] 1 setlinecap}\n" " {[1 index GCWIDTH dup 3 mul exch 4 mul]}\n" " ifelse\n" " } ifelse\n" " 0 setdash\n" " } if pop\n" " GCWIDTH setlinewidth\n" " } bind def\n" "%% Color: r g b COLOR -\n" "/COLOR {ISCOLOR {setrgbcolor}{pop pop pop BWCOLOR setgray} ifelse} bind def\n" "%% Point: x y POINT -\n" "/POINT {\n" " newpath GSETMATH 3 1 roll transform 3 -1 roll setmatrix itransform\n" " currentlinewidth 2 div 0 360 arc fill\n" " } bind def\n" "%% Line: x y xo yo LINE -\n" "/LINE {\n" " newpath GSETMATH 5 1 roll moveto lineto setmatrix stroke\n" " } bind def\n" "%%FRAME/PAINT CIRCLE: x y radius r g b ...CIRCLE -\n" "/CIRCLE {\n" " COLOR GMSCALE 3 1 roll GSETMATH 4 1 roll transform 4 -1 roll setmatrix itransform 3 -1 roll 0 360 arc} bind def\n" "/FRAMECIRCLE {\n" " CIRCLE 1 GLWIDTH setlinewidth stroke\n" " } bind def\n" "/PAINTCIRCLE {\n" " CIRCLE fill\n" " } bind def\n" "%%FRAME/PAINT POLYLINE: rxn ryn ... rx1 ry1 n x y r g b ...POLY -\n" "/POLY {\n" " COLOR GSETMATH 3 1 roll moveto setmatrix\n" " 1 1 3 -1 roll {3 1 roll GMSCALE exch GMSCALE exch 3 -1 roll 1 eq {rmoveto}{rlineto} ifelse} for\n" " } bind def\n" "/FRAMEPOLY {POLY closepath 1 GLWIDTH setlinewidth stroke} bind def\n" "/PAINTPOLY {POLY closepath fill} bind def\n" "%% STRMARKER: (s) ow oh mw mh ox oy x y STRMARKER -\n" "/STRMARKER {\n" " newpath GSETMATH 3 1 roll moveto\n" " setmatrix GMSCALE exch GMSCALE exch rmoveto\n" " GSTDHD pop mul exch 4 index stringwidth pop mul exch rmoveto\n" " GSTDHD pop mul exch GSTDW mul exch rmoveto\n" " show\n" " } bind def\n" "%%%%EndResource\n" "%%%%EndProlog\n\n" ; Local(Char) hc_DocSetup[]= "%%%%BeginSetup\n" " /%s findfont\n" " %i scalefont setfont\n" " 1 setlinecap\n" "%%lpr%% 72 72 translate\n" "%%%%EndSetup\n\n" ; /* Output Header, Procedure defenitions, Document setup */ Local(void) hcInit(GraphicDataPtr gd) { RecT r; Char date[25]; /* see DayTimeStr in corelib */ /* Header */ DayTimeStr(date,TRUE,TRUE); /* get date and time */ fprintf(gd->HardFile,hc_Header,date,hcPageWidth, hcPageHeight); /* Procedure defenitions */ GetPosition(gd->paPanel,&r); fprintf(gd->HardFile,hc_ProcDef,hcPageWidth,hcPageHeight, gd->uMin,gd->uMax, gd->vMin,gd->vMax, hcCurveWidthFactor, hcLineWidthFactor, hcMarkerFactor, hcColor ? "true" : "false" ); /* Document setup */ fprintf(gd->HardFile,hc_DocSetup,hcFontList[hcFontCur],(int)hcFontSize); gd->hcMarkerNo=0; } Local(Char) hc_Trailer[]= /*** "%%lpr%% showpage\n"***/ "showpage\n" "%%%%Trailer\n" "%%%%EOF\n" ; /* Output Document trailer */ Local(void) hcTerm(GraphicDataPtr gd) { int i; fprintf(gd->HardFile,"%%BeginMarkers:\n"); for (i=0; ihcMarkerNo; i++) fprintf(gd->HardFile,"MARKER%i\n",i); fprintf(gd->HardFile,"%%EndMarkers:\n"); fprintf(gd->HardFile,hc_Trailer); } Callback(void) HardcopyOk(ButtoN b) { WindoW optwin=ParentWindow(b); hcOptDataPtr data=(hcOptDataPtr)GetWindowExtra(optwin); WinComDataPtr wcd=(WinComDataPtr)GetWindowExtra(data->wParent); GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; #if _UNIX CharPtr p; Char Buf[PAR_BUF]; #endif float val; Int2 n; Char buf[PATH_MAX+100],num[20]; Select(wcd->Win); Hide(optwin); /* file name */ GetTitle(data->File,buf,PATH_MAX); gd->HardFile=fopen(buf,"wt"); if (!gd->HardFile) Warning("HC_OPEN",buf); /* Width, Height, unit */ n=GetValue(data->Unit); GetTitle(data->Width_,num,sizeof(num)); sscanf(num,"%g",&val); hcPageWidth=val*hcUnitMult[n-1]; GetTitle(data->Height_,num,sizeof(num)); sscanf(num,"%g",&val); hcPageHeight=val*hcUnitMult[n-1]; sprintf(buf+StrLen(buf)," %g %g %i",hcPageWidth,hcPageHeight,(int)n); /* Font */ hcFontCur=GetValue(data->Font); if (hcFontCur) hcFontCur--; sprintf(buf+StrLen(buf)," %s",hcFontList[hcFontCur]); /* Size */ n=GetValue(data->Size); hcFontSize=n ? n+MINSIZE-1 : MINSIZE; sprintf(buf+StrLen(buf)," %i",(int)hcFontSize); /* CurveWidthFactor */ GetTitle(data->CurveWidthFactor,num,sizeof(num)); sscanf(num,"%g",&hcCurveWidthFactor); sprintf(buf+StrLen(buf)," %g",hcCurveWidthFactor); /* LineWidthFactor */ GetTitle(data->LineWidthFactor,num,sizeof(num)); sscanf(num,"%g",&hcLineWidthFactor); sprintf(buf+StrLen(buf)," %g",hcLineWidthFactor); /* MarkerFactor */ GetTitle(data->MarkerFactor,num,sizeof(num)); sscanf(num,"%g",&hcMarkerFactor); sprintf(buf+StrLen(buf)," %g",hcMarkerFactor); /* Color toggle */ sprintf(buf+StrLen(buf)," %c","ft"[hcColor=GetStatus(data->Color)]); #if _UNIX /* Preview toggle */ sprintf(buf+StrLen(buf)," %c","ft"[GetStatus(data->Preview)]); /* Print toggle */ sprintf(buf+StrLen(buf)," %c","ft"[GetStatus(data->Print)]); #endif /* Save current settings */ SetParam(SECTION,"HARDCOPY",buf); /* Create PostScript file */ if (gd->HardFile) { gd->Hardcopy=TRUE; hcSetMode(wcd,gd->HardFile); hcInit(gd); RedrawDiagram(0); hcTerm(gd); gd->Hardcopy=FALSE; fclose(gd->HardFile); } #if _UNIX *StrChr(buf,' ')='\0'; /* filename */ if (GetStatus(data->Preview)) { p=GetParamString(SECTION_COM,"HCVIEWER"); sprintf(Buf,p,buf); system(Buf); } if (GetStatus(data->Print)) { FILE *in, *out; Char b[500]; CharPtr p; in=fopen(buf,"rt"); p=GetParamString(SFS_FILES,"TEMP"); out=fopen(p,"wt"); if (in && out) { while (fgets(b,sizeof(b),in)) { if (!StrNCmp(b,"%lpr%",5)) StrCpy(b,b+5); fputs(b,out); } } fclose(in); fclose(out); StrCpy(b,p); p=GetParamString(SECTION_COM,"HCPRINTER"); sprintf(Buf,p,b); system(Buf); } #endif HardcopyCancel(b); } #if _WIN #pragma argsused #endif Callback(void) HardcopyHelp(ButtoN b) { Help(NULL); } Callback(void) UnitCallback(PopuP Unit) { hcOptDataPtr data; float val; Char num[20]; Int2 unit=GetValue(Unit); data=(hcOptDataPtr)GetWindowExtra(ParentWindow(Unit)); GetTitle(data->Width_,num,sizeof(num)); sscanf(num,"%g",&val); hcPageWidth=val*hcUnitMult[data->oldunit-1]; sprintf(num,"%g",hcPageWidth/hcUnitMult[unit-1]); SetTitle(data->Width_,num); GetTitle(data->Height_,num,sizeof(num)); sscanf(num,"%g",&val); hcPageHeight=val*hcUnitMult[data->oldunit-1]; sprintf(num,"%g",hcPageHeight/hcUnitMult[unit-1]); SetTitle(data->Height_,num); data->oldunit=unit; } Callback(void) HardcopyOutFile(ButtoN b) { WindoW optwin; hcOptDataPtr data; Char def[PATH_MAX],file[PATH_MAX]; optwin=ParentWindow(b); data=(hcOptDataPtr)GetWindowExtra(optwin); GetTitle(data->File,def,sizeof(def)); *file='\0'; if (GetOutputFileName(file,sizeof(file),def)) SetTitle(data->File,file); } #if _WIN #pragma argsused #endif Callback(void) lHardcopy(Int2 index) { WindoW optwin; hcOptDataPtr data; GrouP g,gFile,gFont,gPicture,gOpt; CharPtr p; int pos,unit; Int2 i; Char b[50]; CharPtr Buf; data=MemNew(sizeof(hcOptData)); data->wParent=CurrentWindow(); LockMenus(); /* lock second time because otherwise it would be unlocked immediatedly after return */ optwin=FixedWindow(-50,-50,-sysCharWidth,-sysLineHeight, Text[HARDCOPY_T],NULL); SetWindowExtra(optwin,data,NULL); /* Create controls */ gFile=CreateNormalGroup(optwin,2,0,Text[HCFILE_G]); SetGroupSpacing(gFile,sysCharWidth,0); SetGroupMargins(gFile,sysCharWidth,sysLineHeight/2); data->File=DialogText(gFile,"",20,NULL); PushButton(gFile,Text[HCFILELIST_B],HardcopyOutFile); gPicture=CreateNormalGroup(optwin,3,0,Text[HCPIC_P]); SetGroupSpacing(gPicture,sysCharWidth,0); SetGroupMargins(gPicture,sysCharWidth,sysLineHeight/2); g=CreateHiddenGroup(gPicture,2,0,0); SetGroupSpacing(g,2,0); StaticPrompt(g,Text[HCWIDTH_P],0,dialogTextHeight,NULL,'l'); data->Width_=DialogText(g,"",5,NULL); g=CreateHiddenGroup(gPicture,2,0,0); SetGroupSpacing(g,2,0); StaticPrompt(g,Text[HCHEIGHT_P],0,dialogTextHeight,NULL,'l'); data->Height_=DialogText(g,"",5,NULL); data->Unit=PopupList(gPicture,FALSE,UnitCallback); StrCpy(b,Text[HCUNITS]); for (i=0; i<3; i++) { p=StrChr(b,' '); if (p) *p++='\0'; PopupItem(data->Unit,b); if (p) StrCpy(b,p); } gFont=CreateNormalGroup(optwin,2,0,Text[HCFONTG_P]); SetGroupSpacing(gFont,sysCharWidth,0); SetGroupMargins(gFont,sysCharWidth,sysLineHeight/2); data->Font=SingleList(gFont,15,5,NULL); data->Size=SingleList(gFont,4,5,NULL); gOpt=CreateNormalGroup(optwin,2,0,Text[HCOPT_P]); StaticPrompt(gOpt,Text[HCCWIDF_P],0,dialogTextHeight,NULL,'l'); data->CurveWidthFactor=DialogText(gOpt,"",2,NULL); StaticPrompt(gOpt,Text[HCLWIDF_P],0,dialogTextHeight,NULL,'l'); data->LineWidthFactor=DialogText(gOpt,"",2,NULL); StaticPrompt(gOpt,Text[HCMF_P],0,dialogTextHeight,NULL,'l'); data->MarkerFactor=DialogText(gOpt,"",2,NULL); data->Color=CheckBox(gOpt,Text[HCOPTCOL_P],NULL); Break(gOpt); #if _UNIX data->Preview=CheckBox(gOpt,Text[HCOPTPRE_P],NULL); data->Print=CheckBox(gOpt,Text[HCOPTPRI_P],NULL); #endif /* and set default values: */ Buf=GetParamString(SECTION,"HARDCOPY"); /* - file name */ StrTrim(Buf); p=StrChr(Buf,' '); if (p) *p++='\0'; SetTitle(data->File,Buf); StrCpy(Buf,p); /* - width, height, and unit */ sscanf(Buf," %g %g %i %n",&hcPageWidth,&hcPageHeight,&unit,&pos); data->oldunit=unit; sprintf(b,"%g",hcPageWidth/hcUnitMult[unit-1]); SetTitle(data->Width_,b); sprintf(b,"%g",hcPageHeight/hcUnitMult[unit-1]); SetTitle(data->Height_,b); SetValue(data->Unit,unit); StrCpy(Buf,Buf+pos); /* - font */ StrTrim(Buf); p=StrChr(Buf,' '); if (p) *p++='\0'; for (i=0; iFont,hcFontList[i]); if (!StrCmp(Buf,hcFontList[i])) { SetValue(data->Font,i+1); SetOffset(data->Font,0,i); } } StrCpy(Buf,p); /* - font size */ StrTrim(Buf); p=StrChr(Buf,' '); if (p) *p++='\0'; for (i=MINSIZE; i<=MAXSIZE; i++) { sprintf(b,"%i",(int)i); ListItem(data->Size,b); if (!StrCmp(Buf,b)) { SetValue(data->Size,i-MINSIZE+1); SetOffset(data->Size,0,i-MINSIZE); } } StrCpy(Buf,p); /* - curve width factor */ sscanf(Buf," %g %n",&hcCurveWidthFactor,&pos); sprintf(b,"%g",hcCurveWidthFactor); SetTitle(data->CurveWidthFactor,b); StrCpy(Buf,Buf+pos); /* - line width factor */ sscanf(Buf," %g %n",&hcLineWidthFactor,&pos); sprintf(b,"%g",hcLineWidthFactor); SetTitle(data->LineWidthFactor,b); StrCpy(Buf,Buf+pos); /* - marker factor */ sscanf(Buf," %g %n",&hcMarkerFactor,&pos); sprintf(b,"%g",hcMarkerFactor); SetTitle(data->MarkerFactor,b); StrCpy(Buf,Buf+pos); /* - color toggle */ StrTrim(Buf); SetStatus(data->Color,*Buf=='t'); StrCpy(Buf,Buf+1); #if _UNIX /* - preview toggle */ StrTrim(Buf); SetStatus(data->Preview,*Buf=='t'); StrCpy(Buf,Buf+1); /* - print toggle */ StrTrim(Buf); SetStatus(data->Print,*Buf=='t'); StrCpy(Buf,Buf+1); #endif /* Align */ AlignObjects(ALIGN_RIGHT,(HANDLE)gFile,(HANDLE)gFont,(HANDLE)gPicture,(HANDLE)gOpt,NULL); PushContext(HK_HARDCOPYWIN,NULL,Text[HARDCOPY_C]); TerminalButtons(optwin,gFile,HardcopyOk,HardcopyCancel,HardcopyHelp); Show(optwin); SelectText(data->File,0,0); } #undef MINSIZE #undef MAXSIZE /*---------------------------*/ /* Duplicate window callback */ #if _WIN #pragma argsused #endif Callback(void) lDuplicate(Int2 index) { WinComDataPtr wcd=GetComDataI; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; GraphicDataPtr cgd; /* new copy */ Int2 i,j; cgd=MemNew(sizeof(GraphicData)); if (cgd) { cgd->FuncNum=gd->FuncNum; cgd->FuncCur=gd->FuncCur; for (i=0; iAxis); i++) { cgd->Axis[i].pMin=StringSave(gd->Axis[i].pMin); cgd->Axis[i].pMax=StringSave(gd->Axis[i].pMax); cgd->Axis[i].Funcs=MemNew(ARRAYSIZE(AxisFunc,cgd->FuncNum)); for (j=0; jFuncNum; j++) { cgd->Axis[i].Funcs[j].pFunc=StringSave(gd->Axis[i].Funcs[j].pFunc); } cgd->Axis[i].pTick=StringSave(gd->Axis[i].pTick); MemCopy(cgd->Axis[i].Prop,gd->Axis[i].Prop,sizeof(cgd->Axis[i].Prop)); } for (i=0; ipAngle); i++) cgd->pAngle[i]=StringSave(gd->pAngle[i]); cgd->Attr=MemNew(ARRAYSIZE(FuncAttr,cgd->FuncNum)); MemCopy(cgd->Attr,gd->Attr,ARRAYSIZE(FuncAttr,cgd->FuncNum)); MemCopy(&cgd->Options,&gd->Options,sizeof(cgd->Options)); cgd->SpecialPoints=BSNew(0); if (DuplicateWindow(wcd,cgd)) { /* failure */ WinComData dwcd; dwcd.Private=cgd; WriteDescription(&dwcd,NULL); /* free cgd only */ } } } #if MOUSE /*----------------------*/ /* Mouse menu callbacks */ #if _WIN #pragma argsused #endif Callback(void) lPickCoord(Int2 index) { WinComDataPtr wcd=GetComDataI; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; gd->flags^=MOUSE_PICK; if (!(gd->flags&MOUSE_PICK)) { gd->flags&=~(MOUSE_IMMB|MOUSE_IMMF); } } #if _WIN #pragma argsused #endif Callback(Boolean) lPickCoord_Status(Int2 index) { WinComDataPtr wcd=GetComDataI; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; return (gd->flags&MOUSE_PICK)!=0 && gd->FuncNum==1; } #if _WIN #pragma argsused #endif Callback(void) lImmedFComp(Int2 index) { WinComDataPtr wcd=GetComDataI; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; gd->flags^=MOUSE_IMMF; if (gd->flags&MOUSE_IMMF) { gd->flags&=~MOUSE_IMMB; gd->flags|=MOUSE_PICK; } } #if _WIN #pragma argsused #endif Callback(Boolean) lImmedFComp_Status(Int2 index) { WinComDataPtr wcd=GetComDataI; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; return (gd->flags&MOUSE_IMMF)!=0 && gd->FuncNum==1; } #if _WIN #pragma argsused #endif Callback(void) lImmedBComp(Int2 index) { WinComDataPtr wcd=GetComDataI; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; gd->flags^=MOUSE_IMMB; if (gd->flags&MOUSE_IMMB) { gd->flags&=~MOUSE_IMMF; gd->flags|=MOUSE_PICK; } } #if _WIN #pragma argsused #endif Callback(Boolean) lImmedBComp_Status(Int2 index) { WinComDataPtr wcd=GetComDataI; GraphicDataPtr gd=(GraphicDataPtr)wcd->Private; return (gd->flags&MOUSE_IMMB)!=0 && gd->FuncNum==1; } #endif /* MOUSE */ /*----------------*/ /* Help callbacks */ #if _WIN #pragma argsused #endif Callback(void) lHelp(Int2 indx) { Help(HK_3DWIN); } #if _WIN #pragma argsused #endif Callback(void) lHelpSearch(Int2 indx) { HelpSearch(HK_3DWIN); }