1 | unit UView;
|
---|
2 |
|
---|
3 | interface
|
---|
4 |
|
---|
5 | uses
|
---|
6 | Classes, SysUtils, UItems, DOM;
|
---|
7 |
|
---|
8 | type
|
---|
9 | { TView }
|
---|
10 |
|
---|
11 | TView = class(TItem)
|
---|
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: TItem); override;
|
---|
21 | function PointDestToSrc(Pos: TPoint): TPoint;
|
---|
22 | function PointSrcToDest(Pos: TPoint): TPoint;
|
---|
23 | constructor Create;
|
---|
24 | procedure LoadFromXmlNode(Node: TDOMNode); override;
|
---|
25 | procedure SaveToXmlNode(Node: TDOMNode); override;
|
---|
26 | property SourceRect: TRect read FSourceRect write SetSourceRect;
|
---|
27 | property DestRect: TRect read FDestRect write SetDestRect;
|
---|
28 | property Zoom: Double read FZoom write SetZoom;
|
---|
29 | end;
|
---|
30 |
|
---|
31 |
|
---|
32 | implementation
|
---|
33 |
|
---|
34 | uses
|
---|
35 | UGeometric, UXMLUtils;
|
---|
36 |
|
---|
37 | resourcestring
|
---|
38 | SZeroZoomNotAlowed = 'Zero zoom not allowed';
|
---|
39 |
|
---|
40 | { TView }
|
---|
41 |
|
---|
42 | procedure TView.SetDestRect(AValue: TRect);
|
---|
43 | var
|
---|
44 | Diff: TPoint;
|
---|
45 | begin
|
---|
46 | if RectEquals(FDestRect, AValue) then Exit;
|
---|
47 | Diff := Point(Trunc((DestRect.Right - DestRect.Left) / Zoom - (AValue.Right - AValue.Left) / Zoom) div 2,
|
---|
48 | Trunc((DestRect.Bottom - DestRect.Top) / Zoom - (AValue.Bottom - AValue.Top) / Zoom) div 2);
|
---|
49 | FDestRect := AValue;
|
---|
50 | FSourceRect := Bounds(FSourceRect.Left + Diff.X, FSourceRect.Top + Diff.Y,
|
---|
51 | Trunc((DestRect.Right - DestRect.Left) / Zoom),
|
---|
52 | Trunc((DestRect.Bottom - DestRect.Top) / Zoom));
|
---|
53 | end;
|
---|
54 |
|
---|
55 | procedure TView.SetSourceRect(AValue: TRect);
|
---|
56 | var
|
---|
57 | ZX: Double;
|
---|
58 | ZY: Double;
|
---|
59 | begin
|
---|
60 | if RectEquals(FSourceRect, AValue) then Exit;
|
---|
61 | FSourceRect := AValue;
|
---|
62 | if ((FSourceRect.Right - FSourceRect.Left) <> 0) and
|
---|
63 | ((FSourceRect.Bottom - FSourceRect.Top) <> 0) then begin
|
---|
64 | ZX := (FDestRect.Right - FDestRect.Left) / (FSourceRect.Right - FSourceRect.Left);
|
---|
65 | ZY := (FDestRect.Bottom - FDestRect.Top) / (FSourceRect.Bottom - FSourceRect.Top);
|
---|
66 | if ZX > ZY then
|
---|
67 | Zoom := ZY
|
---|
68 | else Zoom := ZX;
|
---|
69 | end else Zoom := 1;
|
---|
70 | end;
|
---|
71 |
|
---|
72 | procedure TView.SetZoom(AValue: Double);
|
---|
73 | begin
|
---|
74 | if FZoom = AValue then Exit;
|
---|
75 | if AValue = 0 then
|
---|
76 | raise Exception.Create(SZeroZoomNotAlowed);
|
---|
77 | FZoom := AValue;
|
---|
78 | FSourceRect := Bounds(Trunc(FSourceRect.Left + (FSourceRect.Right - FSourceRect.Left) div 2 - (DestRect.Right - DestRect.Left) / Zoom / 2),
|
---|
79 | Trunc(FSourceRect.Top + (FSourceRect.Bottom - FSourceRect.Top) div 2 - (FDestRect.Bottom - DestRect.Top) / Zoom / 2),
|
---|
80 | Trunc((DestRect.Right - DestRect.Left) / Zoom),
|
---|
81 | Trunc((DestRect.Bottom - DestRect.Top) / Zoom));
|
---|
82 | end;
|
---|
83 |
|
---|
84 | procedure TView.Assign(Source: TItem);
|
---|
85 | begin
|
---|
86 | if Source is TView then begin
|
---|
87 | FDestRect := TView(Source).FDestRect;
|
---|
88 | FSourceRect := TView(Source).FSourceRect;
|
---|
89 | FZoom := TView(Source).FZoom;
|
---|
90 | end;
|
---|
91 | end;
|
---|
92 |
|
---|
93 | function TView.PointDestToSrc(Pos: TPoint): TPoint;
|
---|
94 | begin
|
---|
95 | Result := Point(Trunc(Pos.X / FZoom + FSourceRect.Left),
|
---|
96 | Trunc(Pos.Y / FZoom + FSourceRect.Top));
|
---|
97 | end;
|
---|
98 |
|
---|
99 | function TView.PointSrcToDest(Pos: TPoint): TPoint;
|
---|
100 | begin
|
---|
101 | Result := Point(Trunc((Pos.X - FSourceRect.Left) * FZoom),
|
---|
102 | Trunc((Pos.Y - FSourceRect.Top) * FZoom));
|
---|
103 | end;
|
---|
104 |
|
---|
105 | constructor TView.Create;
|
---|
106 | begin
|
---|
107 | Zoom := 1;
|
---|
108 | end;
|
---|
109 |
|
---|
110 | procedure TView.LoadFromXmlNode(Node: TDOMNode);
|
---|
111 | begin
|
---|
112 | inherited;
|
---|
113 | FZoom := ReadDouble(Node, 'Zoom', 0);
|
---|
114 | FSourceRect.Left := ReadInteger(Node, 'SourceRectLeft', 0);
|
---|
115 | FSourceRect.Top := ReadInteger(Node, 'SourceRectTop', 0);
|
---|
116 | FSourceRect.Right := ReadInteger(Node, 'SourceRectRight', 0);
|
---|
117 | FSourceRect.Bottom := ReadInteger(Node, 'SourceRectBottom', 0);
|
---|
118 | FDestRect.Left := ReadInteger(Node, 'DestRectLeft', 0);
|
---|
119 | FDestRect.Top := ReadInteger(Node, 'DestRectTop', 0);
|
---|
120 | FDestRect.Right := ReadInteger(Node, 'DestRectRight', 0);
|
---|
121 | FDestRect.Bottom := ReadInteger(Node, 'DestRectBottom', 0);
|
---|
122 | end;
|
---|
123 |
|
---|
124 | procedure TView.SaveToXmlNode(Node: TDOMNode);
|
---|
125 | begin
|
---|
126 | inherited;
|
---|
127 | WriteDouble(Node, 'Zoom', FZoom);
|
---|
128 | WriteInteger(Node, 'SourceRectLeft', FSourceRect.Left);
|
---|
129 | WriteInteger(Node, 'SourceRectTop', FSourceRect.Top);
|
---|
130 | WriteInteger(Node, 'SourceRectRight', FSourceRect.Right);
|
---|
131 | WriteInteger(Node, 'SourceRectBottom', FSourceRect.Bottom);
|
---|
132 | WriteInteger(Node, 'DestRectLeft', FDestRect.Left);
|
---|
133 | WriteInteger(Node, 'DestRectTop', FDestRect.Top);
|
---|
134 | WriteInteger(Node, 'DestRectRight', FDestRect.Right);
|
---|
135 | WriteInteger(Node, 'DestRectBottom', FDestRect.Bottom);
|
---|
136 | end;
|
---|
137 |
|
---|
138 | end.
|
---|
139 |
|
---|