1 | unit UView;
|
---|
2 |
|
---|
3 | interface
|
---|
4 |
|
---|
5 | uses
|
---|
6 | Classes, SysUtils;
|
---|
7 |
|
---|
8 | type
|
---|
9 | { TView }
|
---|
10 |
|
---|
11 | TView = class
|
---|
12 | private
|
---|
13 | FDestRect: TRect;
|
---|
14 | FSourceRect: TRect;
|
---|
15 | FZoom: Double;
|
---|
16 | procedure SetDestRect(AValue: TRect);
|
---|
17 | procedure SetSourceRect(AValue: TRect);
|
---|
18 | procedure SetZoom(AValue: Double);
|
---|
19 | public
|
---|
20 | procedure Assign(Source: TView);
|
---|
21 | function PointDestToSrc(Pos: TPoint): TPoint;
|
---|
22 | function PointSrcToDest(Pos: TPoint): TPoint;
|
---|
23 | constructor Create;
|
---|
24 | property SourceRect: TRect read FSourceRect write SetSourceRect;
|
---|
25 | property DestRect: TRect read FDestRect write SetDestRect;
|
---|
26 | property Zoom: Double read FZoom write SetZoom;
|
---|
27 | end;
|
---|
28 |
|
---|
29 |
|
---|
30 | implementation
|
---|
31 |
|
---|
32 | uses
|
---|
33 | UGeometric;
|
---|
34 |
|
---|
35 | resourcestring
|
---|
36 | SZeroZoomNotAlowed = 'Zero zoom not allowed';
|
---|
37 |
|
---|
38 | { TView }
|
---|
39 |
|
---|
40 | procedure TView.SetDestRect(AValue: TRect);
|
---|
41 | var
|
---|
42 | Diff: TPoint;
|
---|
43 | begin
|
---|
44 | if RectEquals(FDestRect, AValue) then Exit;
|
---|
45 | Diff := Point(Trunc((DestRect.Right - DestRect.Left) / Zoom - (AValue.Right - AValue.Left) / Zoom) div 2,
|
---|
46 | Trunc((DestRect.Bottom - DestRect.Top) / Zoom - (AValue.Bottom - AValue.Top) / Zoom) div 2);
|
---|
47 | FDestRect := AValue;
|
---|
48 | FSourceRect := Bounds(FSourceRect.Left + Diff.X, FSourceRect.Top + Diff.Y,
|
---|
49 | Trunc((DestRect.Right - DestRect.Left) / Zoom),
|
---|
50 | Trunc((DestRect.Bottom - DestRect.Top) / Zoom));
|
---|
51 | end;
|
---|
52 |
|
---|
53 | procedure TView.SetSourceRect(AValue: TRect);
|
---|
54 | var
|
---|
55 | ZX: Double;
|
---|
56 | ZY: Double;
|
---|
57 | begin
|
---|
58 | if RectEquals(FSourceRect, AValue) then Exit;
|
---|
59 | FSourceRect := AValue;
|
---|
60 | if ((FSourceRect.Right - FSourceRect.Left) <> 0) and
|
---|
61 | ((FSourceRect.Bottom - FSourceRect.Top) <> 0) then begin
|
---|
62 | ZX := (FDestRect.Right - FDestRect.Left) / (FSourceRect.Right - FSourceRect.Left);
|
---|
63 | ZY := (FDestRect.Bottom - FDestRect.Top) / (FSourceRect.Bottom - FSourceRect.Top);
|
---|
64 | if ZX > ZY then
|
---|
65 | Zoom := ZY
|
---|
66 | else Zoom := ZX;
|
---|
67 | end else Zoom := 1;
|
---|
68 | end;
|
---|
69 |
|
---|
70 | procedure TView.SetZoom(AValue: Double);
|
---|
71 | begin
|
---|
72 | if FZoom = AValue then Exit;
|
---|
73 | if AValue = 0 then
|
---|
74 | raise Exception.Create(SZeroZoomNotAlowed);
|
---|
75 | FZoom := AValue;
|
---|
76 | FSourceRect := Bounds(Trunc(FSourceRect.Left + (FSourceRect.Right - FSourceRect.Left) div 2 - (DestRect.Right - DestRect.Left) / Zoom / 2),
|
---|
77 | Trunc(FSourceRect.Top + (FSourceRect.Bottom - FSourceRect.Top) div 2 - (FDestRect.Bottom - DestRect.Top) / Zoom / 2),
|
---|
78 | Trunc((DestRect.Right - DestRect.Left) / Zoom),
|
---|
79 | Trunc((DestRect.Bottom - DestRect.Top) / Zoom));
|
---|
80 | end;
|
---|
81 |
|
---|
82 | procedure TView.Assign(Source: TView);
|
---|
83 | begin
|
---|
84 | FDestRect := Source.FDestRect;
|
---|
85 | FSourceRect := Source.FSourceRect;
|
---|
86 | FZoom := Source.FZoom;
|
---|
87 | end;
|
---|
88 |
|
---|
89 | function TView.PointDestToSrc(Pos: TPoint): TPoint;
|
---|
90 | begin
|
---|
91 | Result := Point(Trunc(Pos.X / FZoom + FSourceRect.Left),
|
---|
92 | Trunc(Pos.Y / FZoom + FSourceRect.Top));
|
---|
93 | end;
|
---|
94 |
|
---|
95 | function TView.PointSrcToDest(Pos: TPoint): TPoint;
|
---|
96 | begin
|
---|
97 | Result := Point(Trunc((Pos.X - FSourceRect.Left) * FZoom),
|
---|
98 | Trunc((Pos.Y - FSourceRect.Top) * FZoom));
|
---|
99 | end;
|
---|
100 |
|
---|
101 | constructor TView.Create;
|
---|
102 | begin
|
---|
103 | Zoom := 1;
|
---|
104 | end;
|
---|
105 |
|
---|
106 | end.
|
---|
107 |
|
---|