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