/* 1D stairs window class functions. For 1D maps only (see map_g.con). Intended for trajectories only. They need not to be reenterable but MUST be reusable. */ #include "common.h" #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 s1d_GetClassTable /* Unique name of the 'Get Class Table' function */ #include "window.h" /* From map_g.con, section &visiblenames: Short names of visual classes are used here */ #define GCC_TIME "%Code(Time)" #define GCC_PHASE "%Code(Phase)" #define GCC_PAR "%Code(Par)" #define GCC_SUP "%Code(SPECCL_MSUP)" Local(Uint2) lClassGlobId(CharPtr e) { FloatHi expr; Uint2 r=0; if (!ComputeExpr(e,&expr)) r=(Uint2)expr; return r; } /* GetClassTable is generated by window.h */ /* Texts */ Local(CharPtr) Text[]={ "Compute{", "Forward", "Extend", "Window{", "Redraw diagram", "Redraw curve", "Clear", "Fit diagram", "Fit curve", "Undo scale", "Layout...", "Hardcopy...", "Duplicate", "Hide", "Attributes{", "Current...", "Curve...", "Mouse{", "Pick up coordinates?", "Immediate forward?", "Help{", "This window", "Search", "-", "}", "Limits of visibility", "Waiting for attributes setting", "Attributes of graphic window", "Current drawing attributes", "Drawing attributes of current curve", "4,11,(6,13)", /* NumLen,TextLen,(ListLines,LineLen) */ "Abscissa", "Ordinate", "Min", "Max", "Tick", "Scale", "Label", "Grid", "Axes", "Graph", "Colors", "Change color", "Foreground", "Background", "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", "Style", "No", "Solid", "Dotted", "Options", "Stairs", "Prev-Next", "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", "Name chosen: %s", "Window title", NULL }; enum { COMPUTE_M, FORWARD_I, EXTEND_I, WINDOW_M, REDRAWD_I, REDRAWC_I, CLEAR_I, FITD_I, /* Fit diagram */ FITC_I, /* Fit curve */ UNDOSCALE_I, /* Undo scale */ LAYOUT_I, /* Layout */ HARDCOPY_I, /* Hardcopy */ DUPLICATE_I, /* Duplicate */ HIDE_I, ATTRIBUTES_M, /* Attributes{ */ CURRENTATR_I, /* Current... */ CURVEATR_I, /* Curve... */ MOUSE_M, /* Mouse{ */ MOUSEPICK_I, /* Pick up coordinates? */ MOUSEIMMEDF_I,/* Immediate forward? */ HELP_M, HELP_I, SEARCH_I, SEPARATOR_I, DUMMYEND_I, ABSORD_P, /* Limits of visibility */ 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) */ ABS_P, /* Abscissa */ ORD_P, /* Ordinate */ MIN_P, /* Min */ MAX_P, /* Max */ TICK_P, /* Tick */ SCALE_P, /* Scale */ FUNC_P, /* Label */ GRID_P, /* Grid */ AXES_P, /* Axes */ RHS_P, /* Graph */ COLORS_T, /* Colors */ COLOR_B, /* Change color */ FG_P, /* Foreground */ BG_P, /* Background */ SHOWPAL_P, /* 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 */ STYLE_P, /* Style */ NO_B, /* No */ SOLID_B, /* Solid */ DOTTED_B, /* Dotted */ OPTIONS_P, /* Options */ STAIRS_B, /* Stairs */ PREVNEXT_B, /* Prev-Next */ 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 */ CURNAME_P, /* Name chosen: %s */ WINTITLE_P, /* Window title */ _L_A_S_T_ }; #define DEFAULT_TITLE "1D staircase" /* default title of window */ #define STAIRS_TITLE DEFAULT_TITLE #define PREVNEXT_TITLE "Prev-Next diagram" #define HK_1DWIN "kh_1DSWin" /* Help key for the window */ #define HK_LAYOUTWIN "kh_1DSWinLayout" /* Help key for layout dialog box */ #define HK_HARDCOPYWIN "kh_1DSWinHardcopy" /* Help key for hardcopy dialog box */ #define KH_CURRENTATTR "kh_1DSWinCurrentAttr" /* Help key for current attributes dialog box */ #define KH_CURVEATTR "kh_1DSWinCurveAttr" /* Help key for curve's attributes dialog box */ /* Settings file section name */ /* NOTE: this window shares the settings with 2D graphic window */ #define SECTION "Window_2DGraphic" #define SECTION_COM "Visual" /* Axis descriptor */ typedef struct { CharPtr pFunc; /* the name of a variable along the axis */ Int2 IndirectIndex; /* index to IndirectValues */ Uint2 Offset; /* offset in values vector */ Int2 Eip; /* Echo Initial Point coord */ } AxisFunc, PNTR AxisFuncPtr; /* Hardcopy */ typedef struct { FloatLo x,y; } MathPoint, PNTR MathPointPtr; /* Draw attributes of points, traces, and paths */ typedef struct { DrawAttr Point; DrawAttr Path; /* style>0 => join along paths */ PoinT PrevPath; /* used if Attr.Path.style>0 and stores 2 PoinTs */ PoinT CurPath; /* with windows coordinates of M-points on prev and cur G-points */ MathPoint hcPrevPath, hcCurPath; /* Hardcopy */ 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 { Uint1 Flags; #define GWIN_PALETTE 0x01 #define GWIN_STAIRS 0x02 /* Draw as stairs, otherwise as Prev-Next */ #define GWIN_FUNC 0x04 #define GWIN_CLEAR 0x08 Uint1 Reserve; /* unused now */ } ShowOptions; /* Element of the undo scale buffer */ typedef struct { FloatHi xyMin[2],xyMax[2]; } UndoElem, PNTR UndoElemPtr; /* 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 */ /* unused pText[2] */ #define FUNCINDEX 2 #define FuncIndex(i) (i==FUNCINDEX) #define pTick pText[3] /* Tick */ AxisFunc Func; /* axis function */ Boolean Prop[6]; /* Properties */ #define bLimits Prop[0] #define bTick Prop[1] #define bScale Prop[2] #define bFunc Prop[3] #define bGrid Prop[4] #define bAxis Prop[5] } Axis[2]; FuncAttr Attr; /* attributes of points and paths */ FuncAttr 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 */ #define MOUSE_PICK 0x0002 /* Mouse click sets up initial point */ #define MOUSE_IMMF 0x0008 /* and starts forward */ #define FIT_IN_PROGRESS 0x0010 /* Fit diagram/curve in progress */ #define FOOL_DRAW 0x0020 /* Set by SampleDraw to fool DrawProc */ GrouP grLimits; /* Limits SpeedBar group */ GrouP grPalette; /* Palette SpeedBar group */ PaneL paSample; /* Palette: sample of curve color */ struct { TexT teLimits[4]; /* 0 - Min, 1 - Max, 2 - unused, 3 - Tick */ PrompT prompt; } teAxis[2]; /* Limits SpeedBar controls */ /* 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 DeltaX,DeltaY; 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[2]; /* Used by conversion routines. May differ from Axis.pText[] in cases the user set invalid Min and/or Max and/or Tick */ Int2 ix_min,ix_max,iy_min,iy_max; /* windows coords of Slate */ Boolean joinpath; /* equal to Attr.Path.style>0 */ /* Undo scale */ UndoElemPtr UndoBuf; Int2 UndoNum; /* Hardcopy */ FILE PNTR HardFile; /* output for hardcopy */ Boolean Hardcopy; /* set when in hardcopy progress for this window */ Int2 hcMarkerNo; /* Ordinal number of current marker */ /* Grid */ #if _UNIX /* no bitmaps, SetPenDash is used */ #else Uint1Ptr GridVert; Uint1Ptr GridHor; #endif /* Click-hold-release */ PoinT ptCur; PoinT ptLast; Boolean bDrag; } StairsData, PNTR StairsDataPtr; #define UNDODEPTH 10 /* undo scale buffer's length */ #define SRHS(x) (4*x*(1-x)) /* Sample Rhs */ #if _WIN #pragma argsused #endif Callback(Boolean) AlwaysStatus(Int2 indx) { return TRUE; } Callback(void) lRedrawC(Int2 indx); Callback(void) lRedrawD(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) lHardcopy(Int2 indx); Callback(void) lDuplicate(Int2 index); Callback(void) lCurrentAtr(Int2 indx); Callback(void) lCurveAtr(Int2 indx); Callback(void) lPickCoord(Int2 index); Callback(Boolean) lPickCoord_Status(Int2 index); Callback(void) lImmedFComp(Int2 index); Callback(Boolean) lImmedFComp_Status(Int2 index); Callback(void) lHelp(Int2 indx); Callback(void) lHelpSearch(Int2 indx); /* Menu */ Local(MenuItem) GraphicMenu[]={ {COMPUTE_M, NULL, NULL}, { FORWARD_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}, { 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}, {MOUSE_M, NULL, NULL}, { MOUSEPICK_I, lPickCoord, lPickCoord_Status}, { MOUSEIMMEDF_I, lImmedFComp, lImmedFComp_Status}, { DUMMYEND_I, NULL, NULL}, {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); #define GetComDataI ((WinComDataPtr)GetWindowExtra(CurrentWindow())) #define GetComDataC(h) ((WinComDataPtr)GetWindowExtra(ParentWindow(h))) ClassMember(void) BuildDefaultDescription(WinComDataPtr wcd) { StairsDataPtr sd; DrawAttr da; CharPtr p; Char buf[100]; Int2 j,dim; wcd->WinTitle=StringSave(DEFAULT_TITLE); if (!wcd->Private) wcd->Private=MemNew(sizeof(StairsData)); sd=(StairsDataPtr)wcd->Private; sd->Axis[0].pMin=StringSave("0"); sd->Axis[0].pMax=StringSave("1"); sd->Axis[1].pMin=StringSave("0"); sd->Axis[1].pMax=StringSave("1"); GetNameAndDim(0,1,&p,&dim); /* 0 - Phase is the FIRST class in map_g.con */ if (dim>1) { StrCpy(buf,p); StrCat(buf,"[0]"); p=buf; } sd->Axis[0].Func.pFunc=StringSave(p); sd->Axis[1].Func.pFunc=StringSave(p); sd->Axis[0].pTick=StringSave("0"); /* default: choose tick automatically */ sd->Axis[1].pTick=StringSave("0"); /* default: choose tick automatically */ for (j=0; jAxis[0].Prop); j++) sd->Axis[0].Prop[j]=TRUE; /* All on by default */ sd->Axis[0].bTick=FALSE; /* except for ticks */ da.color=wcd->Foreground; da.width=2; da.style=1; /* do join for 1D maps */ sd->Attr.Point=da; sd->Attr.Path=da; sd->Options.Flags=GWIN_FUNC|GWIN_STAIRS; sd->Options.Reserve=0; } ClassMember(void) ReadDescription(WinComDataPtr wcd, DataLibPtr arch){ StairsDataPtr sd; Int2 j,un; if (!wcd->Private) wcd->Private=MemNew(sizeof(StairsData)); sd=(StairsDataPtr)wcd->Private; for (j=0; jAxis[0].pText); j++) if (!FuncIndex(j)) sd->Axis[0].pText[j]=DataLibReadVRecord(arch,NULL); sd->Axis[0].Func.pFunc=DataLibReadVRecord(arch,NULL); DataLibRead(arch,(CharPtr)sd->Axis[0].Prop,sizeof(sd->Axis[0].Prop)); DataLibRead(arch,(CharPtr)&sd->Attr.Point,sizeof(DrawAttr)); DataLibRead(arch,(CharPtr)&sd->Attr.Path,sizeof(DrawAttr)); DataLibRead(arch,(CharPtr)&sd->Options,sizeof(sd->Options)); DataLibRead(arch,(CharPtr)&un,sizeof(un)); sd->UndoNum=un ? un-1 : 0; if (un) { sd->UndoBuf=MemNew(ARRAYSIZE(UndoElem,UNDODEPTH)); DataLibRead(arch,(CharPtr)sd->UndoBuf,ARRAYSIZE(UndoElem,un)); } /* Before 09.10.97 axes had the same Min and Max */ for (j=0; jAxis[1].pText); j++) if (!FuncIndex(j)) { sd->Axis[1].pText[j]=DataLibReadVRecord(arch,NULL); if (DataLibLastVRecLen==0) sd->Axis[1].pText[j]=StringSave(sd->Axis[0].pText[j]); } sd->Axis[1].Func.pFunc=DataLibReadVRecord(arch,NULL); if (DataLibLastVRecLen==0) sd->Axis[1].Func.pFunc=StringSave(sd->Axis[0].Func.pFunc); } ClassMember(void) WriteDescription(WinComDataPtr wcd, DataLibPtr arch) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; Int2 j,un; for (j=0; jAxis[0].pText); j++) if (!FuncIndex(j)) { DataLibWriteVRecord(arch,NULL,sd->Axis[0].pText[j],StrLen(sd->Axis[0].pText[j])+1); MemFree(sd->Axis[0].pText[j]); } DataLibWriteVRecord(arch,NULL,sd->Axis[0].Func.pFunc, StrLen(sd->Axis[0].Func.pFunc)+1); MemFree(sd->Axis[0].Func.pFunc); DataLibWrite(arch,(CharPtr)sd->Axis[0].Prop,sizeof(sd->Axis[0].Prop)); DataLibWrite(arch,(CharPtr)&sd->Attr.Point,sizeof(DrawAttr)); DataLibWrite(arch,(CharPtr)&sd->Attr.Path,sizeof(DrawAttr)); DataLibWrite(arch,(CharPtr)&sd->Options,sizeof(sd->Options)); un=sd->UndoBuf ? sd->UndoNum+1 : 0; DataLibWrite(arch,(CharPtr)&un,sizeof(un)); DataLibWrite(arch,(CharPtr)sd->UndoBuf,ARRAYSIZE(UndoElem,un)); MemFree(sd->UndoBuf); /* Before 09.10.97 axes had the same Min and Max */ for (j=0; jAxis[1].pText); j++) if (!FuncIndex(j)) { DataLibWriteVRecord(arch,NULL,sd->Axis[1].pText[j],StrLen(sd->Axis[1].pText[j])+1); MemFree(sd->Axis[1].pText[j]); } DataLibWriteVRecord(arch,NULL,sd->Axis[1].Func.pFunc, StringLen(sd->Axis[1].Func.pFunc)+1); MemFree(sd->Axis[1].Func.pFunc); } #define round(x) ((Int2)floor(x+0.5)) /* to the nearest integer */ /* Makes a FloatHi number looking "good" */ #define VZERO 1e-10 /* x printed as '0' if abs(x)INT4_MAX Local(FloatHi) ApplyArtificialIntellectX(FloatHi min, FloatHi max, Int2 len) { /* Embedded parameter of this part of the ArtificialIntellectX: The minimal horizontal spacing between two numbers. */ #define MININTVL (2*sysCharWidth) #define NO_MORE_THAN 20 /* No more intervals than this number */ FloatHi d,w; Int2 maxn,power,width,width0,i; Char buf[50]; 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 } Local(FloatHi) ApplyArtificialIntellectY(FloatHi min, FloatHi max, Int2 len) { /* Embedded parameter of this part of the ArtificialIntellectY: The minimal vertical spacing (2*sysLineHeight now). */ #define MININTVL (3*sysLineHeight/2) /* Min allowable interval between lines */ #define NO_MORE_THAN 20 /* No more intervals than this number */ FloatHi d; Int2 maxn,power; 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; !IsMultiple10(d); power++) { if (OutOfRange(d)) return d/maxn/pow(10,power); else d*=10; } for (; maxn; maxn--) { if (IsInteger(d/maxn)) return d/maxn/pow(10,power); } /* To be on the safe side. Control never comes here */ return (max-min)/2; #undef MININTVL #undef NO_MORE_THAN } /* Check limits along axis */ Local(void) CheckLimits(WinComDataPtr wcd) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; FloatHi lims[2],tick,d; Int2 a; Int2 ce; for (a=0; a<=1; a++) { lims[0]=lims[1]=tick=0; /* for a case of a bug */ ce=ComputeExpr(sd->Axis[a].pText[0],lims+0) | /* all must be computed */ ComputeExpr(sd->Axis[a].pText[1],lims+1) | ComputeExpr(sd->Axis[a].pTick,&tick); (ce ? Disable : Enable)(sd->teAxis[a].prompt); sd->RAxis[a].Tick=tick; d=lims[1]-lims[0]; if (d<0) { sd->RAxis[a].Max=lims[0]; sd->RAxis[a].Min=lims[1]; } else if (d==0) { sd->RAxis[a].Min=lims[0]; sd->RAxis[a].Max=lims[0]+1; } else { sd->RAxis[a].Min=lims[0]; sd->RAxis[a].Max=lims[1]; } } } #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) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; /* As the user might set wrong min and/or max. we'll better check them */ CheckLimits(wcd); sd->DeltaX=(sd->Slate.right-1+HOFF-sd->Slate.left)/ (sd->RAxis[0].Max-sd->RAxis[0].Min); sd->DeltaY=(sd->Slate.top-sd->Slate.bottom+1-VOFF)/ (sd->RAxis[1].Max-sd->RAxis[1].Min); } /* Converts mathematical coordinates to window coordinates */ #define SM 20 Local(Int2) MathToWinX(FloatHi x, StairsDataPtr sd) { FloatHi d; d=sd->Slate.left+sd->DeltaX*(x-sd->RAxis[0].Min); if (dSlate.left-SM; if (d>INT2_MAX) d=sd->Slate.right+SM; return round(d); } Local(Int2) MathToWinY(FloatHi y, StairsDataPtr sd) { FloatHi d; d=sd->Slate.bottom-1+VOFF+sd->DeltaY*(y-sd->RAxis[1].Min); if (dSlate.top-SM; if (d>INT2_MAX) d=sd->Slate.bottom+SM; return round(d); } #undef SM /* Converts window coordinates to mathematical coordinates */ Local(FloatHi) WinToMathX(Int2 x, StairsDataPtr sd) { return sd->RAxis[0].Min+(x-sd->Slate.left)/sd->DeltaX; } Local(FloatHi) WinToMathY(Int2 y, StairsDataPtr sd) { return sd->RAxis[1].Min+(y-sd->Slate.bottom+1-VOFF)/sd->DeltaY; } /* Makes calculations needed to draw scales */ Local(void) CalculateScales(WinComDataPtr wcd) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; FloatHi xstep,ystep,y,ymax; Int2 i,width; Boolean hc=sd->Hardcopy; /* is hardcopy requested for this window */ Char buf[50]; SelectFont(SystemFont); if (hc) { fprintf(sd->HardFile,"/GP?MW { [ 0 0 0 0]\n"); } if (sd->Axis[0].bScale) { /* horizontal */ sd->Slate.bottom-=sysLineHeight+sysDescent; if (hc) fprintf(sd->HardFile," 1 1 GPBMW\n"); } if (sd->Axis[0].bScale || sd->Axis[0].bGrid) { /* vertical */ if (sd->Axis[0].bScale) { sd->Slate.top+=sysLineHeight/2; if (hc) fprintf(sd->HardFile," 1 1 GPTMW\n"); } if (!sd->Axis[0].bScale && sd->Axis[0].bScale) { sd->Slate.bottom-=(sysLineHeight/2)+sysDescent; if (hc) fprintf(sd->HardFile," 0.5 0 GPBMW\n"); } ystep=sd->RAxis[1].Tick; if (ystep<=0 || ystep>sd->RAxis[1].Max-sd->RAxis[1].Min) ystep=ApplyArtificialIntellectY(sd->RAxis[1].Min,sd->RAxis[1].Max, sd->Slate.bottom+VOFF-sd->Slate.top); sd->RAxis[1].Step=ystep; if (sd->Axis[0].bScale) { ymax=dtos(buf,"%g",sd->RAxis[1].Max); /* round it, if necessary */ if (hc) fprintf(sd->HardFile," ["); for (width=i=0; (y=dtos(buf,"%g",i*ystep+sd->RAxis[1].Min), y<=ymax); i++) { if (widthHardFile,"(%s)",buf); if (i>100) break; /* if ymax-ymin is very large and step is specified */ } width+=sysCharWidth/2; if (hc) fprintf(sd->HardFile,"] 0.5 GPLMW\n"); sd->Slate.left+=width; } } if (sd->Axis[0].bScale || sd->Axis[0].bGrid) { /* horizontal */ if (sd->Axis[0].bScale) { sprintf(buf,"%g",sd->RAxis[0].Max); sd->Slate.right-=(StringWidth(buf)>>1)+(sysCharWidth/4); if (hc) fprintf(sd->HardFile," [(%s)] 0.25 GPRMW\n",buf); if (!sd->Axis[0].bScale) { sprintf(buf,"%g",sd->RAxis[0].Min); sd->Slate.left+=(StringWidth(buf)>>1)+(sysCharWidth/4); if (hc) fprintf(sd->HardFile," [(%s)] 0.25 GPLMW\n",buf); } else { sd->Slate.bottom-=0.5*sysLineHeight-sysDescent; if (hc) fprintf(sd->HardFile," 0.5 0 GPBMW\n"); } } xstep=sd->RAxis[0].Tick; if (xstep<=0 || xstep>sd->RAxis[0].Max-sd->RAxis[0].Min) xstep=ApplyArtificialIntellectX(sd->RAxis[0].Min,sd->RAxis[0].Max, sd->Slate.right-sd->Slate.left); sd->RAxis[0].Step=xstep; } sd->Slate.right--; sd->Slate.right+=HOFF; sd->Slate.bottom--; sd->Slate.bottom+=VOFF; /* Windows coordinates of drawing rectangle */ sd->ix_min=MathToWinX(sd->RAxis[0].Min,sd); sd->ix_max=MathToWinX(sd->RAxis[0].Max,sd); sd->iy_min=MathToWinY(sd->RAxis[1].Min,sd); sd->iy_max=MathToWinY(sd->RAxis[1].Max,sd); if (hc) { fprintf(sd->HardFile," } bind def\n/GP?M GP?MW def\n\n"); } } #undef HOFF #undef VOFF Local(void) lRefreshScale(WinComDataPtr wcd) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; Select(sd->paPanel); /* Recalulate scales */ GetPosition(sd->paPanel,&sd->Slate); CalculateScales(wcd); /* Update panel */ Redraw(sd->paPanel); } /* Refresh scales after user pressed invisible DefaultButton */ Callback(void) RefreshScale(ButtoN b) { WinComDataPtr wcd=GetComDataC(b); lRefreshScale(wcd); UndoRecord(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); StairsDataPtr sd=(StairsDataPtr)wcd->Private; Int2 a,j; for (a=0; a<=1; a++) for (j=0; jteAxis[a].teLimits); j++) if (t==sd->teAxis[a].teLimits[j]) { GetTitleAndSave(t,&sd->Axis[a].pText[j]); GetNumbers(wcd); return; } } /* Get rectangle surrounding axis's lable and draw it */ Local(void) DrawLabel(WinComDataPtr wcd, Int2 axis, RectPtr pr) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; #define MAXCHAR (Int2)50 RecT r; CharPtr p; Int2 width; Char c; Boolean hc=sd->Hardcopy; /* Hardcopy */ SelectFont(SystemFont); if (!pr) pr=&r; p=sd->Axis[0].Func.pFunc; width=(StrLen(p)<=MAXCHAR) ? StringWidth(p) : TextWidth(p,MAXCHAR); if (axis==0) { /* abs */ LoadRect(pr,sd->ix_max-width,sd->iy_min-sysLineHeight, sd->ix_max,sd->iy_min); OffsetRect(pr,-(sysCharWidth/2),-(sysLineHeight/2)+sysDescent); } else { /* ord */ LoadRect(pr,sd->ix_min,sd->iy_max, sd->ix_min+width,sd->iy_max+sysLineHeight); OffsetRect(pr,(sysCharWidth/2),sysDescent); } if (StrLen(p)>MAXCHAR) { c=p[MAXCHAR]; p[MAXCHAR]='\0'; } else c='\0'; ColorSet(wcd->Foreground); lString(pr->left,pr->bottom-sysDescent,p); if (hc) fprintf(sd->HardFile,"(%s) G%cL\n",p,"XY"[axis]); if (c) p[MAXCHAR]=c; #undef MAXCHAR } /*----------------------------------------------*/ /* Palette SpeedBar support (in Graphic window) */ /* 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=sd->Attr; /* to simplify */ if (Attr.Path.style>0 && Attr.Path.color==Attr.Point.color) Attr.Path.color=col; Attr.Point.color=col; sd->Attr=Attr; Redraw(sd->paSample); } Callback(void) PalSampProc(PaneL pnl) { WinComDataPtr wcd=GetComDataC(pnl); StairsDataPtr sd=(StairsDataPtr)wcd->Private; RecT r; Select(pnl); GetPosition(pnl,&r); ColorSet(sd->Attr.Point.color); PaintRect(&r); } /*-----------------------------------------------------*/ /* Graphic panel callbacks: draw, click, drag, release */ Local(jmp_buf) grenv; #if _WIN #pragma argsused #endif Local(void) grex(int sig) { /* do nothing */ } Callback(void) DrawProc(PaneL panel) { WinComDataPtr wcd=GetComDataC(panel); StairsDataPtr sd=(StairsDataPtr)wcd->Private; FloatHi x,y,xmax,ymax; DrawAttr attr; RecT r,rr; Int2 i,j,ix,iy,ix_min,ix_max,iy_min,iy_max; Boolean scale; Boolean hc; /* is hardcopy requested for this window */ Char buf[50]; Char wrk[sizeof(Uint2)+1]; /* ClassGetDim */ 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=sd->Hardcopy; scale=!(sd->flags&DONT_SCALE); if (scale) { GetPosition(panel,&sd->Slate); /* first GetNumbers&CalculateScales call does not take into account scales, if any */ GetNumbers(wcd); CalculateScales(wcd); GetNumbers(wcd); GetPosition(panel,&sd->Slate); CalculateScales(wcd); } ix_min=sd->ix_min; ix_max=sd->ix_max; iy_min=sd->iy_min; iy_max=sd->iy_max; /* 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); /* Draw horizontal scale */ if (sd->Axis[0].bScale || sd->Axis[0].bGrid) { /* horizontal */ xmax=dtos(buf,"%g",sd->RAxis[0].Max); /* round it, if necessary */ j=iy_min+(sd->Axis[0].bScale ? 1.5*sysLineHeight-sysDescent : sysLineHeight); if (hc) { y=dtos(buf,"%g",sd->RAxis[0].Min); /* round it, if necessary */ } for (i=0; (x=dtos(buf,"%g",i*sd->RAxis[0].Step+sd->RAxis[0].Min),x<=xmax); i++) { ix=MathToWinX(x,sd); if (sd->Axis[0].bGrid && i) { if (hc) { fprintf(sd->HardFile,"%g GXG\n",x); } #if _UNIX SetPenDash(0,1,3); lLine(ix,iy_max,ix,iy_min); Solid(); #else LoadRect(&rr,ix,iy_max,ix+1,iy_min+1); #if _WIN /* Prevent CopyBits from crash */ if (iy_min>iy_max) #endif CopyBits(&rr,sd->GridVert); #endif } if (sd->Axis[0].bScale) { lString(ix-(StringWidth(buf)>>1),j,buf); lLine(ix,iy_min-(sysCharWidth/2),ix,iy_min); if (hc) { fprintf(sd->HardFile,sd->Axis[0].bScale ? "1.5 1" : " 1 1"); fprintf(sd->HardFile,"(%s) %g %g GXS\n",buf,x,y); } } if (i>100) break; /* if xmax-xmin is very large and step is specified */ } } /* Draw vertcial scale */ if (sd->Axis[0].bScale || sd->Axis[0].bGrid) { /* vertical */ GetPosition(panel,&r); ymax=dtos(buf,"%g",sd->RAxis[1].Max); /* round it, if necessary */ if (hc) { x=dtos(buf,"%g",sd->RAxis[1].Min); /* round it, if necessary */ } for (i=0; (y=dtos(buf,"%g",i*sd->RAxis[1].Step+sd->RAxis[1].Min),y<=ymax); i++) { iy=MathToWinY(y,sd); if (sd->Axis[0].bGrid && i) { if (hc) { fprintf(sd->HardFile,"%g GYG\n",y); } #if _UNIX SetPenDash(3,1,3); lLine(ix_min,iy,ix_max,iy); Solid(); #else LoadRect(&rr,ix_min,iy,ix_max+1,iy+1); #if _WIN /* Prevent CopyBits from crash */ if (ix_max>ix_min) #endif CopyBits(&rr,sd->GridHor); #endif } if (sd->Axis[0].bScale) { lString(sd->Slate.left-StringWidth(buf)-(sysCharWidth/4), iy+(sysAscent>>1),buf); lLine(ix_min,iy,ix_min+(sysCharWidth/2),iy); if (hc) { fprintf(sd->HardFile,"0.5 (%s) %g %g GYS\n",buf,x,y); } } if (i>100) break; /* if ymax-ymin is very large and step is specified */ } } /* Draw axes */ if (sd->Axis[0].bAxis) if (sd->RAxis[1].Min*sd->RAxis[1].Max<0) { i=MathToWinY(0,sd); lLine(ix_min,i,ix_max,i); if (hc) fprintf(sd->HardFile,"GXA\n"); } if (sd->Axis[0].bAxis) if (sd->RAxis[0].Min*sd->RAxis[0].Max<0) { j=MathToWinX(0,sd); lLine(j,iy_min,j,iy_max); if (hc) fprintf(sd->HardFile,"GYA\n"); } /* Draw frame */ FrameRect(&sd->Slate); if (hc) fprintf(sd->HardFile,"GFRAME\n\n"); /* Axes names for abs and ord */ if (sd->Axis[0].bFunc) for (i=0; i<2; i++) DrawLabel(wcd,i,NULL); /* Draw functions (rhs) */ if (sd->Options.Flags&GWIN_FUNC && FBStatus(-1)) { /* && types are chosen */ double x,f,ox,of,xw; double *t,*p,*dg; double step,y; int deg=0,i,x_min,y_min,x_max,y_max; Boolean first=TRUE; ClipRect(&sd->Slate); x=MAX(sd->RAxis[0].Min,sd->RAxis[1].Min); y=MIN(sd->RAxis[0].Max,sd->RAxis[1].Max); x_min=MathToWinX(x,sd); x_max=MathToWinX(y,sd); y_min=MathToWinY(x,sd); y_max=MathToWinY(y,sd); lLine(x_min,y_min,x_max,y_max); if (hc) fprintf(sd->HardFile,"%g %g %g %g LINE\n\n",x,x,y,y); wrk[0]='\0'; /* search by RealId */ *(Uint2Ptr)(wrk+1)=lClassGlobId(GCC_PHASE); dg=GetLocalClassVector(ClassGlobToLoc(lClassGlobId(GCC_SUP))); if (sd->flags&FOOL_DRAW) deg=1; else if (dg) { deg=*(int*)dg; if (deg<0 || deg>256) {Beep(); deg=0;} } if (sd->Options.Flags&GWIN_STAIRS && *GetClassDim(wrk)==1 && deg) { step=(sd->RAxis[0].Max-sd->RAxis[0].Min)/(ix_max-ix_min+1); t=GetLocalClassVector(ClassGlobToLoc(lClassGlobId(GCC_TIME))); p=GetLocalClassVector(ClassGlobToLoc(lClassGlobId(GCC_PAR))); StartCR(&grenv,grex); for (x=sd->RAxis[0].Min; x<=sd->RAxis[0].Max; x+=step) { if (setjmp(grenv)==0) { if (sd->flags&FOOL_DRAW) { f=SRHS(x); } else { /* Call Rhs according map_g.con, section &functions */ for (xw=x,i=0; iHardFile,"%g %g POINT\n",x,f); first=FALSE; } else { lLine(MathToWinX(ox,sd),MathToWinY(of,sd),MathToWinX(x,sd),MathToWinY(f,sd)); if (hc) fprintf(sd->HardFile,"%g %g %g %g LINE\n",ox,of,x,f); } ox=x; of=f; } } EndCR(); } ResetClip(); } ProcessUpdatesFirst(TRUE); } /*** Local(void) CompAB(FloatLoPtr a, FloatLoPtr b, StairsDataPtr sd) { *a=((FloatLo)sd->iy_max-sd->iy_min)/(sd->ix_max-sd->ix_min); *b=((FloatLo)sd->ix_max*sd->iy_min-sd->ix_min*sd->iy_max)/(sd->ix_max-sd->ix_min); } ***/ Local(void) DrawMarqueeRect(PaneL panel) { WinComDataPtr wcd=GetComDataC(panel); StairsDataPtr sd=(StairsDataPtr)wcd->Private; RecT r,mr; /*** FloatLo a,b;***/ Select(panel); /*** CompAB(&a,&b,sd); LoadRect(&r,(sd->ptCur.y-b)/a,a*sd->ptCur.x+b,sd->ptCur.x,sd->ptCur.y); ***/ LoadRect(&r,sd->ptCur.x,sd->ptCur.y,sd->ptLast.x,sd->ptLast.y); SectRect(&r,&sd->Slate,&mr); ColorSet(wcd->Foreground); FrameRect(&mr); } Callback(void) ClickProc(PaneL panel, PoinT pt) { WinComDataPtr wcd=GetComDataC(panel); StairsDataPtr sd=(StairsDataPtr)wcd->Private; if (ccd.Computing) { /* Computing is in progress - ignore */ sd->ptCur.x=INT2_MIN; return; } if (PtInRect(pt,&sd->Slate)) { sd->ptCur=pt; sd->bDrag=FALSE; } else sd->ptCur.x=INT2_MIN; } Callback(void) DragProc(PaneL panel, PoinT pt) { WinComDataPtr wcd=GetComDataC(panel); StairsDataPtr sd=(StairsDataPtr)wcd->Private; FloatHi f[2]; Int2 a,j; Char buf[20]; if (sd->ptCur.x==INT2_MIN) 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 (EqualPt(pt,sd->ptCur)) return; InvertMode(); if (sd->bDrag) { DrawMarqueeRect(panel); f[0]=WinToMathX(pt.x,sd); f[1]=WinToMathY(pt.y,sd); j=1; } else { sd->bDrag=TRUE; f[0]=WinToMathX(sd->ptCur.x,sd); f[1]=WinToMathY(sd->ptCur.y,sd); j=0; } for (a=0; a<=1; a++) if (sd->Axis[0].bLimits) { sprintf(buf,"%g",f[a]); SetTitle(sd->teAxis[a].teLimits[j],buf); } sd->ptLast=pt; DrawMarqueeRect(panel); } Callback(void) ReleaseProc(PaneL panel, PoinT pt) { WinComDataPtr wcd=GetComDataC(panel); StairsDataPtr sd=(StairsDataPtr)wcd->Private; FloatHi xmi,xma,ymi,yma,x; FloatHiPtr vp; Int2 a,j; Uint2 id; Uint1 loc_class; Char buf[20]; if (sd->ptCur.x==INT2_MIN) return; /* click was outside of drawing rectangle */ if (sd->bDrag) { /* Drag was called - change scales */ InvertMode(); DrawMarqueeRect(panel); if (PtInRect(pt,&sd->Slate)) { /* Change limits */ xmi=WinToMathX(sd->ptCur.x,sd); xma=WinToMathX(pt.x,sd); if (xmi>xma) {x=xmi; xmi=xma; xma=x;} ymi=WinToMathY(sd->ptCur.y,sd); yma=WinToMathY(pt.y,sd); if (ymi>yma) {x=ymi; ymi=yma; yma=x;} sd->RAxis[0].Min=xmi; sd->RAxis[0].Max=xma; sd->RAxis[1].Min=ymi; sd->RAxis[1].Max=yma; for (a=0; a<=1; a++) { for (j=0; j<2; j++) { sprintf(buf,"%g",sd->RAxis[a].Limits[j]); MemFree(sd->Axis[a].pText[j]); sd->Axis[a].pText[j]=StringSave(buf); } if (sd->Axis[0].bLimits) for (j=0; j<2; j++) SetTitle(sd->teAxis[a].teLimits[j],sd->Axis[a].pText[j]); } RefreshScale(sd->buRefr); } else { /* Release outside the Slate, don't change */ if (sd->Axis[0].bLimits) for (a=0; a<=1; a++) for (j=0; j<2; j++) SetTitle(sd->teAxis[a].teLimits[j],sd->Axis[a].pText[j]); } } else { /* Click-Hold-Release at the same place - set coordinates of initial point */ if (FBStatus(-1) && sd->flags&MOUSE_PICK) { x=WinToMathX(pt.x,sd); vp=NULL; if (GetClassNameAndId(sd->Axis[0].Func.IndirectIndex,NULL,&id)) { loc_class=ClassGlobToLoc(id); if (loc_class) vp=GetLocalClassVector(loc_class); } if (vp) { vp=(FloatHiPtr)((CharPtr)vp+sd->Axis[0].Func.Offset); *vp=x; UpdateInitPoint(); InvalidateBifData(); if (sd->flags&MOUSE_IMMF) { LockMenus(); Forward(0); UnlockMenus(); } return; } } Beep(); } } #if _UNIX #else /* Bitmaps for grids */ Local(void) BuildGrids(StairsDataPtr sd) { Int2 i,len; /* Vibrant documentation requires width to be in multiples of 2 bytes, but 1 also works */ #define VIB_MULT 1 len=VIB_MULT*(screenRect.bottom-screenRect.top); sd->GridVert=MemNew(len); for (i=0; iGridVert[i]=0x80; #undef VIB_MULT len=(screenRect.right-screenRect.left)/BITSPERBYTE+1; sd->GridHor=MemNew(len); MemFill(sd->GridHor,0x11,len); /* the leftmost bit must be 0 */ } Local(void) FreeGrids(StairsDataPtr sd) { MemFree(sd->GridVert); MemFree(sd->GridHor); } #endif /* _UNIX */ Local(void) SetCallbacks(StairsDataPtr sd, Boolean set) { if (set) SetPanelClick(sd->paPanel,ClickProc,DragProc,NULL,ReleaseProc); else SetPanelClick(sd->paPanel,NULL,NULL,NULL,NULL); } ClassMember(void) CreateControls(WinComDataPtr wcd) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; WindoW w; TexT t; RecT r; PoinT pt,pt1; PaneL pnl; int numwidth; Int2 a,i,panelw,panelh,width,spc; w=wcd->Win; /*** SetTitle(w,sd->Options.Flags&GWIN_STAIRS ? STAIRS_TITLE : PREVNEXT_TITLE); Use default or given by the user title. ***/ /* 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); sd->buRefr=DefaultButton(w,"",RefreshScale); sd->teAct=HiddenText(w,"",1,ActProc,NULL,NULL); Hide(sd->teAct); #if _WIN #ifdef WIN32 pt.y++; #else pt.y--; #endif #endif SetNextPosition(w,pt); /* Sizes */ panelw=wcd->Width; panelh=wcd->Height; /* Create Limits SpeedBar */ for (a=0; a<=1; a++) { sd->teAxis[a].prompt=NULL; for (i=0; iteAxis[a].teLimits); i++) sd->teAxis[a].teLimits[i]=NULL; } if (sd->Axis[0].bLimits) { sd->grLimits=CreateHiddenGroup(w,20,0,0); SetGroupMargins(sd->grLimits,sysCharWidth/2,0); SetGroupSpacing(sd->grLimits,spc=3,0); sscanf(GetParamString(SECTION,"NUMWIDTH"),"%i",&numwidth); for (a=0; a<=1; a++) { if (a) { /* make a break if there is not room */ width=StringWidth(Text[ORD_P]); GetNextPosition(sd->grLimits,&pt); pt.x+=sysCharWidth/2; SetNextPosition(sd->grLimits,pt); if (2*sysCharWidth+pt.x+ 4*spc+width+ 2*numwidth*sysCharWidth+StringWidth("..")+ (sd->Axis[0].bTick ? StringWidth(":")+numwidth*sysCharWidth : 0) > panelw ) Break(sd->grLimits); } sd->teAxis[a].prompt=StaticPrompt(sd->grLimits,Text[a ? ORD_P : ABS_P],0,dialogTextHeight,NULL,'l'); for (i=0; i<2; i++) { t=DialogText(sd->grLimits,sd->Axis[a].pText[i],numwidth,LimitsProc); SetTextSelect(t,SelectProc,NULL); sd->teAxis[a].teLimits[i]=t; if (!i) StaticPrompt(sd->grLimits,"..",0,dialogTextHeight,NULL,'l'); } if (sd->Axis[0].bTick) { StaticPrompt(sd->grLimits,":",0,dialogTextHeight,NULL,'l'); t=DialogText(sd->grLimits,sd->Axis[a].pTick,numwidth,LimitsProc); SetTextSelect(t,SelectProc,NULL); sd->teAxis[a].teLimits[3]=t; } } GetPosition(sd->grLimits,&r); panelh-=r.bottom-r.top; } else sd->grLimits=NULL; /* Create Palette SpeedBar */ if (sd->Options.Flags&GWIN_PALETTE) { sd->grPalette=CreateHiddenGroup(w,20,0,0); SetGroupMargins(sd->grPalette,sysCharWidth/2,0); SetGroupSpacing(sd->grPalette,sysCharWidth/2,0); pnl=SimplePanel(sd->grPalette,panelw-2*sysCharWidth,sysLineHeight,PalDrawProc); Redraw(pnl); SetPanelClick(pnl,PalSelProc,NULL,NULL,NULL); sd->paSample=SimplePanel(sd->grPalette,sysCharWidth,sysLineHeight,PalSampProc); Redraw(sd->paSample); GetPosition(sd->grPalette,&r); panelh-=r.bottom-r.top+1; } else sd->grPalette=NULL; /* Compute dimensions of drawing rectangle in a panel (will be created later) */ GetNextPosition(w,&pt); LoadRect(&sd->Slate,pt.x,pt.y,pt.x+panelw-1,pt.y+panelh-1); #if _UNIX /* no bitmaps, SetPenDash is used */ #else BuildGrids(sd); #endif /* _UNIX */ /* Process Scale */ /* first GetNumbers&CalculateScales call does not take scales into account, if any */ r=sd->Slate; GetNumbers(wcd); CalculateScales(wcd); GetNumbers(wcd); sd->Slate=r; CalculateScales(wcd); /* Create panel for drawing */ sd->paPanel=SimplePanel(w,panelw,panelh,DrawProc); SetCallbacks(sd,TRUE); Redraw(sd->paPanel); sd->InitLevel=0; UndoRecord(wcd); } ClassMember(void) RemoveControls(WinComDataPtr wcd) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; Hide(sd->grLimits); Hide(sd->grPalette); Remove(sd->buRefr); Remove(sd->teAct); Remove(sd->grLimits); Remove(sd->grPalette); Remove(sd->paPanel); #if _UNIX #else FreeGrids(sd); #endif } ClassMember(void) ManageControls(WinComDataPtr wcd, Boolean enable) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; (enable ? Enable : Disable)(sd->grLimits); (enable ? Enable : Disable)(sd->grPalette); /* Don't Enable/Disable sd->paPanel to avoid multiple redraws after Enable */ SetCallbacks(sd,enable); } ClassMember(void) BuildMenu(WinComDataPtr wcd) { MenuItemPtr ip; Int2 i; wcd->Foreground=BlackIndex; wcd->Background=WhiteIndex; 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==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; } } } ClassMember(void) NewInitPoint(WinComDataPtr wcd) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; /* We need only call when functions are selected. Calls from SetInitPoint should be ignored */ if (sd->Options.Flags&GWIN_FUNC) DrawProc(sd->paPanel); /* actually to draw RHS */ } ClassMember(void) ClearWindow(WinComDataPtr wcd) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; Redraw(sd->paPanel); UndoRecord(wcd); } ClassMember(Boolean) SimpleFunctions(WinComDataPtr wcd) { wcd->flags|=WFL_GDIM1; return TRUE; /* always nothing to compile */ } #if _WIN #pragma argsused #endif ClassMember(void) PutFunctions(WinComDataPtr wcd, FILE PNTR Source, Int2Ptr LineNum) { /* nothing */ } #if _WIN #pragma argsused #endif ClassMember(void) SetFunctions(WinComDataPtr wcd, LibHandle hWinLib) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; ParseName(sd->Axis[0].Func.pFunc,&sd->Axis[0].Func.IndirectIndex,&sd->Axis[0].Func.Offset); } ClassMember(void) ExportDescription(WinComDataPtr wcd, DataLibPtr arch, FILE PNTR out) { StairsDataPtr sd; Int2 a,i,j; ReadDescription(wcd,arch); /* also allocates private data area */ sd=(StairsDataPtr)wcd->Private; for (a=0; a<=1; a++) { for (j=0; jAxis[a].pText); j++) if (!FuncIndex(j)) fprintf(out," %s\n",sd->Axis[a].pText[j]); fprintf(out," %s\n", sd->Axis[a].Func.pFunc); } fprintf(out," "); for (j=0; jAxis[0].Prop); j++) fprintf(out,"%i ",(int)sd->Axis[0].Prop[j]); fprintf(out,"\n"); fprintf(out," point=(%li,%i,%i) path=(%li,%i,%i)\n", ColorOut(sd->Attr.Point.color),(int)sd->Attr.Point.width,(int)sd->Attr.Point.style, ColorOut(sd->Attr.Path.color),(int)sd->Attr.Path.width,(int)sd->Attr.Path.style); fprintf(out," options=(%i,%i)\n", (int)sd->Options.Flags, (int)sd->Options.Reserve); fprintf(out," undo=%i\n",(int)sd->UndoNum); for (i=0; iUndoNum; i++) fprintf(out," %g %g\n",sd->UndoBuf[i].xyMin,sd->UndoBuf[i].xyMax); WriteDescription(wcd,NULL); /* free mem only */ MemFree(sd); } ClassMember(void) ImportDescription(WinComDataPtr wcd, DataLibPtr arch, FILE PNTR in) { StairsData sd; long col1,col3; int i1,i2,i3,j1,j2,k2,k3; Int2 a,i,j; Char buf[PAR_BUF]; MemFill(&sd,0,sizeof(sd)); wcd->Private=&sd; for (a=0; a<=1; a++) { for (j=0; jPrivate; DrawAttr Point,Path; if (from) { BSRead(from,&Point,sizeof(Point)); BSRead(from,&Path,sizeof(Path)); } else { Point=sd->Attr.Point; Path=sd->Attr.Path; } if (to) { BSWrite(to,&Point,sizeof(Point)); BSWrite(to,&Path,sizeof(Path)); } else { DataLibWrite(dgm,(CharPtr)&Point,sizeof(Point)); DataLibWrite(dgm,(CharPtr)&Path,sizeof(Path)); } } ClassMember(void) RestoreAttr(WinComDataPtr wcd, DataLibPtr dgm, ByteStorePtr from, ByteStorePtr to, Boolean skip) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; DrawAttr Point,Path; if (from) { BSRead(from,&Point,sizeof(Point)); BSRead(from,&Path,sizeof(Path)); } else { DataLibRead(dgm,(CharPtr)&Point,sizeof(Point)); DataLibRead(dgm,(CharPtr)&Path,sizeof(Path)); } if (skip) return; if (to) { BSWrite(to,&Point,sizeof(Point)); BSWrite(to,&Path,sizeof(Path)); } else { sd->Attr.Point=Point; if (sd->Attr.Path.style<=0 && Path.style>0) { /* Switching from "don't join" to "join" */ sd->Attr.flags|=PATH_CHANGE; sd->joinpath=TRUE; } sd->Attr.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; MemCopy(&sd->SaveAttr,&sd->Attr,sizeof(sd->Attr)); } ClassMember(void) PopAttr(WinComDataPtr wcd) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; MemCopy(&sd->Attr,&sd->SaveAttr,sizeof(sd->Attr)); } #if _WIN #pragma argsused #endif ClassMember(void) SpecialAction(WinComDataPtr wcd, VisualSpecAction vsa) { /* nothing */ } #if _WIN #pragma argsused #endif ClassMember(void) FreeCurveData(WinComDataPtr wcd, FilePtr curvefp) { /* nothing */ } ClassMember(void) GInit(WinComDataPtr wcd) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; Int2 a,j; Boolean hc=sd->Hardcopy; if (sd->flags&FIT_IN_PROGRESS) return; sd->joinpath=FALSE; if (sd->Attr.Path.style>0) sd->joinpath=TRUE; /* Disable all speed bar controls */ if (!sd->InitLevel++) { for (a=0; a<=1; a++) for (j=0; jteAxis[a].teLimits); j++) Disable(sd->teAxis[a].teLimits[j]); Show(sd->teAct); } if (hc) fprintf(sd->HardFile,"\n%%BeginCurve: %s\n",DiagramLib.DirName); } ClassMember(void) GTerm(WinComDataPtr wcd) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; Int2 a,j; Boolean hc=sd->Hardcopy; if (sd->flags&FIT_IN_PROGRESS) return; /* Enable all speed bar controls */ if (!--sd->InitLevel) { for (a=0; a<=1; a++) for (j=0; jteAxis[a].teLimits); j++) Enable(sd->teAxis[a].teLimits[j]); Hide(sd->teAct); } if (hc) fprintf(sd->HardFile,"%%EndCurve: %s\n",DiagramLib.DirName); } Local(void) GraphicSwap(StairsDataPtr sd) { PoinT pt; pt=sd->Attr.PrevPath; sd->Attr.PrevPath=sd->Attr.CurPath; sd->Attr.CurPath=pt; if (sd->Hardcopy) { MathPoint pt; pt=sd->Attr.hcPrevPath; sd->Attr.hcPrevPath=sd->Attr.hcCurPath; sd->Attr.hcCurPath=pt; } } ClassMember(void) MInit(WinComDataPtr wcd) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; RecT r; if (sd->flags&FIT_IN_PROGRESS) return; if (sd->Options.Flags&GWIN_CLEAR) { UseWindow(wcd->Win); Select(sd->paPanel); Solid(); WidePen(1); /* just for Mac and Motif */ r=sd->Slate; InsetRect(&r,1,1); ClipRect(&r); sd->flags|=DONT_SCALE; DrawProc(sd->paPanel); sd->flags&=~DONT_SCALE; } if (sd->Attr.flags&PATH_CHANGE) GraphicSwap(sd); } ClassMember(void) MTerm(WinComDataPtr wcd) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; if (sd->flags&FIT_IN_PROGRESS) return; if (sd->Attr.Path.style>0 || !(sd->Options.Flags&GWIN_STAIRS)) GraphicSwap(sd); } Local(StairsDataPtr) Sd; /* used only by functions called by MProcess */ Local(FloatHi) mpt[2]; Local(void) hcLine(FloatHiPtr ptprev, FloatHiPtr pt) { fprintf(Sd->HardFile,"%g %g %g %g LINE\n",pt[0],pt[1],ptprev[0],ptprev[1]); } Local(void) hcPoint(FloatHiPtr pt) { fprintf(Sd->HardFile,"%g %g POINT\n",pt[0],pt[1]); } ClassMember(void) MProcess(WinComDataPtr wcd) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; FloatHi x; FloatHi hcx[2]; RecT r; Int2 a,ix,iy,ox,oy; Boolean hc=sd->Hardcopy; /* TRUE if Hardcopy is in progress */ Boolean stairs=sd->Options.Flags&GWIN_STAIRS; Boolean notfirst; /* point on G-curve */ Select(sd->paPanel); r=sd->Slate; InsetRect(&r,1,1); ClipRect(&r); Sd=sd; /* Compute functions along axes and convert their values to window coordinates */ x=*(FloatHiPtr)((CharPtr)*IndirectValues[sd->Axis[0].Func.IndirectIndex]+ sd->Axis[0].Func.Offset); if (sd->flags&FIT_IN_PROGRESS) { for (a=0; a<=1; a++) { if (xRAxis[a].FitMin) sd->RAxis[a].FitMin=x; if (x>sd->RAxis[a].FitMax) sd->RAxis[a].FitMax=x; } return; } if (x==NOUPDATE) return; ix=MathToWinX(x,sd); iy=MathToWinY(x,sd); notfirst=!(wcd->flags&WFL_G1) && !(sd->Attr.flags&PATH_CHANGE); ox=sd->Attr.PrevPath.x; oy=sd->Attr.PrevPath.y; /* Join current point with previous one(s) along a path */ if (sd->Attr.Path.style>0) { if (notfirst) { if (stairs) { SetCurrentPen(&sd->Attr.Path); lLine(ox,oy,ox,iy); if (hc) { hcx[0]=sd->Attr.hcPrevPath.x; hcx[1]=x; mpt[0]=sd->Attr.hcPrevPath.x; mpt[1]=sd->Attr.hcPrevPath.y; hcLine(mpt,hcx); } lLine(ox,iy,ix,iy); if (hc) { mpt[0]=mpt[1]=x; hcLine(mpt,hcx); } SetCurrentPen(&sd->Attr.Point); lPoint(ox,oy); if (hc) { mpt[0]=sd->Attr.hcPrevPath.x; mpt[1]=sd->Attr.hcPrevPath.y; hcPoint(mpt); } } /* else nothing for Prev-Next form */ } else sd->Attr.flags&=~PATH_CHANGE; } LoadPt(&sd->Attr.CurPath,ix,iy); if (hc) { sd->Attr.hcCurPath.x=x; sd->Attr.hcCurPath.y=x; } /* Plot the current point */ SetCurrentPen(&sd->Attr.Point); if (stairs) { lPoint(ix,iy); if (hc) { hcx[0]=hcx[1]=x; hcPoint(hcx); } } else { if (notfirst) { lPoint(ox,iy); if (hc) { hcx[0]=sd->Attr.hcPrevPath.x; hcx[1]=x; hcPoint(hcx); } } } } 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) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; fprintf(sd->HardFile,"%i %i PEN\n",(int)attr->width,(int)attr->style); hcSetColor(sd->HardFile,"COLOR\n"); } ClassMember(void) hcString(WinComDataPtr wcd, CharPtr str, float PNTR hardcopy) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; Int2 i; fprintf(sd->HardFile,"(%s)",str); for (i=0; i<6; ) fprintf(sd->HardFile," %g",hardcopy[i++]); fprintf(sd->HardFile," %g %g STRMARKER\n",mpt[0],mpt[1]); } ClassMember(void) hcPaintOval(WinComDataPtr wcd, RectPtr r) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; fprintf(sd->HardFile,"%g %g %g ",mpt[0],mpt[1],(r->right-r->left)/2.0); hcSetColor(sd->HardFile,"PAINTCIRCLE\n"); } ClassMember(void) hcFrameOval(WinComDataPtr wcd, RectPtr r) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; fprintf(sd->HardFile,"%g %g %g ",mpt[0],mpt[1],(r->right-r->left)/2.0); hcSetColor(sd->HardFile,"FRAMECIRCLE\n"); } Local(void) hcPoly(StairsDataPtr sd, 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-MathToWinX(mpt[0],sd); wy=-(poly[0].y-MathToWinY(mpt[1],sd)); } fprintf(sd->HardFile," %i %i",(int)wx,(int)wy); } fprintf(sd->HardFile," %i %g %g ",(int)num,mpt[0],mpt[1]); hcSetColor(sd->HardFile,oper); } ClassMember(void) hcPaintPoly(WinComDataPtr wcd, Int2 num, PointPtr poly) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; hcPoly(sd,num,poly,"PAINTPOLY\n"); } ClassMember(void) hcFramePoly(WinComDataPtr wcd, Int2 num, PointPtr poly) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; hcPoly(sd,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; StairsDataPtr sd=(StairsDataPtr)wcd->Private; TexT t; FloatHi d; Int2 a,j; Boolean change=FALSE; Char buf[30]; DeactivateWindows(wcd); for (a=0; a<=1; a++) { sd->RAxis[a].FitMin=DBL_MAX; sd->RAxis[a].FitMax=-DBL_MAX; } sd->flags|=FIT_IN_PROGRESS; if (diagram) RedrawDiagram(0); else RedrawCurve(0); sd->flags^=FIT_IN_PROGRESS; UseWindow(wcd->Win); for (a=0; a<=1; a++) { if (sd->RAxis[a].FitMin!=DBL_MAX && sd->RAxis[a].FitMin!=sd->RAxis[a].FitMax) { change=TRUE; d=(sd->RAxis[a].FitMax-sd->RAxis[a].FitMin)/100*PERCENT; sd->RAxis[a].Min=sd->RAxis[a].FitMin-d; sd->RAxis[a].Max=sd->RAxis[a].FitMax+d; /* Update controls, see LimitsProc */ for (j=0; j<2; j++) { /* 0 - Min, 1 - Max */ sprintf(buf,"%g",sd->RAxis[a].Limits[j]); MemFree(sd->Axis[a].pText[j]); sd->Axis[a].pText[j]=StringSave(buf); t=sd->teAxis[a].teLimits[j]; if (t) SetTitle(t,buf); } /* Tick */ if (sd->RAxis[a].Tick>0) { if (Message(MSG_YN, "Fit has found non-zero tick value.\n" "Set it to zero?\n" "(to allow Content to determine it)") ==ANS_YES) { sd->RAxis[a].Tick=0; MemFree(sd->Axis[a].pTick); sd->Axis[a].pTick=StringSave("0"); t=sd->teAxis[a].teLimits[3]; if (t) SetTitle(t,"0"); } } GetNumbers(wcd); } } if (change) { ClearWindow(wcd); if (diagram) RedrawDiagram(0); else RedrawCurve(0); } ActivateWindows(); } #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) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; Int2 a,i,n=sd->UndoNum; if (sd->UndoBuf) { if (sd->UndoBuf[n].xyMin[0]!=sd->RAxis[0].Min || sd->UndoBuf[n].xyMax[0]!=sd->RAxis[0].Max || sd->UndoBuf[n].xyMin[1]!=sd->RAxis[1].Min || sd->UndoBuf[n].xyMax[1]!=sd->RAxis[1].Max) { if (n==UNDODEPTH-1) for (i=0; iUndoBuf[i]=sd->UndoBuf[i+1]; else n++; } else return; } else { sd->UndoBuf=MemNew(ARRAYSIZE(UndoElem,UNDODEPTH)); n=0; } for (a=0; a<=1; a++) { sd->UndoBuf[n].xyMin[a]=sd->RAxis[a].Min; sd->UndoBuf[n].xyMax[a]=sd->RAxis[a].Max; } sd->UndoNum=n; SetStatusOfItems(&wcd->MenuDesc); } #if _WIN #pragma argsused #endif Callback(void) lUndoScale(Int2 index) { WinComDataPtr wcd=GetComDataI; StairsDataPtr sd=(StairsDataPtr)wcd->Private; UndoElem ue; Int2 a,i,j,n; Char b[20]; n=sd->UndoNum; /* n>0! see UndoScale_Status */ ue=sd->UndoBuf[n]; for (i=n; i; i--) sd->UndoBuf[i]=sd->UndoBuf[i-1]; sd->UndoBuf[0]=ue; for (a=0; a<=1; a++) { for (j=0; j<2; j++) { sd->RAxis[a].Min=sd->UndoBuf[n].xyMin[a]; sd->RAxis[a].Max=sd->UndoBuf[n].xyMax[a]; sprintf(b,"%g",sd->RAxis[a].Limits[j]); MemFree(sd->Axis[a].pText[j]); sd->Axis[a].pText[j]=StringSave(b); if (sd->Axis[0].bLimits) SetTitle(sd->teAxis[a].teLimits[j],sd->Axis[a].pText[j]); } } lRefreshScale(wcd); } #if _WIN #pragma argsused #endif Callback(Boolean) lUndoScale_Status(Int2 index) { WinComDataPtr wcd=GetComDataI; StairsDataPtr sd=(StairsDataPtr)wcd->Private; return sd->UndoNum>0; } /*----------------------------------*/ /* Menu callback: Layout dialog box */ typedef struct { WinComDataPtr Com; /* Common data for all classes of windows */ Color Colors[2]; /* colors */ struct { CharPtr pTrace; /* to array of ptrs to all V-functions along the axis */ Boolean Prop[6]; /* 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[6]; /* must be == to DIM(StairsWindow.Axis.Prop) */ } Axis[2]; FuncAttr Attr; /* to array of points,traces,paths atributes */ TexT Title; /* WinTitle */ GrouP grAttrOf; /* 'Set attributes of' group */ ButtoN buAttrOf[2]; /* 0-points, 1-paths */ 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 */ GrouP grDrawAs; /* Choice: Stairs/Prev-Next form */ ButtoN cbPalette; /* 'Show palette in window' */ ButtoN cbFunc; /* 'Draw Rhs in window' */ PaneL paSample; /* Panel to display a sample of window */ PaneL paLimits,paPalette,paDraw; /* and its superimposed parts */ PrompT prVar; /* Current variable for axes */ /* Fields related to attributes of current curve */ Int2 spnum; /* number of special points (only last pt for trajectories) */ 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 */ Uint1 Lock; /* to prevent recursion in SampleProc */ Boolean NewVar; /* Set if variable has been chosen */ } 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'); } Local(void) ShowGrAttributes(LayoutDataPtr layout, Int2 i) { DrawAttrPtr pda; switch (i) { case 0: pda=&layout->Attr.Point; break; case 1: pda=&layout->Attr.Path; 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) { Int2 j; Char b[100]; switch (layout->Kind) { case 0: /* current */ SetValue(layout->grDrawAs,(layout->Options.Flags&GWIN_STAIRS) ? 1 : 2); sprintf(b,Text[CURNAME_P],layout->Axis[0].pTrace); SetTitle(layout->prVar,b); SetStatus(layout->cbClear,(Boolean)(layout->Options.Flags&GWIN_CLEAR)); case 2: /* curve */ ShowGrAttributes(layout,GetValue(layout->grAttrOf)-1); break; case 1: /* axes */ for (j=0; jAxis[0].Prop); j++) SetStatus(layout->Axis[0].cbProp[j],layout->Axis[0].Prop[j]); (layout->Axis[0].Prop[0] ? Enable : Disable)(layout->Axis[0].cbProp[1]); /* Tick depends on Limits */ SetStatus(layout->cbPalette,(Boolean)(layout->Options.Flags&GWIN_PALETTE)); SetStatus(layout->cbFunc,(Boolean)(layout->Options.Flags&GWIN_FUNC)); break; } if (redraw) Redraw(layout->paSample); } /* Palette/Circle common callback */ Callback(void) PCCProc(ButtoN bu) { LayoutDataPtr layout=GetLayoutData(bu); Uint1 fl; if (bu==layout->cbPalette) fl=GWIN_PALETTE; if (bu==layout->cbFunc) fl=GWIN_FUNC; 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 /* grDrawAs callback */ Callback(void) DrawAsProc(GrouP g) { LayoutDataPtr layout=GetLayoutData(g); Int2 i=GetValue(g); if (i==1) { layout->Options.Flags|=GWIN_STAIRS; layout->Attr.Path.style=1; /* solid */ } else { layout->Options.Flags&=~GWIN_STAIRS; layout->Attr.Path.style=0; /* don't join */ } ShowAttributes(layout,TRUE); } /* cbClear checkbox callback */ #define ClearProc PCCProc /* cbPalette checkbox callback */ #define ShowPaletteProc PCCProc /* cbfunc checkbox callback */ #define FuncProc 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.Point.width=width; break; case 2: /* Paths */ layout->Attr.Path.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.Path.style=style; break; } ShowAttributes(layout,TRUE); } /* cbProp[1-5] callback */ Callback(void) PropProc(ButtoN bu) { LayoutDataPtr layout=GetLayoutData(bu); Int2 j; for (j=0; jAxis[0].Prop); j++) if (bu==layout->Axis[0].cbProp[j]) { layout->Axis[0].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[0].bLimits) { Select(paLimits); SelectFont(SystemFont); GetPosition(paLimits,&r); off=r.left+2; for (a=0; a<=1; a++) { r.left=off; off+=StringWidth(StrCpy(Buf,Text[a?ORD_P:ABS_P]))+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[j])+(sysCharWidth/4); r.right=off; DrawString(&r,SampLims[j],'c',FALSE); FrameRect(&r); off+=2; } } } } #define SamplePaletteProc PaletteProc Local(void) CopyFromWork(WinComDataPtr wcd, LayoutDataPtr layout); #define GPN 6 /* G-points in sample curve */ Local(Int2) Ox,Oy,Dx,Dy; Local(FloatLo) xmin,xmax; Local(Int2) SampleX(FloatLo x) { return Ox+(x-xmin)/(xmax-xmin)*Dx; } Local(Int2) SampleY(FloatLo y) { return Oy-(y-xmin)/(xmax-xmin)*Dy; } Callback(void) SampleDrawProc(PaneL paDraw) { LayoutDataPtr layout=GetLayoutData(paDraw); WinComData foolwcd; StairsData foolsd; DrawAttr flowers; WindoW attrwin=ParentWindow(paDraw); VoidPtr saveExtra=GetWindowExtra(attrwin); FuncAttr Attr; RecT r; FloatLo x,y,ox,oy; Int2 Kind; Int2 a,j; Select(paDraw); GetPosition(paDraw,&r); /* Use GraphDrawProc and VisualizerGPoint to draw the Sample */ /* 1. Fool DrawProc before call */ MemFill(&foolwcd,0,sizeof(WinComData)); MemFill(&foolsd,0,sizeof(StairsData)); #if _UNIX #else BuildGrids(&foolsd); #endif foolwcd.Private=&foolsd; foolsd.flags|=FOOL_DRAW; /* 2. Fill in foolwcd from layout */ Kind=layout->Kind; layout->Kind=0; CopyFromWork(&foolwcd,layout); layout->Kind=Kind; MemMove(&foolwcd.Colors,layout->Colors,sizeof(foolwcd.Colors)); for (a=0; a<=1; a++) for (j=0; jAttr; flowers.color=layout->Foreground; flowers.width=1; flowers.style=1; for (j=0; jOptions.Flags&GWIN_STAIRS) { /* Join current point with previous one along a path */ if (Attr.Path.style>0) { if (j) { SetCurrentPen(&Attr.Path); lLine(SampleX(ox),SampleY(ox),SampleX(ox),SampleY(oy)); lLine(SampleX(ox),SampleY(oy),SampleX(oy),SampleY(oy)); SetCurrentPen(&Attr.Point); lPoint(SampleX(ox),SampleY(ox)); } } /* Plot the current point */ lPoint(SampleX(x),SampleY(x)); } else { /* Join current point with previous one along a path */ if (Attr.Path.style>0) { if (j) { SetCurrentPen(&Attr.Path); lLine(SampleX(ox),SampleY(oy),SampleX(x),SampleY(y)); SetCurrentPen(&Attr.Point); lPoint(SampleX(ox),SampleY(oy)); } } /* Plot the current point */ lPoint(SampleX(x),SampleY(y)); } ox=x; oy=y; x=y; } /* 5. Restore everything. This does not write but frees memory only */ #if _UNIX #else FreeGrids(&foolsd); #endif WriteDescription(&foolwcd,NULL); SetWindowExtra(attrwin,saveExtra,NULL); } 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) { 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; } /* 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). */ /* ASSERT: s==1 */ Local(void) ActivateSegment(LayoutDataPtr layout, Int2 s) { WinComDataPtr wcd=layout->Com; StairsDataPtr sd=(StairsDataPtr)wcd->Private; BSSeek(layout->spbs[s-1],0,SEEK_SET); RestoreVisualAttr(&DiagramLib,layout->spbs[s-1],NULL); /* Copy V-functions (for show sample only!) */ layout->Axis[0].pTrace=StringSave(sd->Axis[0].Func.pFunc); /* Copy attributes of V-functions */ MemMove(&layout->Attr,&sd->Attr,sizeof(FuncAttr)); } /* ASSERT: s==1 */ Local(void) DeactivateSegment(LayoutDataPtr layout, Int2 s) { WinComDataPtr wcd=layout->Com; StairsDataPtr sd=(StairsDataPtr)wcd->Private; BSFree(layout->spbs[s-1]); layout->spbs[s-1]=BSNew(0); MemMove(&sd->Attr,&layout->Attr,sizeof(FuncAttr)); layout->Axis[0].pTrace=MemFree(layout->Axis[0].pTrace); SaveVisualAttr(&DiagramLib,NULL,layout->spbs[s-1],FALSE); } /* Copy visual attributes to/from layout work area and free it */ Local(void) CopyToWork(LayoutDataPtr layout, WinComDataPtr wcd) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; if (layout->Kind==2) { /* attribs of active curve */ PushVisualAttr(TRUE); /* will be restored in FreeAttributes */ DataLibSavePos(&DiagramLib); ReadSPList(&layout->spnum,&layout->splist); ReadVAList(layout->spnum+1,&layout->spbs); ActivateSegment(layout,1); } else { MemMove(&layout->Attr,&sd->Attr,sizeof(layout->Attr)); /* Copy V-functions */ layout->Axis[0].pTrace=StringSave(sd->Axis[0].Func.pFunc); } MemMove(&layout->Axis[0].Prop,&sd->Axis[0].Prop,sizeof(layout->Axis[0].Prop)); /* Copy general attributes */ MemMove(layout->Colors,wcd->Colors,sizeof(layout->Colors)); layout->Options=sd->Options; } Local(void) CopyFromWork(WinComDataPtr wcd, LayoutDataPtr layout) { StairsDataPtr sd=(StairsDataPtr)wcd->Private; Int2 a,j; if (layout->Kind==2) { /* attribs of active curve */ /* First save segment's attributes to spbs[...] */ DeactivateSegment(layout,1); /* Now save to DiagramLib */ WriteVAList(layout->spnum+1,layout->spbs); return; } MemFree(sd->Axis[0].Func.pFunc); sd->Axis[0].Func.pFunc=StringSave(layout->Axis[0].pTrace); MemMove(&sd->Attr,&layout->Attr,sizeof(FuncAttr)); MemMove(sd->Axis[0].Prop,layout->Axis[0].Prop,sizeof(sd->Axis[0].Prop)); switch (layout->Kind) { case 0: /* current */ case 2: /* curve */ break; case 1: /* axes */ GetTitleAndSave(layout->Title,&wcd->WinTitle); for (a=0; a<=1; a++) for (j=0; jAxis[a].pText); j++) if (!FuncIndex(j)) GetTitleAndSave(layout->Axis[a].teText[j],&sd->Axis[a].pText[j]); break; } /* Copy general attributes */ MemMove(wcd->Colors,layout->Colors,sizeof(wcd->Colors)); sd->Options=layout->Options; } Local(void) FreeWork(LayoutDataPtr layout) { if (layout->Kind==2) { FreeSPList(layout->spnum,layout->splist); FreeVAList(layout->spnum,layout->spbs); PopVisualAttr(); DataLibRestorePos(&DiagramLib); } MemFree(layout->Axis[0].pTrace); } Local(void) CreateSampleGroup(GrouP parent, Int2 width, Int2 height) { LayoutDataPtr layout=GetLayoutData(parent); GrouP g; g=CreateNormalGroup(parent,0,0,Text[SAMPLE_WIN]); layout->SampleHeight=height; layout->paSample=SimplePanel(g,1,1,SampleProc); Hide(layout->paLimits=SimplePanel(g,width,sysLineHeight,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, don't recompile but force to SetFunctions */ if (layout->NewVar) 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; StairsDataPtr sd=(StairsDataPtr)wcd->Private; LayoutDataPtr layout; WindoW db; GrouP MainGroup,g,gT,gM,gA,gS,gFBS; RecT r; Int2 a,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); gM=CreateHiddenGroup(MainGroup,2,0,0); gT=CreateHiddenGroup(gM,2,0,1); CreatePrompt(gT,WINTITLE_P); layout->Title=DialogText(gT,wcd->WinTitle,1,NULL); CreatePrompt(gM,-1); g=CreateHiddenGroup(gM,0,5,1); gA=CreateNormalGroup(g,3,0,Text[ABSORD_P]); SetGroupSpacing(gA,GetGroupSM("nsx"),0); StdPrmt=FALSE; CreatePrompt(gA,MIN_P); CreatePrompt(gA,MAX_P); CreatePrompt(gA,TICK_P); StdPrmt=TRUE; for (a=0; a<=1; a++) for (j=0; jAxis[a].teText); j++) if (!FuncIndex(j)) layout->Axis[a].teText[j]=DialogText(gA,sd->Axis[a].pText[j],numwidth,NULL); gS=CreateNormalGroup(g,3,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[GRID_P],PropProc); layout->Axis[0].cbProp[5]=CheckBox(gS,Text[AXES_P],PropProc); layout->cbPalette=CheckBox(gS,Text[SHOWPAL_P],ShowPaletteProc); layout->cbFunc=CheckBox(gS,Text[RHS_P],FuncProc); gFBS=CreateNormalGroup(g,2,0,Text[COLORS_T]); PushButton(gFBS,Text[FG_P],SetFGColor); PushButton(gFBS,Text[BG_P],SetBGColor); GetPosition(g,&r); j=r.bottom-r.top-2*(GetGroupSM("hmy")+GetGroupSM("hsy"))-sysLineHeight; CreateSampleGroup(gM,(r.right-r.left)-2*GetGroupSM("hmx"),j); AlignObjects(ALIGN_RIGHT,(HANDLE)layout->Title,(HANDLE)layout->paDraw,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.Point.color; break; case 2: /* Path */ cp=&layout->Attr.Path.color; break; } *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]); 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) NamesListProc(LisT l, Int2 var) { LayoutDataPtr layout=GetLayoutData(l); CharPtr PNTR pn; pn=(CharPtr PNTR)GetObjectExtra(l); MemFree(layout->Axis[0].pTrace); layout->Axis[0].pTrace=StringSave(pn[var-1]); /* name to insert */ layout->NewVar=TRUE; ShowAttributes(layout,TRUE); } Callback(void) lCurrentAtr(Int2 indx) { WinComDataPtr wcd=GetComDataI; LayoutDataPtr layout; WindoW db; GrouP MainGroup; GrouP gSWSC,gSWS,gA,gOptions; RecT r; 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); /* Graphic options and sample */ if (layout->Kind==0) { gA=CreateNormalGroup(MainGroup,2,0,Text[AXES_P]); CreateNamesList(gA,linelen,lines,NamesListProc,NULL); layout->prVar=CreatePrompt(gA,-1); } else layout->prVar=NULL; gSWSC=CreateHiddenGroup(MainGroup,4,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,2,0,Text[OPTIONS_P]); layout->grDrawAs=HiddenGroup(gOptions,2,0,DrawAsProc); SetGroupSpacing(layout->grDrawAs,2*GetGroupSM("hsx"),0); SetGroupMargins(layout->grDrawAs,GetGroupSM("hmx"),0); RadioButton(layout->grDrawAs,Text[STAIRS_B]); RadioButton(layout->grDrawAs,Text[PREVNEXT_B]); layout->cbClear=CheckBox(gOptions,Text[CLEAR_P],ClearProc); } AlignObjects(ALIGN_RIGHT,(HANDLE)layout->paLimits, (HANDLE)layout->paPalette, (HANDLE)layout->paDraw, (HANDLE)layout->prVar, 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" "%% 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" "%% 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" "%% incLeftMargin: [lm rm tm bm] [(s1)...] w GPLMW [lm rm tm bm]\n" "/GPLMW {\n" " GSTDW mul exch 0 exch\n" " {stringwidth pop 1 index 1 index lt {exch} if pop} forall\n" " add exch dup 0 get 3 -1 roll add 0 exch PUT4\n" " } bind def\n" "%% incRightMargin: [lm rm tm bm] [(s1)...] w GPRMW [lm rm tm bm]\n" "/GPRMW {" " GSTDW mul exch 0 exch\n" " {stringwidth pop 1 index 1 index lt {exch} if pop} forall\n" " add exch dup 1 get 3 -1 roll add 1 exch PUT4\n" " } bind def\n" "%% incTopMargin: [lm rm tm bm] h d GPTMW [lm rm tm bm]\n" "/GPTMW {\n" " GSTDHD GSPW exch dup 2 get 3 -1 roll add 2 exch PUT4" " } bind def\n" "%% incBottomMargin: [lm rm tm bm] h d GPBMW [lm rm tm bm]\n" "/GPBMW {\n" " GSTDHD GSPW exch dup 3 get 3 -1 roll add 3 exch PUT4\n" " } bind def\n\n" "%% xScale: HeighFactor DescentFactor (s) x y GXS\n" "/GXS {\n" " newpath 1 index 1 index GSETMATH 3 1 roll moveto setmatrix\n" " 0 GSTDW 2 div rlineto 1 GLWIDTH setlinewidth stroke\n" " newpath GSETMATH 3 1 roll moveto setmatrix\n" " 3 1 roll GSTDHD GSPW neg 1 index stringwidth pop 2 div neg exch rmoveto show\n" " stroke} bind def\n" "%% yScale: RelRightMargin (s) x y GYS\n" "/GYS {\n" " newpath 1 index 1 index GSETMATH 3 1 roll moveto setmatrix\n" " GSTDW 2 div 0 rlineto 1 GLWIDTH setlinewidth stroke\n" " newpath GSETMATH 3 1 roll moveto setmatrix\n" " exch GSTDW mul 1 index stringwidth pop add neg GSTDHD pop 2 div neg rmoveto show\n" " stroke} bind def\n" "%% xLabel: (label) GXL\n" "/GXL {\n" " GMXMAXW GMYMINW newpath GSETMATH 3 1 roll moveto setmatrix\n" " dup stringwidth pop GSTDW 2 div add neg GSTDHD pop 2 div rmoveto show stroke\n" " } bind def\n" "%% yLabel: (label) GYL\n" "/GYL {\n" " GMXMINW GMYMAXW newpath GSETMATH 3 1 roll moveto setmatrix\n" " GSTDW 2 div 1.5 0 GSTDHD GSPW neg rmoveto show stroke\n" " } bind def\n" "%% xAxis: GXA\n" "/GXA {\n" " newpath GSETMATH GMXMINW 0 moveto GMXMAXW 0 lineto setmatrix\n" " 1 GLWIDTH setlinewidth stroke\n" " } bind def\n" "%% yAxis: GYA\n" "/GYA {\n" " newpath GSETMATH 0 GMYMINW moveto 0 GMYMAXW lineto setmatrix\n" " 1 GLWIDTH setlinewidth stroke\n" " } bind def\n" "%% xGrid: x GXG\n" "/GXG {\n" " newpath GSETMATH exch dup GMYMINW moveto GMYMAXW lineto setmatrix\n" " gsave 1 GLWIDTH setlinewidth [GSTDW 32 div GSTDW 2 div] GSTDW 8 div setdash stroke grestore\n" " } bind def\n" "%% yGrid: y GYG\n" "/GYG {\n" " newpath GSETMATH exch dup GMXMINW exch moveto GMXMAXW exch lineto setmatrix\n" " gsave 1 GLWIDTH setlinewidth [GSTDW 32 div GSTDW 2 div] GSTDW 8 div setdash stroke grestore\n" " } bind def\n\n" "%% Frame: - GFRAME -\n" "/GFRAME {newpath\n" " GPLM GPBM moveto\n" " GPW GPRM sub GPBM lineto\n" " GPW GPRM sub GPH GPTM sub lineto\n" " GPLM GPH GPTM sub lineto\n" " closepath 1 GLWIDTH setlinewidth gsave stroke grestore clip} bind def\n" "%% UnitCircle: - GUNITCIRCLE -\n" "/GUNITCIRCLE {\n" "newpath GSETMATH 0 0 1 0 360 arc setmatrix\n" "1 GLWIDTH setlinewidth stroke\n" "} bind def\n\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(StairsDataPtr sd) { Char date[25]; /* see DayTimeStr in corelib */ /* Header */ DayTimeStr(date,TRUE,TRUE); /* get date and time */ fprintf(sd->HardFile,hc_Header,date,hcPageWidth, hcPageHeight); /* Procedure defenitions */ fprintf(sd->HardFile,hc_ProcDef,hcPageWidth,hcPageHeight, sd->RAxis[0].Min, sd->RAxis[0].Max, sd->RAxis[1].Min, sd->RAxis[1].Max, hcCurveWidthFactor, hcLineWidthFactor, hcMarkerFactor, hcColor ? "true" : "false" ); /* Document setup */ fprintf(sd->HardFile,hc_DocSetup,hcFontList[hcFontCur],(int)hcFontSize); sd->hcMarkerNo=0; } Local(Char) hc_Trailer[]= /*** "%%lpr%% showpage\n"***/ "showpage\n" "%%%%Trailer\n" "%%%%EOF\n" ; /* Output Document trailer */ Local(void) hcTerm(StairsDataPtr sd) { int i; fprintf(sd->HardFile,"%%BeginMarkers:\n"); for (i=0; ihcMarkerNo; i++) fprintf(sd->HardFile,"MARKER%i\n",i); fprintf(sd->HardFile,"%%EndMarkers:\n"); fprintf(sd->HardFile,hc_Trailer); } Callback(void) HardcopyOk(ButtoN b) { WindoW optwin=ParentWindow(b); hcOptDataPtr data=(hcOptDataPtr)GetWindowExtra(optwin); WinComDataPtr wcd=(WinComDataPtr)GetWindowExtra(data->wParent); StairsDataPtr sd=(StairsDataPtr)wcd->Private; #if _UNIX CharPtr p; Char Buf[PAR_BUF]; #endif float val; Int2 n; Char buf[PATH_MAX+100],num[20]; Hide(optwin); /* file name */ GetTitle(data->File,buf,PATH_MAX); sd->HardFile=fopen(buf,"wt"); if (!sd->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 (sd->HardFile) { sd->Hardcopy=TRUE; hcSetMode(wcd,sd->HardFile); hcInit(sd); RedrawDiagram(0); hcTerm(sd); sd->Hardcopy=FALSE; fclose(sd->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; StairsDataPtr sd=(StairsDataPtr)wcd->Private; StairsDataPtr csd; /* new copy */ Int2 a; csd=MemNew(sizeof(StairsData)); if (csd) { for (a=0; a<=1; a++) { csd->Axis[a].pMin=StringSave(sd->Axis[a].pMin); csd->Axis[a].pMax=StringSave(sd->Axis[a].pMax); csd->Axis[a].Func.pFunc=StringSave(sd->Axis[a].Func.pFunc); csd->Axis[a].pTick=StringSave(sd->Axis[a].pTick); } MemCopy(csd->Axis[0].Prop,sd->Axis[0].Prop,sizeof(csd->Axis[0].Prop)); MemCopy(&csd->Attr,&sd->Attr,sizeof(FuncAttr)); MemCopy(&csd->Options,&sd->Options,sizeof(csd->Options)); if (DuplicateWindow(wcd,csd)) { /* failure */ WinComData dwcd; dwcd.Private=csd; WriteDescription(&dwcd,NULL); /* free cgd only */ } } } /*----------------------*/ /* Mouse menu callbacks */ #if _WIN #pragma argsused #endif Callback(void) lPickCoord(Int2 index) { WinComDataPtr wcd=GetComDataI; StairsDataPtr sd=(StairsDataPtr)wcd->Private; sd->flags^=MOUSE_PICK; if (!(sd->flags&MOUSE_PICK)) { sd->flags&=~(MOUSE_IMMF); } } #if _WIN #pragma argsused #endif Callback(Boolean) lPickCoord_Status(Int2 index) { WinComDataPtr wcd=GetComDataI; StairsDataPtr sd=(StairsDataPtr)wcd->Private; return (sd->flags&MOUSE_PICK)!=0; } #if _WIN #pragma argsused #endif Callback(void) lImmedFComp(Int2 index) { WinComDataPtr wcd=GetComDataI; StairsDataPtr sd=(StairsDataPtr)wcd->Private; sd->flags^=MOUSE_IMMF; if (sd->flags&MOUSE_IMMF) { sd->flags|=MOUSE_PICK; } } #if _WIN #pragma argsused #endif Callback(Boolean) lImmedFComp_Status(Int2 index) { WinComDataPtr wcd=GetComDataI; StairsDataPtr sd=(StairsDataPtr)wcd->Private; return (sd->flags&MOUSE_IMMF)!=0; } /*----------------*/ /* Help callbacks */ #if _WIN #pragma argsused #endif Callback(void) lHelp(Int2 indx) { Help(HK_1DWIN); } #if _WIN #pragma argsused #endif Callback(void) lHelpSearch(Int2 indx) { HelpSearch(HK_1DWIN); }