MathgeomGLS

Форк
0
1133 строки · 28.3 Кб
1
unit faGraf1d;
2
(* App crashes; stops responding; when vertical volume intergration calculated
3
  for x/arccsc(ln(x^4)); xonarccsc(ln(x_4)).yfx file
4
  also for large movements when logx and logy axes in use *)
5

6
interface
7

8
uses
9
  Winapi.Windows,
10
  Winapi.Messages,
11
  System.SysUtils,
12
  System.Variants,
13
  System.Classes,
14
  System.UITypes,
15
  System.Math,
16
  Vcl.Graphics,
17
  Vcl.Controls,
18
  Vcl.Forms,
19
  Vcl.Dialogs,
20
  Vcl.ComCtrls,
21
  Vcl.Menus,
22
  Vcl.ExtDlgs,
23
  Vcl.Printers,
24

25
  GLS.Scene,
26
  GLS.Coordinates,
27

28
  GLS.BaseClasses,
29
  GLS.SceneViewer,
30
  GLS.BitmapFont,
31
  GLS.WindowsFont,
32
  GLS.RenderContextInfo,
33

34
  fAbout,
35
  Graf.Canvas1d,
36
  Graf.Global1d,
37
  faFunc1d;
38

39
type
40
  TMainForm = class(TForm)
41
    MainMenu: TMainMenu;
42
    File1: TMenuItem;
43
    New: TMenuItem;
44
    Open: TMenuItem;
45
    Save: TMenuItem;
46
    SaveAs: TMenuItem;
47
    SaveBMPfile1: TMenuItem;
48
    SaveJPGfile1: TMenuItem;
49
    N2: TMenuItem;
50
    Print1: TMenuItem;
51
    SetupPrinter1: TMenuItem;
52
    N1: TMenuItem;
53
    ExitApp: TMenuItem;
54
    View1: TMenuItem;
55
    GridOptions1: TMenuItem;
56
    NumGraphs: TMenuItem;
57
    Texts1: TMenuItem;
58
    Style1: TMenuItem;
59
    SelectStyle1: TMenuItem;
60
    SaveStyle1: TMenuItem;
61
    StatusBar: TStatusBar;
62
    GLViewer: TGLSceneViewer;
63
    GLScene: TGLScene;
64
    GLCamera: TGLCamera;
65
    GLDirectOpenGL: TGLDirectOpenGL;
66
    GLWinBitFont: TGLWindowsBitmapFont;
67
    GLMemoryViewer: TGLMemoryViewer;
68
    PrinterSetupDialog: TPrinterSetupDialog;
69
    DefaultLayout1: TMenuItem;
70
    Help1: TMenuItem;
71
    About1: TMenuItem;
72
    miRuwiki: TMenuItem;
73
    procedure FormCreate(Sender: TObject);
74
    procedure FormShow(Sender: TObject);
75
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
76
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
77
    procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
78
    procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
79
      WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
80
    procedure GLViewerDragOver(Sender, Source: TObject; X, Y: Integer;
81
      State: TDragState; var Accept: Boolean);
82
    procedure GLViewerEndDrag(Sender, Target: TObject; X, Y: Integer);
83
    procedure GLViewerMouseDown(Sender: TObject; Button: TMouseButton;
84
      Shift: TShiftState; X, Y: Integer);
85
    procedure GLViewerMouseMove(Sender: TObject; Shift: TShiftState;
86
      X, Y: Integer);
87
    procedure GLViewerMouseUp(Sender: TObject; Button: TMouseButton;
88
      Shift: TShiftState; X, Y: Integer);
89
    procedure GLDirectOpenGLRender(Sender: TObject;
90
      var rci: TGLRenderContextInfo);
91
    procedure NewClick(Sender: TObject);
92
    procedure OpenClick(Sender: TObject);
93
    procedure SaveClick(Sender: TObject);
94
    procedure SaveAsClick(Sender: TObject);
95
    procedure ExitAppClick(Sender: TObject);
96
    procedure GridOptions1Click(Sender: TObject);
97
    procedure Texts1Click(Sender: TObject);
98
    procedure SaveBMPfile1Click(Sender: TObject);
99
    procedure SaveJPGfile1Click(Sender: TObject);
100
    procedure Print1Click(Sender: TObject);
101
    procedure SetupPrinter1Click(Sender: TObject);
102
    procedure SelectStyle1Click(Sender: TObject);
103
    procedure SaveStyle1Click(Sender: TObject);
104
    procedure GLViewerMouseLeave(Sender: TObject);
105
    procedure NumGraphsClick(Sender: TObject);
106
    procedure DefaultLayout1Click(Sender: TObject);
107
    procedure About1Click(Sender: TObject);
108
  private
109
    dMove: Integer;
110
    procedure ShowXYvalues(const X, Y: extended);
111
    procedure UpdateGridXRange;
112
    procedure UpdateGridYRange;
113
    procedure DefaultLayout;
114
    function ValueX(const X: Integer): extended;
115
    function ValueY(const Y: Integer): extended;
116
    function ValueLogX(const X: Integer): extended;
117
    function ValueLogY(const Y: Integer): extended;
118
  public
119
    oMousex, oMousey: Integer;
120
  end;
121

122
const
123
  crHandMove = 1;
124
  crMoveRight = 2;
125
  crMoveLeft = 3;
126
  crMoveUp = 4;
127
  crMoveDown = 5;
128
  crZoom = 6;
129

130
var
131
  MainForm: TMainForm;
132
  NewFont: Boolean = True;
133
  PrinterExists: Boolean;
134

135
// =====================================================================
136
implementation
137
// =====================================================================
138

139
{$R *.dfm}
140

141
uses
142
  faGridOpt1d,
143
  faIntegrateX,
144
  faIntegrateY,
145
  faBitmap,
146
  faStyle,
147
  faTextBlocks,
148
  faDerivative,
149
  faBetween,
150
  faVolumeX,
151
  faVolumeY,
152
  faValueX,
153
  faValueX1,
154
  faValueX2,
155
  faNumeric,
156
  faPrint;
157

158
procedure TMainForm.FormCreate(Sender: TObject);
159
begin
160
  BinPath := ExtractFilePath(ParamStr(0));
161
  BinPath := IncludeTrailingPathDelimiter(BinPath);
162

163
  DataPath := BinPath + 'data\plot1d\';
164
  SetCurrentDir(DataPath);
165
  ImagePath := BinPath + 'data\image\';
166

167
  PrinterExists := Printer.Printers.Count > 0;
168
  StyleFName := BinPath + 'Style1d.sty';
169
  LayoutFName := BinPath + 'Layout1d.lay';
170

171
  Screen.Cursors[crHandMove] := LoadCursor(HInstance, 'HANDMOVE');
172
  Screen.Cursors[crMoveRight] := LoadCursor(HInstance, 'MOVERIGHT');
173
  Screen.Cursors[crMoveLeft] := LoadCursor(HInstance, 'MOVELEFT');
174
  Screen.Cursors[crMoveUp] := LoadCursor(HInstance, 'MOVEUP');
175
  Screen.Cursors[crMoveDown] := LoadCursor(HInstance, 'MOVEDOWN');
176
  Screen.Cursors[crZoom] := LoadCursor(HInstance, 'ZOOM');
177
  dMove := $200;
178
end;
179

180
procedure TMainForm.FormShow(Sender: TObject);
181
var
182
  f: File of TLayout;
183

184
begin
185
  if FileExists(LayoutFName) then
186
  begin
187
    try
188
      AssignFile(f, LayoutFName);
189
      try
190
        Reset(f);
191
        Read(f, Layout);
192
      finally
193
        CloseFile(f);
194
      end;
195

196
      if Layout.IsMaximize then
197
        WindowState := wsMaximized
198
      else
199
      begin
200
        with Layout do
201
        begin
202
          Left := MainLeft;
203
          Top := MainTop;
204
          Width := MainWidth;
205
          Height := MainHeight;
206
          GraphFName := CurrentGraphFName;
207
          DataPath := CurrentDataPath;
208
          ImagePath := CurrentImagePath;
209
          PrinterInfo := CurrentPrinterInfo;
210

211
          if GridsVisible then
212
            GridOptionsForm.Show;
213
          with GridOptionsForm do
214
          begin
215
            MainForm.Left := GridsLeft;
216
            MainForm.Top := GridsTop;
217
          end;
218

219
          if NumericVisible then
220
            NumericForm.Show;
221
          with NumericForm do
222
          begin
223
            MainForm.Left := NumericLeft;
224
            MainForm.Top := NumericTop;
225
          end;
226

227
          if TextVisible then
228
            TextBlocksForm.Show;
229
          with TextBlocksForm do
230
          begin
231
            MainForm.Left := TextLeft;
232
            MainForm.Top := TextTop;
233
            MainForm.Width := TextWidth;
234
            MainForm.Height := TextHeight;
235
          end;
236
          with FunctionsForm do
237
          begin
238
            MainForm.Left := FuncLeft;
239
            MainForm.Top := FuncTop;
240
          end;
241
          with DerivativeForm do
242
          begin
243
            MainForm.Left := DerivLeft;
244
            MainForm.Top := DerivTop;
245
          end;
246
          with IntegrateXForm do
247
          begin
248
            MainForm.Left := IntegXLeft;
249
            MainForm.Top := IntegXTop;
250
          end;
251
          with IntegrateYForm do
252
          begin
253
            MainForm.Left := IntegYLeft;
254
            MainForm.Top := IntegYTop;
255
          end;
256
          with BetweenForm do
257
          begin
258
            MainForm.Left := BetweenLeft;
259
            MainForm.Top := BetweenTop;
260
          end;
261
          with VolumeXForm do
262
          begin
263
            MainForm.Left := VolumeXLeft;
264
            MainForm.Top := VolumeXTop;
265
          end;
266
          with VolumeYForm do
267
          begin
268
            MainForm.Left := VolumeYLeft;
269
            MainForm.Top := VolumeYTop;
270
          end;
271
          with fxValueForm do
272
          begin
273
            MainForm.Left := fxLeft;
274
            MainForm.Top := fxTop;
275
          end;
276
          with fx1ValueForm do
277
          begin
278
            MainForm.Left := fx1Left;
279
            MainForm.Top := fx1Top;
280
          end;
281
          with fx2ValueForm do
282
          begin
283
            MainForm.Left := fx2Left;
284
            MainForm.Top := fx2Top;
285
          end;
286
        end;
287
      end;
288
    except
289
      MessageDlg('������ ������ �����!' + #13#10'"' + LayoutFName + '".' +
290
        #13#10'����� �������������� �������� ���������', mtError, [mbOK], 0);
291
      DefaultLayout;
292
    end;
293
  end
294
  else
295
    DefaultLayout;
296
  if DataPath = '' then
297
    DataPath := BinPath + 'data\plot1d\';
298
  if ImagePath = '' then
299
    ImagePath := BinPath + 'data\image\';
300
  if not DirectoryExists(DataPath) then
301
    ForceDirectories(DataPath);
302
  if not DirectoryExists(ImagePath) then
303
    ForceDirectories(ImagePath);
304

305
  if PrinterExists then
306
  begin
307
    SetPrinterInfo(PrinterInfo);
308
    GetPrinterInfo(PrinterInfo);
309
    if PrinterInfo.Orientation = poPortrait then
310
      StatusBar.Panels[1].Text := '  ' + Printer.Printers[PrinterInfo.Index] +
311
        '  ' + GetPaperType + ', �������'
312
    else
313
      StatusBar.Panels[1].Text := '  ' + Printer.Printers[PrinterInfo.Index] +
314
        '  ' + GetPaperType + ', ���������';
315
  end
316
  else
317
  begin
318
    Print1.Enabled := false; // disabled if no printer
319
    SetupPrinter1.Enabled := false;
320
    StatusBar.Panels[1].Text := '������� �� ������';
321
  end;
322

323
  Caption := GraphFName;
324
  KeepRange := false;
325
  FunctionsForm.Show;
326
  Altered := false;
327
end;
328

329
procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
330
var
331
  f: File of TLayout;
332

333
begin
334
  with Layout do
335
  begin
336
    IsMaximize := WindowState = wsMaximized;
337
    MainLeft := Left;
338
    MainTop := Top;
339
    MainWidth := Width;
340
    MainHeight := Height;
341
    CurrentGraphFName := GraphFName;
342
    CurrentDataPath := DataPath;
343
    CurrentImagePath := ImagePath;
344
    CurrentPrinterInfo := PrinterInfo;
345
    GridsVisible := GridOptionsForm.Visible;
346
    with GridOptionsForm do
347
    begin
348
      GridsLeft := Left;
349
      GridsTop := Top;
350
    end;
351

352
    NumericVisible := NumericForm.Visible;
353
    with NumericForm do
354
    begin
355
      NumericLeft := Left;
356
      NumericTop := Top;
357
    end;
358

359
    with NumericForm do
360
      if Visible then
361
      begin
362
        if (DataListBox.Count = 0) and (CheckListBox.Count > 0) then
363
          DeleteButtonClick(Sender);
364
        FunctionsForm.CoordPointButton.Visible := false;
365
      end;
366

367
    TextVisible := TextBlocksForm.Visible;
368
    with TextBlocksForm do
369
    begin
370
      TextLeft := Left;
371
      TextTop := Top;
372
      TextWidth := Width;
373
      TextHeight := Height;
374
    end;
375
    with FunctionsForm do
376
    begin
377
      FuncLeft := Left;
378
      FuncTop := Top;
379
    end;
380
    with DerivativeForm do
381
    begin
382
      DerivLeft := Left;
383
      DerivTop := Top;
384
    end;
385
    with IntegrateXForm do
386
    begin
387
      IntegXLeft := Left;
388
      IntegXTop := Top;
389
    end;
390
    with IntegrateYForm do
391
    begin
392
      IntegYLeft := Left;
393
      IntegYTop := Top;
394
    end;
395
    with BetweenForm do
396
    begin
397
      BetweenLeft := Left;
398
      BetweenTop := Top;
399
    end;
400
    with VolumeXForm do
401
    begin
402
      VolumeXLeft := Left;
403
      VolumeXTop := Top;
404
    end;
405
    with VolumeYForm do
406
    begin
407
      VolumeYLeft := Left;
408
      VolumeYTop := Top;
409
    end;
410
    with fxValueForm do
411
    begin
412
      fxLeft := Left;
413
      fxTop := Top;
414
    end;
415
    with fx1ValueForm do
416
    begin
417
      fx1Left := Left;
418
      fx1Top := Top;
419
    end;
420
    with fx2ValueForm do
421
    begin
422
      fx2Left := Left;
423
      fx2Top := Top;
424
    end;
425
  end;
426

427
  try
428
    AssignFile(f, LayoutFName);
429
    try
430
      Rewrite(f);
431
      write(f, Layout);
432
    finally
433
      CloseFile(f);
434
    end;
435
  except
436
    MessageDlg('������ ��� ������ � ������' + #13#10'��� ������ � "' +
437
      LayoutFName + '".', mtError, [mbOK], 0);
438
  end;
439

440
  if Altered then
441
  begin
442
    case MessageDlg('��������� ������� ���� ��������.' +
443
      #13#10'��������� ��������� ?', mtConfirmation,
444
      [mbYes, mbNo, mbCancel], 0) of
445
      mrYes:
446
        FunctionsForm.SaveClick(Sender);
447
      mrCancel:
448
        begin
449
          CanClose := false;
450
          Exit;
451
        end;
452
    end;
453
  end;
454
end;
455

456
procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
457
  Shift: TShiftState);
458
var
459
  X, Y, r: extended;
460

461
begin
462
  with GraphData.Grid do
463
    if (xAxisStyle = asLog) or (yAxisStyle = asLog) then
464
      Exit;
465
  case Key of
466
    // VK_F2:ShowAbout;
467
    VK_ESCAPE:
468
      if (MessageDlg('������� ����������?', mtConfirmation, [mbYes, mbNo], 0)
469
        = mrYes) then
470
        ExitAppClick(Sender);
471
    VK_LEFT, VK_NUMPAD4:
472
      begin
473
        Screen.Cursor := crMoveLeft;
474
        with GraphData do
475
        begin
476
          X := (xMax - xMin) / dMove;
477
          xMin := xMin + X;
478
          xMax := xMax + X;
479
        end;
480
        UpdateGridXRange;
481
        Altered := True;
482
        if dMove > 1 then
483
          dec(dMove, dMove div 16);
484
        GLViewer.Invalidate;
485
        Key := 0;
486
      end;
487
    VK_RIGHT, VK_NUMPAD6:
488
      begin
489
        Screen.Cursor := crMoveRight;
490
        with GraphData do
491
        begin
492
          X := (xMax - xMin) / dMove;
493
          xMin := xMin - X;
494
          xMax := xMax - X;
495
        end;
496
        UpdateGridXRange;
497
        Altered := True;
498
        if dMove > 1 then
499
          dec(dMove, dMove div 16);
500
        GLViewer.Invalidate;
501
        Key := 0;
502
      end;
503
    VK_UP, VK_NUMPAD8:
504
      begin
505
        Screen.Cursor := crMoveUp;
506
        with GraphData do
507
        begin
508
          Y := (yMax - yMin) / dMove;
509
          yMin := yMin - Y;
510
          yMax := yMax - Y;
511
        end;
512
        UpdateGridYRange;
513
        Altered := True;
514
        if dMove > 1 then
515
          dec(dMove, dMove div 16);
516
        GLViewer.Invalidate;
517
        Key := 0;
518
      end;
519
    VK_DOWN, VK_NUMPAD2:
520
      begin
521
        Screen.Cursor := crMoveDown;
522
        with GraphData do
523
        begin
524
          Y := (yMax - yMin) / dMove;
525
          yMin := yMin + Y;
526
          yMax := yMax + Y;
527
        end;
528
        UpdateGridYRange;
529
        Altered := True;
530
        if dMove > 1 then
531
          dec(dMove, dMove div 16);
532
        GLViewer.Invalidate;
533
        Key := 0;
534
      end;
535
    VK_ADD: // zoom in
536
      begin
537
        Screen.Cursor := crZoom;
538
        with GraphData do
539
        begin
540
          X := (xMax - xMin) / dMove;
541
          xMin := xMin + X;
542
          xMax := xMax - X;
543

544
          Y := (yMax - yMin) / dMove;
545
          yMin := yMin + Y;
546
          yMax := yMax - Y;
547
        end;
548
        UpdateGridXRange;
549
        UpdateGridYRange;
550
        Altered := True;
551
        if dMove > 1 then
552
          dec(dMove, dMove div 16);
553
        GLViewer.Invalidate;
554
        Key := 0;
555
      end;
556
    VK_SUBTRACT: // zoom out
557
      begin
558
        Screen.Cursor := crZoom;
559
        X := (GraphData.xMax - GraphData.xMin) / dMove;
560
        GraphData.xMin := GraphData.xMin - X;
561
        GraphData.xMax := GraphData.xMax + X;
562

563
        Y := (GraphData.yMax - GraphData.yMin) / dMove;
564
        GraphData.yMin := GraphData.yMin - Y;
565
        GraphData.yMax := GraphData.yMax + Y;
566
        UpdateGridXRange;
567
        UpdateGridYRange;
568
        Altered := True;
569
        if dMove > 1 then
570
          dec(dMove, dMove div 16);
571
        GLViewer.Invalidate;
572
        Key := 0;
573
      end;
574
    VK_HOME, VK_NUMPAD7:
575
      begin
576
        X := (GraphData.xMax - GraphData.xMin) / 2;
577
        GraphData.xMin := -X;
578
        GraphData.xMax := X;
579
        Y := (GraphData.yMax - GraphData.yMin) / 2;
580
        GraphData.yMin := -Y;
581
        GraphData.yMax := Y;
582
        UpdateGridXRange;
583
        UpdateGridYRange;
584
        Altered := True;
585
        GLViewer.Invalidate;
586
        Key := 0;
587
      end;
588
    12, VK_NUMPAD5: // eual grid
589
      begin
590
        with GraphData do
591
        begin
592
          X := xMax - xMin;
593
          Y := yMax - yMin;
594
          r := (X * MainForm.GLViewer.Height) / (Y * MainForm.GLViewer.Width);
595

596
          if X > Y then
597
          begin
598
            if Shift = [ssCtrl] then
599
            begin
600
              xMax := yMax;
601
              xMin := yMin;
602
            end
603
            else
604
            begin
605
              yMax := yMax * r;
606
              yMin := yMin * r;
607
            end;
608
          end
609
          else
610
          begin
611
            if Shift = [ssCtrl] then
612
            begin
613
              yMax := xMax;
614
              yMin := xMin;
615
            end
616
            else
617
            begin
618
              xMax := xMax / r;
619
              xMin := xMin / r;
620
            end;
621
          end;
622
        end;
623
        UpdateGridXRange;
624
        UpdateGridYRange;
625
        Altered := True;
626
        GLViewer.Invalidate;
627
        Key := 0;
628
      end;
629
  end;
630
end;
631

632
procedure TMainForm.FormKeyUp(Sender: TObject; var Key: Word;
633
  Shift: TShiftState);
634
begin
635
  Screen.Cursor := crDefault;
636
  dMove := $200;
637
end;
638

639
procedure TMainForm.FormMouseWheel(Sender: TObject; Shift: TShiftState;
640
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
641
var
642
  d: Integer;
643
  X, Y: extended;
644

645
begin
646
  with GraphData.Grid do
647
    if (xAxisStyle = asLog) or (yAxisStyle = asLog) then
648
      Exit;
649
  // WheelDelta is negative when wheel is rotated toward user, i.e. Zoom in.
650
  d := -WheelDelta div 2;
651
  if Shift = [ssShift] then
652
    d := d div 4
653
  else if Shift = [ssCtrl] then
654
    d := d div 2;
655

656
  with GraphData do
657
  begin
658
    X := (xMax - xMin) / d;
659
    xMin := xMin + X;
660
    xMax := xMax - X;
661

662
    Y := (yMax - yMin) / d;
663
    yMin := yMin + Y;
664
    yMax := yMax - Y;
665
  end;
666
  UpdateGridXRange;
667
  UpdateGridYRange;
668
  Altered := True;
669
  GLViewer.Invalidate;
670
end;
671

672
procedure TMainForm.GLViewerDragOver(Sender, Source: TObject; X, Y: Integer;
673
  State: TDragState; var Accept: Boolean);
674
begin
675
  Accept := Source = Sender;
676
  if Accept then
677
    with GraphData, PlotData do
678
    begin
679
      with Grid do
680
      begin
681
        if xAxisStyle = asLog then
682
          xLabel := ValueLogX(X)
683
        else
684
          xLabel := ValueX(X);
685

686
        if yAxisStyle = asLog then
687
          yLabel := ValueLogY(Y)
688
        else
689
          yLabel := ValueY(Y);
690
      end;
691

692
      FunctionsForm.EditLocX.Text := FloatToStrF(xLabel, ffNumber, 4, 3);
693
      FunctionsForm.EditLocY.Text := FloatToStrF(yLabel, ffNumber, 4, 3);
694
      ShowXYvalues(xLabel, yLabel);
695
    end;
696
end;
697

698
procedure TMainForm.GLViewerEndDrag(Sender, Target: TObject; X, Y: Integer);
699
begin
700
  if Target = Sender then // end of drag
701
    with FunctionsForm.CheckListBox,
702
      TPlotDataObject(Items.Objects[ItemIndex]).Data do
703
    begin
704
      with GraphData.Grid do
705
      begin
706
        if xAxisStyle = asLog then
707
          xLabel := ValueLogX(X)
708
        else
709
          xLabel := ValueX(X);
710

711
        if yAxisStyle = asLog then
712
          yLabel := ValueLogY(Y)
713
        else
714
          yLabel := ValueY(Y);
715
      end;
716

717
      Altered := True;
718
      GLViewer.Invalidate;
719
    end;
720
end;
721

722
procedure TMainForm.GLViewerMouseDown(Sender: TObject; Button: TMouseButton;
723
  Shift: TShiftState; X, Y: Integer);
724
var
725
  dx, dy: extended;
726

727
begin
728
  if Shift = [ssLeft] then // drag only if left button pressed
729
    with Sender as TGLSceneViewer do // treat Sender as TGLSceneViewer
730
    begin
731
      if (X >= LabelRect.Left) and (X <= LabelRect.Right) and
732
        (Y >= LabelRect.Top) and (Y <= LabelRect.Bottom) then
733
        BeginDrag(false)
734
      else
735
        Screen.Cursor := crHandMove;
736
    end
737
  else if (GraphData.Grid.xAxisStyle <> asLog) and
738
    (GraphData.Grid.yAxisStyle <> asLog) and (Shift = [ssLeft, ssAlt]) then
739
  begin // reposition graph; set mouse location as graph center
740
    with GraphData do
741
    begin
742
      dx := (xMin + xMax) / 2 - ValueX(X);
743
      dy := (yMin + yMax) / 2 - ValueY(Y);
744
      xMin := xMin - dx;
745
      xMax := xMax - dx;
746
      yMin := yMin - dy;
747
      yMax := yMax - dy;
748
    end;
749
    UpdateGridXRange;
750
    UpdateGridYRange;
751
    Altered := True;
752
    GLViewer.Invalidate;
753
  end;
754
end;
755

756
procedure TMainForm.GLViewerMouseLeave(Sender: TObject);
757
begin
758
  oMousex := -1;
759
end;
760

761
procedure TMainForm.GLViewerMouseMove(Sender: TObject; Shift: TShiftState;
762
  X, Y: Integer);
763

764
  procedure IsAltered;
765
  begin
766
    UpdateGridXRange;
767
    UpdateGridYRange;
768
    Altered := True;
769
    GLViewer.Invalidate;
770
  end;
771

772
var
773
  xValue, yValue: extended;
774

775
begin
776
  xValue := 0;
777
  yValue := 0;
778

779
  if Active and (oMousex > -1) then
780
  begin
781
    if Shift = [ssLeft] then
782
    begin
783
      with GraphData do
784
      begin
785
        if Grid.xAxisStyle = asLog then
786
        begin // ratio of change to current value of x
787
          xValue := (ValueLogX(X) - ValueLogX(oMousex)) / ValueLogX(X);
788
          xMin := xMin - xMin * xValue;
789
          xMax := xMax - xMax * xValue;
790
        end
791
        else
792
        begin
793
          xValue := ValueX(X) - ValueX(oMousex);
794
          xMax := xMax - xValue;
795
          xMin := xMin - xValue;
796
        end;
797

798
        if Grid.yAxisStyle = asLog then
799
        begin // ratio of change to current value of y
800
          yValue := (ValueLogY(Y) - ValueLogY(oMousey)) / ValueLogY(Y);
801
          yMin := yMin - yMin * yValue;
802
          yMax := yMax - yMax * yValue;
803
        end
804
        else
805
        begin
806
          yValue := ValueY(Y) - ValueY(oMousey);
807
          yMax := yMax - yValue;
808
          yMin := yMin - yValue;
809
        end;
810
      end;
811
      IsAltered;
812
    end
813
    else if Shift = [ssLeft, ssCtrl] then
814
    begin
815
      Screen.Cursor := crSizeAll;
816

817
      if GraphData.Grid.xAxisStyle = asLog then
818
      begin
819
        xValue := (ValueLogX(X) - ValueLogX(oMousex)) / ValueLogX(X);
820
        GraphData.xMin := GraphData.xMin + GraphData.xMin * xValue;
821
        GraphData.xMax := GraphData.xMax - GraphData.xMax * xValue;
822
      end
823
      else
824
      begin
825
        xValue := ValueX(X) - ValueX(oMousex);
826
        GraphData.xMin := GraphData.xMin + xValue;
827
        GraphData.xMax := GraphData.xMax - xValue;
828
      end;
829

830
      if GraphData.Grid.yAxisStyle = asLog then
831
      begin
832
        yValue := (ValueLogY(Y) - ValueLogY(oMousey)) / ValueLogY(Y);
833
        GraphData.yMin := GraphData.yMin + GraphData.yMin * yValue;
834
        GraphData.yMax := GraphData.yMax - GraphData.yMax * yValue;
835
      end
836
      else
837
      begin
838
        yValue := ValueY(Y) - ValueY(oMousey);
839
        GraphData.yMin := GraphData.yMin + yValue;
840
        GraphData.yMax := GraphData.yMax - yValue;
841
      end;
842

843
      IsAltered;
844
    end;
845

846
    if GraphData.Grid.xAxisStyle = asLog then
847
      xValue := ValueLogX(X)
848
    else
849
      xValue := ValueX(X);
850

851
    if GraphData.Grid.yAxisStyle = asLog then
852
      yValue := ValueLogY(Y)
853
    else
854
      yValue := ValueY(Y);
855
  end;
856

857
  oMousex := X;
858
  oMousey := Y;
859

860
  ShowXYvalues(xValue, yValue);
861
end;
862

863
procedure TMainForm.GLViewerMouseUp(Sender: TObject; Button: TMouseButton;
864
  Shift: TShiftState; X, Y: Integer);
865
begin
866
  Screen.Cursor := crDefault;
867
end;
868

869
procedure TMainForm.NewClick(Sender: TObject);
870
begin
871
  FunctionsForm.NewClick(Sender);
872
end;
873

874
procedure TMainForm.OpenClick(Sender: TObject);
875
begin
876
  FunctionsForm.OpenClick(Sender);
877
end;
878

879
procedure TMainForm.SaveClick(Sender: TObject);
880
begin
881
  FunctionsForm.SaveClick(Sender);
882
end;
883

884
procedure TMainForm.SaveAsClick(Sender: TObject);
885
begin
886
  FunctionsForm.SaveAsClick(Sender);
887
end;
888

889
procedure TMainForm.SaveBMPfile1Click(Sender: TObject);
890
begin
891
  BitmapForm := TBitmapForm.Create(Application);
892
  if FunctionsForm.CheckListBox.Count > 1 then
893
    BitmapForm.Caption := '   ��������� ������� ��� ''' +
894
      ChangeFileExt(GraphFName, '.bmp''')
895
  else
896
    BitmapForm.Caption := '   ��������� ������ ��� ''' +
897
      ChangeFileExt(GraphFName, '.bmp''');
898
  BitmapForm.ShowModal;
899
  BitmapForm.Free;
900
  BitmapForm := nil;
901
end;
902

903
procedure TMainForm.SaveJPGfile1Click(Sender: TObject);
904
begin
905
  BitmapForm := TBitmapForm.Create(Application);
906
  if FunctionsForm.CheckListBox.Count > 1 then
907
    BitmapForm.Caption := '   ��������� ������� ��� ''' +
908
      ChangeFileExt(GraphFName, '.jpg''')
909
  else
910
    BitmapForm.Caption := '   ��������� ������ ��� ''' +
911
      ChangeFileExt(GraphFName, '.jpg''');
912
  BitmapForm.ShowModal;
913
  BitmapForm.Free;
914
  BitmapForm := nil;
915
end;
916

917
procedure TMainForm.Print1Click(Sender: TObject);
918
begin
919
  PrintForm := TPrintForm.Create(Application);
920
  PrintForm.Caption := '   ������ ''' + GraphFName + '''.';
921
  PrintForm.ShowModal;
922
  PrintForm.Free;
923
  PrintForm := nil;
924
end;
925

926
procedure TMainForm.SetupPrinter1Click(Sender: TObject);
927
begin
928
  if PrinterSetupDialog.Execute then
929
  begin
930
    GetPrinterInfo(PrinterInfo);
931
    if PrinterInfo.Orientation = poPortrait then
932
      StatusBar.Panels[1].Text := '  ' + Printer.Printers[PrinterInfo.Index] +
933
        '  ' + GetPaperType + ', �������'
934
    else
935
      StatusBar.Panels[1].Text := '  ' + Printer.Printers[PrinterInfo.Index] +
936
        '  ' + GetPaperType + ', ���������';
937
  end;
938
end;
939

940
procedure TMainForm.DefaultLayout1Click(Sender: TObject);
941
begin
942
  DefaultLayout;
943
end;
944

945
procedure TMainForm.ExitAppClick(Sender: TObject);
946
begin
947
  Close;
948
end;
949

950
procedure TMainForm.GridOptions1Click(Sender: TObject);
951
begin
952
  if not GridOptionsForm.Visible then
953
    GridOptionsForm.Show;
954
end;
955

956
procedure TMainForm.NumGraphsClick(Sender: TObject);
957
begin
958
  if not NumericForm.Visible then
959
  begin
960
    NumericForm.Show;
961
    NumericForm.CheckListBoxClick(Sender); // updates NumericForm.DataListBox
962
  end;
963
end;
964

965
procedure TMainForm.Texts1Click(Sender: TObject);
966
begin
967
  if not TextBlocksForm.Visible then
968
    TextBlocksForm.Show;
969
end;
970

971
procedure TMainForm.SelectStyle1Click(Sender: TObject);
972
begin
973
  StyleNameForm := TStyleNameForm.Create(Application);
974
  StyleNameForm.Selecting := True;
975
  StyleNameForm.ShowModal;
976
  StyleNameForm.Free;
977
  StyleNameForm := nil;
978
  Altered := True;
979
  (*
980
    NewFont needed to initialize GLWinFont.GetCharWidth
981
    if the font has been altered, which may or may not be the case,
982
    so do it anyway
983
  *)
984
  NewFont := True;
985
  GLViewer.Invalidate;
986
end;
987

988
procedure TMainForm.SaveStyle1Click(Sender: TObject);
989
begin
990
  StyleNameForm := TStyleNameForm.Create(Application);
991
  StyleNameForm.Selecting := false;
992
  StyleNameForm.ShowModal;
993
  StyleNameForm.Free;
994
  StyleNameForm := nil;
995
end;
996

997
procedure TMainForm.GLDirectOpenGLRender(Sender: TObject;
998
  var rci: TGLRenderContextInfo);
999
var
1000
  fxCanvas: TfxCanvas;
1001

1002
begin
1003
  fxCanvas := TfxCanvas.Create(GLViewer.Width, GLViewer.Height);
1004
  try
1005
    if NewFont then
1006
    begin
1007
      fxCanvas.SetGLWinBitFont(rci, GLWinBitFont, GraphData.FontName,
1008
        GraphData.FontSize, GraphData.FontStyle);
1009
      fxCanvas.SetupFont(rci, GLWinBitFont);
1010
      NewFont := false;
1011
    end;
1012

1013
    with fxCanvas do
1014
    begin
1015
      xAxisGradsCalc(GLWinBitFont); // calculates graduations
1016
      yAxisGradsCalc(GLWinBitFont);
1017

1018
      if GraphData.Grid.GridStyle > gsNone then
1019
        DrawAxes;
1020

1021
      AddFunctionLabelsText; // add the labels to text list
1022
      DrawTextList(rci, TextList, GLWinBitFont); // axes and labels text
1023
      DrawFunctions;
1024
      DrawNumericData;
1025
      DrawTextBlocks(rci, GLWinBitFont);
1026
    end;
1027
  finally
1028
    fxCanvas.Free;
1029
  end;
1030
end;
1031

1032
procedure TMainForm.ShowXYvalues(const X, Y: extended);
1033
var
1034
  sx, sy: string;
1035

1036
begin
1037
  sx := FloatToStrF(X, ffNumber, 16, 8);
1038
  sy := FloatToStrF(Y, ffNumber, 16, 8);
1039
  StatusBar.Panels[0].Text := ' x : ' + sx + ', y : ' + sy;
1040
end;
1041

1042
procedure TMainForm.UpdateGridXRange;
1043
begin
1044
  with GridOptionsForm do
1045
    if Visible then
1046
    begin
1047
      EditMinX.Text := FloatToStrF(GraphData.xMin, ffGeneral, 13, 4);
1048
      EditMaxX.Text := FloatToStrF(GraphData.xMax, ffGeneral, 13, 4);
1049
    end;
1050
end;
1051

1052
procedure TMainForm.About1Click(Sender: TObject);
1053
begin
1054
  with TFormAbout.Create(Self) do
1055
  try
1056
    ShowModal;
1057
  finally
1058
    Free;
1059
  end;
1060
end;
1061

1062
procedure TMainForm.DefaultLayout;
1063
begin
1064
  MainForm.Left := 1;
1065
  MainForm.Top := 1;
1066
  MainForm.Width := Screen.Width - GridOptionsForm.Width - 10;
1067
  MainForm.Height := Screen.Height - 30;
1068
  FunctionsForm.Left := MainForm.Left + MainForm.Width + 5;
1069
  FunctionsForm.Top := MainForm.Top + 5;
1070
  GridOptionsForm.Left := FunctionsForm.Left;
1071
  GridOptionsForm.Top := FunctionsForm.Top + FunctionsForm.Height + 10;
1072
  GridOptionsForm.Show;
1073
  NumericForm.Top := 25;
1074
  NumericForm.Left := 25;
1075
  TextBlocksForm.Top := 75;
1076
  TextBlocksForm.Left := 75;
1077
end;
1078

1079
procedure TMainForm.UpdateGridYRange;
1080
begin
1081
  with GridOptionsForm do
1082
    if Visible then
1083
    begin
1084
      EditMinY.Text := FloatToStrF(GraphData.yMin, ffGeneral, 13, 4);
1085
      EditMaxY.Text := FloatToStrF(GraphData.yMax, ffGeneral, 13, 4);
1086
    end;
1087
end;
1088

1089
function TMainForm.ValueX(const X: Integer): extended;
1090
begin
1091
  Result := GraphData.xMin + X * (GraphData.xMax - GraphData.xMin) /
1092
    GLViewer.Width;
1093
end;
1094

1095
function TMainForm.ValueY(const Y: Integer): extended;
1096
begin
1097
  Result := GraphData.yMax + Y * (GraphData.yMin - GraphData.yMax) /
1098
    GLViewer.Height;
1099
end;
1100

1101
function TMainForm.ValueLogX(const X: Integer): extended;
1102
var
1103
  LogMin, a: extended;
1104

1105
begin
1106
  LogMin := Log10(GraphData.xMin);
1107
  a := LogMin + X * (Log10(GraphData.xMax) - LogMin) / GLViewer.Width;
1108
  Result := Power(10, a);
1109
end;
1110

1111
function TMainForm.ValueLogY(const Y: Integer): extended;
1112
var
1113
  LogMax, a: extended;
1114

1115
begin
1116
  LogMax := Log10(GraphData.yMax);
1117
  a := LogMax + Y * (Log10(GraphData.yMin) - LogMax) / GLViewer.Height;
1118
  Result := Power(10, a);
1119
end;
1120

1121
// ------------------------------------------------------------------
1122
initialization
1123

1124
// ------------------------------------------------------------------
1125
FormatSettings.DecimalSeparator := '.';
1126

1127
// ------------------------------------------------------------------
1128
finalization
1129

1130
// ------------------------------------------------------------------
1131
// return to FormatSettings.DecimalSeparator := ',';
1132

1133
end.
1134

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.