MathgeomGLS
1109 строк · 28.1 Кб
1unit fPlot1D;
2(* App crashes; stops responding; when vertical volume intergration calculated
3for x/arccsc(ln(x^4)); xonarccsc(ln(x_4)).yfx file
4also for large movements when logx and logy axes in use *)
5
6interface
7
8uses
9Winapi.Windows,
10Winapi.Messages,
11System.SysUtils,
12System.Variants,
13System.Classes,
14System.UITypes,
15System.Math,
16Vcl.Graphics,
17Vcl.Controls,
18Vcl.Forms,
19Vcl.Dialogs,
20Vcl.ComCtrls,
21Vcl.Menus,
22Vcl.ExtDlgs,
23Vcl.Printers,
24
25GLS.Scene,
26GLS.Coordinates,
27
28GLS.BaseClasses,
29GLS.SceneViewer,
30GLS.BitmapFont,
31GLS.WindowsFont,
32GLS.RenderContextInfo,
33
34uCanvas,
35uGlobal,
36fAbout,
37fFuncts;
38
39type
40TMainForm = class(TForm)
41MainMenu: TMainMenu;
42File1: TMenuItem;
43New: TMenuItem;
44Open: TMenuItem;
45Save: TMenuItem;
46SaveAs: TMenuItem;
47SaveBMPfile1: TMenuItem;
48SaveJPGfile1: TMenuItem;
49N2: TMenuItem;
50Print1: TMenuItem;
51SetupPrinter1: TMenuItem;
52N1: TMenuItem;
53ExitApp: TMenuItem;
54View1: TMenuItem;
55GridOptions1: TMenuItem;
56NumGraphs: TMenuItem;
57Texts1: TMenuItem;
58Style1: TMenuItem;
59SelectStyle1: TMenuItem;
60SaveStyle1: TMenuItem;
61StatusBar: TStatusBar;
62GLViewer: TGLSceneViewer;
63GLScene: TGLScene;
64GLCamera: TGLCamera;
65GLDirectOpenGL: TGLDirectOpenGL;
66GLWinBitFont: TGLWindowsBitmapFont;
67GLMemoryViewer: TGLMemoryViewer;
68PrinterSetupDialog: TPrinterSetupDialog;
69DefaultLayout1: TMenuItem;
70Help1: TMenuItem;
71About1: TMenuItem;
72procedure FormCreate(Sender: TObject);
73procedure FormShow(Sender: TObject);
74procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
75procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
76procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
77procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
78WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
79procedure GLViewerDragOver(Sender, Source: TObject; X, Y: Integer;
80State: TDragState; var Accept: Boolean);
81procedure GLViewerEndDrag(Sender, Target: TObject; X, Y: Integer);
82procedure GLViewerMouseDown(Sender: TObject; Button: TMouseButton;
83Shift: TShiftState; X, Y: Integer);
84procedure GLViewerMouseMove(Sender: TObject; Shift: TShiftState;
85X, Y: Integer);
86procedure GLViewerMouseUp(Sender: TObject; Button: TMouseButton;
87Shift: TShiftState; X, Y: Integer);
88procedure GLDirectOpenGLRender(Sender: TObject;
89var rci: TGLRenderContextInfo);
90procedure NewClick(Sender: TObject);
91procedure OpenClick(Sender: TObject);
92procedure SaveClick(Sender: TObject);
93procedure SaveAsClick(Sender: TObject);
94procedure ExitAppClick(Sender: TObject);
95procedure GridOptions1Click(Sender: TObject);
96procedure Texts1Click(Sender: TObject);
97procedure SaveBMPfile1Click(Sender: TObject);
98procedure SaveJPGfile1Click(Sender: TObject);
99procedure Print1Click(Sender: TObject);
100procedure SetupPrinter1Click(Sender: TObject);
101procedure SelectStyle1Click(Sender: TObject);
102procedure SaveStyle1Click(Sender: TObject);
103procedure GLViewerMouseLeave(Sender: TObject);
104procedure NumGraphsClick(Sender: TObject);
105procedure DefaultLayout1Click(Sender: TObject);
106procedure About1Click(Sender: TObject);
107private
108dMove: integer;
109procedure ShowXYvalues(const x, y: extended);
110procedure UpdateGridXRange;
111procedure UpdateGridYRange;
112procedure DefaultLayout;
113function ValueX(const x: integer): extended;
114function ValueY(const y: integer): extended;
115function ValueLogX(const x: integer): extended;
116function ValueLogY(const y: integer): extended;
117public
118oMousex, oMousey: integer;
119end;
120
121const
122crHandMove = 1;
123crMoveRight = 2;
124crMoveLeft = 3;
125crMoveUp = 4;
126crMoveDown = 5;
127crZoom = 6;
128
129var
130MainForm: TMainForm;
131NewFont: Boolean = True;
132PrinterExists: Boolean;
133
134//=====================================================================
135implementation
136//=====================================================================
137
138{$R *.dfm}
139{$R CURSORS.RES}
140
141uses
142fGridOpts,
143fIntegrateX,
144fIntegrateY,
145fBitmap,
146fStyle,
147fTextBlocks,
148fDerivative,
149fBetween,
150fVolumeX,
151fVolumeY,
152fxValue,
153fx1Value,
154fx2Value,
155fNumeric,
156fPrint;
157
158procedure TMainForm.FormCreate(Sender: TObject);
159
160begin
161BinPath := ExtractFilePath(ParamStr(0));
162BinPath := IncludeTrailingPathDelimiter(BinPath);
163DataPath := BinPath + 'Examples\';
164
165PrinterExists := Printer.Printers.Count > 0;
166StyleFName := BinPath + 'Styles.sty';
167LayoutFName := BinPath + 'Layout.lay';
168
169Screen.Cursors[crHandMove] := LoadCursor(HInstance, 'HANDMOVE');
170Screen.Cursors[crMoveRight] := LoadCursor(HInstance, 'MOVERIGHT');
171Screen.Cursors[crMoveLeft] := LoadCursor(HInstance, 'MOVELEFT');
172Screen.Cursors[crMoveUp] := LoadCursor(HInstance, 'MOVEUP');
173Screen.Cursors[crMoveDown] := LoadCursor(HInstance, 'MOVEDOWN');
174Screen.Cursors[crZoom] := LoadCursor(HInstance, 'ZOOM');
175dMove := $200;
176end;
177
178procedure TMainForm.FormShow(Sender: TObject);
179var
180f: File of TLayout;
181
182begin
183if FileExists(LayoutFName) then
184begin
185try
186AssignFile(f, LayoutFName);
187try
188Reset(f);
189Read(f, Layout);
190finally
191CloseFile(f);
192end;
193
194if Layout.IsMaximize then WindowState := wsMaximized
195else
196begin
197with Layout do
198begin
199Left := MainLeft;
200Top := MainTop;
201Width := MainWidth;
202Height := MainHeight;
203GraphFName := CurrentGraphFName;
204DataPath := CurrentDataPath;
205ImagePath := CurrentImagePath;
206PrinterInfo := CurrentPrinterInfo;
207
208if GridsVisible then GridOptionsForm.Show;
209with GridOptionsForm do
210begin
211MainForm.Left := GridsLeft;
212MainForm.Top := GridsTop;
213end;
214
215if NumericVisible then NumericForm.Show;
216with NumericForm do
217begin
218MainForm.Left := NumericLeft;
219MainForm.Top := NumericTop;
220end;
221
222if TextVisible then TextBlocksForm.Show;
223with TextBlocksForm do
224begin
225MainForm.Left := TextLeft;
226MainForm.Top := TextTop;
227MainForm.Width := TextWidth;
228MainForm.Height := TextHeight;
229end;
230with FunctionsForm do
231begin
232MainForm.Left := FuncLeft;
233MainForm.Top := FuncTop;
234end;
235with DerivativeForm do
236begin
237MainForm.Left := DerivLeft;
238MainForm.Top := DerivTop;
239end;
240with IntegrateXForm do
241begin
242MainForm.Left := IntegXLeft;
243MainForm.Top := IntegXTop;
244end;
245with IntegrateYForm do
246begin
247MainForm.Left := IntegYLeft;
248MainForm.Top := IntegYTop;
249end;
250with BetweenForm do
251begin
252MainForm.Left := BetweenLeft;
253MainForm.Top := BetweenTop;
254end;
255with VolumeXForm do
256begin
257MainForm.Left := VolumeXLeft;
258MainForm.Top := VolumeXTop;
259end;
260with VolumeYForm do
261begin
262MainForm.Left := VolumeYLeft;
263MainForm.Top := VolumeYTop;
264end;
265with fxValueForm do
266begin
267MainForm.Left := fxLeft;
268MainForm.Top := fxTop;
269end;
270with fx1ValueForm do
271begin
272MainForm.Left := fx1Left;
273MainForm.Top := fx1Top;
274end;
275with fx2ValueForm do
276begin
277MainForm.Left := fx2Left;
278MainForm.Top := fx2Top;
279end;
280end;
281end;
282except
283MessageDlg('File Error! An Error has occurred when attempting to read'+
284#13#10'"'+LayoutFName+'".'+
285#13#10'The default layout will be used.',
286mtError, [mbOK], 0);
287DefaultLayout;
288end;
289end
290else DefaultLayout;
291if DataPath = '' then DataPath := BinPath + 'Examples\';
292if ImagePath = '' then ImagePath := BinPath + 'Images\';
293if not DirectoryExists(DataPath) then ForceDirectories(DataPath);
294if not DirectoryExists(ImagePath) then ForceDirectories(ImagePath);
295
296if PrinterExists then
297begin
298SetPrinterInfo(PrinterInfo);
299GetPrinterInfo(PrinterInfo);
300if PrinterInfo.Orientation = poPortrait
301then StatusBar.Panels[1].Text :=
302' '+Printer.Printers[PrinterInfo.Index]+' '+GetPaperType +
303', Portrait.'
304else StatusBar.Panels[1].Text :=
305' '+Printer.Printers[PrinterInfo.Index]+' '+GetPaperType +
306', Landscape.';
307end
308else
309begin
310Print1.Enabled := false; // disabled if no printer
311SetupPrinter1.Enabled := false;
312StatusBar.Panels[1].Text := 'No printer was found.';
313end;
314
315Caption := GraphFName;
316KeepRange := false;
317FunctionsForm.Show;
318Altered := false;
319end;
320
321procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
322var
323f: File of TLayout;
324
325begin
326with Layout do
327begin
328IsMaximize := WindowState = wsMaximized;
329MainLeft := Left;
330MainTop := Top;
331MainWidth := Width;
332MainHeight := Height;
333CurrentGraphFName := GraphFName;
334CurrentDataPath := DataPath;
335CurrentImagePath := ImagePath;
336CurrentPrinterInfo := PrinterInfo;
337GridsVisible := GridOptionsForm.Visible;
338with GridOptionsForm do
339begin
340GridsLeft := Left;
341GridsTop := Top;
342end;
343
344NumericVisible := NumericForm.Visible;
345with NumericForm do
346begin
347NumericLeft := Left;
348NumericTop := Top;
349end;
350
351with NumericForm do if Visible then
352begin
353if (DataListBox.Count = 0) and (CheckListBox.Count > 0)
354then DeleteButtonClick(Sender);
355FunctionsForm.CoordPointButton.Visible := False;
356end;
357
358TextVisible := TextBlocksForm.Visible;
359with TextBlocksForm do
360begin
361TextLeft := Left;
362TextTop := Top;
363TextWidth := Width;
364TextHeight := Height;
365end;
366with FunctionsForm do
367begin
368FuncLeft := Left;
369FuncTop := Top;
370end;
371with DerivativeForm do
372begin
373DerivLeft := Left;
374DerivTop := Top;
375end;
376with IntegrateXForm do
377begin
378IntegXLeft := Left;
379IntegXTop := Top;
380end;
381with IntegrateYForm do
382begin
383IntegYLeft := Left;
384IntegYTop := Top;
385end;
386with BetweenForm do
387begin
388BetweenLeft := Left;
389BetweenTop := Top;
390end;
391with VolumeXForm do
392begin
393VolumeXLeft := Left;
394VolumeXTop := Top;
395end;
396with VolumeYForm do
397begin
398VolumeYLeft := Left;
399VolumeYTop := Top;
400end;
401with fxValueForm do
402begin
403fxLeft := Left;
404fxTop := Top;
405end;
406with fx1ValueForm do
407begin
408fx1Left := Left;
409fx1Top := Top;
410end;
411with fx2ValueForm do
412begin
413fx2Left := Left;
414fx2Top := Top;
415end;
416end;
417
418try
419AssignFile(f, LayoutFName);
420try
421Rewrite(f);
422write(f, Layout);
423finally
424CloseFile(f);
425end;
426except
427MessageDlg('File Error! An Error has occurred'+
428#13#10'when attempting to write to "'+LayoutFName+'".',
429mtError, [mbOK], 0);
430end;
431
432if Altered then
433begin
434case MessageDlg('The current graph data has been altered.'+
435#13#10'Do you wish to save the alterations ?', mtConfirmation,
436[mbYes, mbNo, mbCancel], 0) of
437mrYes: FunctionsForm.SaveClick(Sender);
438mrCancel: begin
439CanClose := false;
440Exit;
441end;
442end;
443end;
444end;
445
446procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
447Shift: TShiftState);
448var
449x, y, r: extended;
450
451begin
452with GraphData.Grid do
453if (xAxisStyle = asLog) or (yAxisStyle = asLog) then exit;
454case Key of
455//VK_F2:ShowAbout;
456VK_ESCAPE:
457if (MessageDlg('Do you wish to close the applicsation?',
458mtConfirmation, [mbYes, mbNo], 0) = mrYes)
459then ExitAppClick(Sender);
460VK_LEFT, VK_NUMPAD4:
461begin
462Screen.Cursor := crMoveLeft;
463with GraphData do
464begin
465x := (xMax - xMin)/dMove;
466xMin := xMin + x;
467xMax := xMax + x;
468end;
469UpdateGridXRange;
470Altered := true;
471if dMove > 1 then dec(dMove, dMove div 16);
472GLViewer.Invalidate;
473Key := 0;
474end;
475VK_RIGHT, VK_NUMPAD6:
476begin
477Screen.Cursor := crMoveRight;
478with GraphData do
479begin
480x := (xMax - xMin)/dMove;
481xMin := xMin - x;
482xMax := xMax - x;
483end;
484UpdateGridXRange;
485Altered := true;
486if dMove > 1 then dec(dMove, dMove div 16);
487GLViewer.Invalidate;
488Key := 0;
489end;
490VK_UP, VK_NUMPAD8:
491begin
492Screen.Cursor := crMoveUp;
493with GraphData do
494begin
495y := (yMax - yMin)/dMove;
496yMin := yMin - y;
497yMax := yMax - y;
498end;
499UpdateGridYRange;
500Altered := true;
501if dMove > 1 then dec(dMove, dMove div 16);
502GLViewer.Invalidate;
503Key := 0;
504end;
505VK_DOWN, VK_NUMPAD2:
506begin
507Screen.Cursor := crMoveDown;
508with GraphData do
509begin
510y := (yMax - yMin)/dMove;
511yMin := yMin + y;
512yMax := yMax + y;
513end;
514UpdateGridYRange;
515Altered := true;
516if dMove > 1 then dec(dMove, dMove div 16);
517GLViewer.Invalidate;
518Key := 0;
519end;
520VK_ADD: // zoom in
521begin
522Screen.Cursor := crZoom;
523with GraphData do
524begin
525x := (xMax - xMin)/dMove;
526xMin := xMin + x;
527xMax := xMax - x;
528
529y := (yMax - yMin)/dMove;
530yMin := yMin + y;
531yMax := yMax - y;
532end;
533UpdateGridXRange;
534UpdateGridYRange;
535Altered := true;
536if dMove > 1 then dec(dMove, dMove div 16);
537GLViewer.Invalidate;
538Key := 0;
539end;
540VK_SUBTRACT: // zoom out
541begin
542Screen.Cursor := crZoom;
543x := (GraphData.xMax - GraphData.xMin)/dMove;
544GraphData.xMin := GraphData.xMin - x;
545GraphData.xMax := GraphData.xMax + x;
546
547y := (GraphData.yMax - GraphData.yMin)/dMove;
548GraphData.yMin := GraphData.yMin - y;
549GraphData.yMax := GraphData.yMax + y;
550UpdateGridXRange;
551UpdateGridYRange;
552Altered := true;
553if dMove > 1 then dec(dMove, dMove div 16);
554GLViewer.Invalidate;
555Key := 0;
556end;
557VK_HOME, VK_NUMPAD7:
558begin
559x := (GraphData.xMax - GraphData.xMin)/2;
560GraphData.xMin := -x;
561GraphData.xMax := x;
562y := (GraphData.yMax - GraphData.yMin)/2;
563GraphData.yMin := -y;
564GraphData.yMax := y;
565UpdateGridXRange;
566UpdateGridYRange;
567Altered := true;
568GLViewer.Invalidate;
569Key := 0;
570end;
57112, VK_NUMPAD5: // eual grid
572begin
573with GraphData do
574begin
575x := xMax - xMin;
576y := yMax - yMin;
577r := (x*MainForm.GLViewer.Height)/(y*Mainform.GLViewer.Width);
578
579if x > y then
580begin
581if Shift = [ssCtrl] then
582begin
583xMax := yMax;
584xMin := yMin;
585end
586else
587begin
588yMax := yMax*r;
589yMin := yMin*r;
590end;
591end
592else
593begin
594if Shift = [ssCtrl] then
595begin
596yMax := xMax;
597yMin := xMin;
598end
599else
600begin
601xMax := xMax/r;
602xMin := xMin/r;
603end;
604end;
605end;
606UpdateGridXRange;
607UpdateGridYRange;
608Altered := true;
609GLViewer.Invalidate;
610Key := 0;
611end;
612end;
613end;
614
615procedure TMainForm.FormKeyUp(Sender: TObject; var Key: Word;
616Shift: TShiftState);
617begin
618Screen.Cursor := crDefault;
619dMove := $200;
620end;
621
622procedure TMainForm.FormMouseWheel(Sender: TObject; Shift: TShiftState;
623WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
624var
625d: integer;
626x, y: extended;
627
628begin
629with GraphData.Grid do
630if (xAxisStyle = asLog) or (yAxisStyle = asLog) then exit;
631// WheelDelta is negative when wheel is rotated toward user, i.e. Zoom in.
632d := -WheelDelta div 2;
633if Shift = [ssShift] then d := d div 4
634else if Shift = [ssCtrl] then d := d div 2;
635
636with GraphData do
637begin
638x := (xMax - xMin)/d;
639xMin := xMin + x;
640xMax := xMax - x;
641
642y := (yMax - yMin)/d;
643yMin := yMin + y;
644yMax := yMax - y;
645end;
646UpdateGridXRange;
647UpdateGridYRange;
648Altered := true;
649GLViewer.Invalidate;
650end;
651
652procedure TMainForm.GLViewerDragOver(Sender, Source: TObject; X, Y: Integer;
653State: TDragState; var Accept: Boolean);
654begin
655Accept := Source = Sender;
656if Accept then with GraphData, PlotData do
657begin
658with Grid do
659begin
660if xAxisStyle = asLog
661then xLabel := ValueLogX(X)
662else xLabel := ValueX(X);
663
664if yAxisStyle = asLog
665then yLabel := ValueLogY(Y)
666else yLabel := ValueY(Y);
667end;
668
669FunctionsForm.EditLocX.Text := FloatToStrF(xLabel, ffNumber, 4, 3);
670FunctionsForm.EditLocY.Text := FloatToStrF(yLabel, ffNumber, 4, 3);
671ShowXYvalues(xLabel, yLabel);
672end;
673end;
674
675procedure TMainForm.GLViewerEndDrag(Sender, Target: TObject; X, Y: Integer);
676begin
677if Target = Sender then // end of drag
678with FunctionsForm.CheckListBox,
679TPlotDataObject(Items.Objects[ItemIndex]).Data do
680begin
681with GraphData.Grid do
682begin
683if xAxisStyle = asLog
684then xLabel := ValueLogX(X)
685else xLabel := ValueX(X);
686
687if yAxisStyle = asLog
688then yLabel := ValueLogY(Y)
689else yLabel := ValueY(Y);
690end;
691
692Altered := true;
693GLViewer.Invalidate;
694end;
695end;
696
697procedure TMainForm.GLViewerMouseDown(Sender: TObject; Button: TMouseButton;
698Shift: TShiftState; X, Y: Integer);
699var
700dx, dy: extended;
701
702begin
703if Shift = [ssLeft] then // drag only if left button pressed
704with Sender as TGLSceneViewer do // treat Sender as TGLSceneViewer
705begin
706if (X >= LabelRect.Left ) and (X <= LabelRect.Right) and
707(Y >= LabelRect.Top) and (Y <= LabelRect.Bottom)
708then BeginDrag(false) else Screen.Cursor := crHandMove;
709end
710else if (GraphData.Grid.xAxisStyle <> asLog) and
711(GraphData.Grid.yAxisStyle <> asLog) and
712(Shift = [ssLeft, ssAlt]) then
713begin // reposition graph; set mouse location as graph center
714with GraphData do
715begin
716dx := (xMin + xMax)/2 - ValueX(X);
717dy := (yMin + yMax)/2 - ValueY(Y);
718xMin := xMin - dx;
719xMax := xMax - dx;
720yMin := yMin - dy;
721yMax := yMax - dy;
722end;
723UpdateGridXRange;
724UpdateGridYRange;
725Altered := true;
726GLViewer.Invalidate;
727end;
728end;
729
730procedure TMainForm.GLViewerMouseLeave(Sender: TObject);
731begin
732oMousex := -1;
733end;
734
735procedure TMainForm.GLViewerMouseMove(Sender: TObject; Shift: TShiftState;
736X, Y: Integer);
737
738procedure IsAltered;
739begin
740UpdateGridXRange;
741UpdateGridYRange;
742Altered := true;
743GLViewer.Invalidate;
744end;
745
746var
747xValue, yValue: extended;
748
749begin
750xValue := 0;
751yValue := 0;
752
753if Active and (oMousex > -1) then
754begin
755if Shift = [ssLeft] then
756begin
757with GraphData do
758begin
759if Grid.xAxisStyle = asLog then
760begin // ratio of change to current value of x
761xValue := (ValueLogX(X) - ValueLogX(oMousex))/ValueLogX(X);
762xMin := xMin - xMin*xValue;
763xMax := xMax - xMax*xValue;
764end
765else
766begin
767xValue := ValueX(X) - ValueX(oMousex);
768xMax := xMax - xValue;
769xMin := xMin - xValue;
770end;
771
772if Grid.yAxisStyle = asLog then
773begin // ratio of change to current value of y
774yValue := (ValueLogY(Y) - ValueLogY(oMousey))/ValueLogY(Y);
775yMin := yMin - yMin*yValue;
776yMax := yMax - yMax*yValue;
777end
778else
779begin
780yValue := ValueY(Y) - ValueY(oMousey);
781yMax := yMax - yValue;
782yMin := yMin - yValue;
783end;
784end;
785IsAltered;
786end
787else
788if Shift = [ssLeft, ssCtrl] then
789begin
790Screen.Cursor := crSizeAll;
791
792if GraphData.Grid.xAxisStyle = asLog then
793begin
794xValue := (ValueLogX(X) - ValueLogX(oMousex))/ValueLogX(X);
795GraphData.xMin := GraphData.xMin + GraphData.xMin*xValue;
796GraphData.xMax := GraphData.xMax - GraphData.xMax*xValue;
797end
798else
799begin
800xValue := ValueX(X) - ValueX(oMousex);
801GraphData.xMin := GraphData.xMin + xValue;
802GraphData.xMax := GraphData.xMax - xValue;
803end;
804
805if GraphData.Grid.yAxisStyle = asLog then
806begin
807yValue := (ValueLogY(Y) - ValueLogY(oMousey))/ValueLogY(Y);
808GraphData.yMin := GraphData.yMin + GraphData.yMin*yValue;
809GraphData.yMax := GraphData.yMax - GraphData.yMax*yValue;
810end
811else
812begin
813yValue := ValueY(Y) - ValueY(oMousey);
814GraphData.yMin := GraphData.yMin + yValue;
815GraphData.yMax := GraphData.yMax - yValue;
816end;
817
818IsAltered;
819end;
820
821if GraphData.Grid.xAxisStyle = asLog then
822xValue := ValueLogX(X)
823else
824xValue := ValueX(X);
825
826if GraphData.Grid.yAxisStyle = asLog then
827yValue := ValueLogY(Y)
828else
829yValue := ValueY(Y);
830end;
831
832oMousex := X;
833oMousey := Y;
834
835ShowXYvalues(xValue, yValue);
836end;
837
838procedure TMainForm.GLViewerMouseUp(Sender: TObject; Button: TMouseButton;
839Shift: TShiftState; X, Y: Integer);
840begin
841Screen.Cursor := crDefault;
842end;
843
844procedure TMainForm.NewClick(Sender: TObject);
845begin
846FunctionsForm.NewClick(Sender);
847end;
848
849procedure TMainForm.OpenClick(Sender: TObject);
850begin
851FunctionsForm.OpenClick(Sender);
852end;
853
854procedure TMainForm.SaveClick(Sender: TObject);
855begin
856FunctionsForm.SaveClick(Sender);
857end;
858
859procedure TMainForm.SaveAsClick(Sender: TObject);
860begin
861FunctionsForm.SaveAsClick(Sender);
862end;
863
864procedure TMainForm.SaveBMPfile1Click(Sender: TObject);
865begin
866BitmapForm := TBitmapForm.Create(Application);
867if FunctionsForm.CheckListBox.Count > 1 then
868BitmapForm.Caption := ' Save graphs as ''' +
869ChangeFileExt(GraphFName, '.bmp''')
870else
871BitmapForm.Caption := ' Save graph as ''' +
872ChangeFileExt(GraphFName, '.bmp''');
873BitmapForm.ShowModal;
874BitmapForm.Free;
875BitmapForm := nil;
876end;
877
878procedure TMainForm.SaveJPGfile1Click(Sender: TObject);
879begin
880BitmapForm := TBitmapForm.Create(Application);
881if FunctionsForm.CheckListBox.Count > 1 then
882BitmapForm.Caption := ' Save graphs as ''' +
883ChangeFileExt(GraphFName, '.jpg''')
884else
885BitmapForm.Caption := ' Save graph as ''' +
886ChangeFileExt(GraphFName, '.jpg''');
887BitmapForm.ShowModal;
888BitmapForm.Free;
889BitmapForm := nil;
890end;
891
892procedure TMainForm.Print1Click(Sender: TObject);
893begin
894PrintForm := TPrintForm.Create(Application);
895PrintForm.Caption := ' Print '''+ GraphFName+'''.';
896PrintForm.ShowModal;
897PrintForm.Free;
898PrintForm := nil;
899end;
900
901procedure TMainForm.SetupPrinter1Click(Sender: TObject);
902begin
903if PrinterSetupDialog.Execute then
904begin
905GetPrinterInfo(PrinterInfo);
906if PrinterInfo.Orientation = poPortrait
907then StatusBar.Panels[1].Text :=
908' '+Printer.Printers[PrinterInfo.Index]+' '+GetPaperType +
909', Portrait.'
910else StatusBar.Panels[1].Text :=
911' '+Printer.Printers[PrinterInfo.Index]+' '+GetPaperType +
912', Landscape.';
913end;
914end;
915
916procedure TMainForm.DefaultLayout1Click(Sender: TObject);
917begin
918DefaultLayout;
919end;
920
921procedure TMainForm.ExitAppClick(Sender: TObject);
922begin
923Close;
924end;
925
926procedure TMainForm.GridOptions1Click(Sender: TObject);
927begin
928if not GridOptionsForm.Visible then
929GridOptionsForm.Show;
930end;
931
932procedure TMainForm.NumGraphsClick(Sender: TObject);
933begin
934if not NumericForm.Visible then
935begin
936NumericForm.Show;
937NumericForm.CheckListBoxClick(Sender); // updates NumericForm.DataListBox
938end;
939end;
940
941procedure TMainForm.Texts1Click(Sender: TObject);
942begin
943if not TextBlocksForm.Visible then
944TextBlocksForm.Show;
945end;
946
947procedure TMainForm.SelectStyle1Click(Sender: TObject);
948begin
949StyleNameForm := TStyleNameForm.Create(Application);
950StyleNameForm.Selecting := true;
951StyleNameForm.ShowModal;
952StyleNameForm.Free;
953StyleNameForm := nil;
954Altered := true;
955(*
956NewFont needed to initialize GLWinFont.GetCharWidth
957if the font has been altered, which may or may not be the case,
958so do it anyway
959*)
960NewFont := true;
961GLViewer.Invalidate;
962end;
963
964procedure TMainForm.SaveStyle1Click(Sender: TObject);
965begin
966StyleNameForm := TStyleNameForm.Create(Application);
967StyleNameForm.Selecting := false;
968StyleNameForm.ShowModal;
969StyleNameForm.Free;
970StyleNameForm := nil;
971end;
972
973procedure TMainForm.GLDirectOpenGLRender(Sender: TObject;
974var rci: TGLRenderContextInfo);
975var
976fxCanvas: TfxCanvas;
977
978begin
979fxCanvas := TfxCanvas.Create(GLViewer.Width, GLViewer.Height);
980try
981if NewFont then
982begin
983fxCanvas.SetGLWinBitFont(rci, GLWinBitFont, GraphData.FontName,
984GraphData.FontSize, GraphData.FontStyle);
985fxCanvas.SetupFont(rci, GLWinBitFont);
986NewFont := false;
987end;
988
989with fxCanvas do
990begin
991xAxisGradsCalc(GLWinBitFont); // calculates graduations
992yAxisGradsCalc(GLWinBitFont);
993
994if GraphData.Grid.GridStyle > gsNone
995then DrawAxes;
996
997AddFunctionLabelsText; // add the labels to text list
998DrawTextList(rci, TextList, GLWinBitFont); // axes and labels text
999DrawFunctions;
1000DrawNumericData;
1001DrawTextBlocks(rci, GLWinBitFont);
1002end;
1003finally
1004fxCanvas.Free;
1005end;
1006end;
1007
1008procedure TMainForm.ShowXYvalues(const x, y: extended);
1009var
1010sx, sy: string;
1011
1012begin
1013sx := FloatToStrF(x, ffnumber, 16, 8);
1014sy := FloatToStrF(y, ffnumber, 16, 8);
1015StatusBar.Panels[0].Text := ' x : '+sx+', y : '+sy;
1016end;
1017
1018procedure TMainForm.UpdateGridXRange;
1019begin
1020with GridOptionsForm do
1021if Visible then
1022begin
1023EditMinX.Text := FloatToStrF(GraphData.xMin, ffGeneral, 13, 4);
1024EditMaxX.Text := FloatToStrF(GraphData.xMax, ffGeneral, 13, 4);
1025end;
1026end;
1027
1028procedure TMainForm.About1Click(Sender: TObject);
1029begin
1030FormAbout.Show
1031(*
1032with TAboutForm.Create();
1033try
1034ShowModal;
1035finally
1036Free;
1037end;
1038*)
1039end;
1040
1041procedure TMainForm.DefaultLayout;
1042begin
1043MainForm.Left := 1;
1044MainForm.Top := 1;
1045MainForm.Width := Screen.Width - GridOptionsForm.Width - 10;
1046MainForm.Height := Screen.Height - 30;
1047FunctionsForm.Left := MainForm.Left + MainForm.Width + 5;
1048FunctionsForm.Top := MainForm.Top + 5;
1049GridOptionsForm.Left := FunctionsForm.Left;
1050GridOptionsForm.Top := FunctionsForm.Top + FunctionsForm.Height + 10;
1051GridOptionsForm.Show;
1052NumericForm.Top := 25;
1053NumericForm.Left := 25;
1054TextBlocksForm.Top := 75;
1055TextBlocksForm.Left := 75;
1056end;
1057
1058procedure TMainForm.UpdateGridYRange;
1059begin
1060with GridOptionsForm do
1061if Visible then
1062begin
1063EditMinY.Text := FloatToStrF(GraphData.yMin, ffGeneral, 13, 4);
1064EditMaxY.Text := FloatToStrF(GraphData.yMax, ffGeneral, 13, 4);
1065end;
1066end;
1067
1068function TMainForm.ValueX(const x: integer): extended;
1069begin
1070Result := GraphData.xMin + X * (GraphData.xMax - GraphData.xMin) / GLViewer.Width;
1071end;
1072
1073function TMainForm.ValueY(const y: integer): extended;
1074begin
1075Result := GraphData.yMax + Y * (GraphData.yMin - GraphData.yMax) / GLViewer.Height;
1076end;
1077
1078function TMainForm.ValueLogX(const x: integer): extended;
1079var
1080LogMin, a: extended;
1081
1082begin
1083LogMin := Log10(GraphData.xMin);
1084a := LogMin + x*(Log10(GraphData.xMax) - LogMin)/GLViewer.Width;
1085Result := Power(10, a);
1086end;
1087
1088function TMainForm.ValueLogY(const y: integer): extended;
1089var
1090LogMax, a: extended;
1091
1092begin
1093LogMax := Log10(GraphData.yMax);
1094a := LogMax + y*(Log10(GraphData.yMin) - LogMax)/GLViewer.Height;
1095Result := Power(10, a);
1096end;
1097
1098//------------------------------------------------------------------
1099initialization
1100//------------------------------------------------------------------
1101FormatSettings.DecimalSeparator := '.';
1102
1103//------------------------------------------------------------------
1104finalization
1105//------------------------------------------------------------------
1106// return to FormatSettings.DecimalSeparator := ',';
1107
1108
1109end.
1110