source: branches/AlphaChannel/Packages/CevoComponents/DrawDlg.pas

Last change on this file was 257, checked in by chronos, 4 years ago
  • Modified: Allow to close windows by Escape key.
File size: 8.3 KB
Line 
1unit DrawDlg;
2
3{$mode delphi}{$H+}
4
5interface
6
7uses
8 Classes, SysUtils, Forms, LCLIntf, LCLType, {$IFDEF LINUX}LMessages,{$ENDIF}
9 Messages, Graphics, Controls, ButtonBase, ButtonA, ButtonB, Area, ScreenTools;
10
11type
12 { TDrawDlg }
13
14 TDrawDlg = class(TForm)
15 private
16 MoveFormPos: TPoint;
17 MoveMousePos: TPoint;
18 MoveActive: Boolean;
19 procedure VisibleChangedHandler(Sender: TObject);
20 protected
21 TitleHeight: Integer;
22 // defines area to grip the window for moving (from top)
23 procedure InitButtons;
24 procedure OnEraseBkgnd(var m: TMessage); message WM_ERASEBKGND;
25 procedure OnHitTest(var Msg: TMessage); message WM_NCHITTEST;
26 procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
27 override;
28 procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
29 procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
30 procedure MouseLeave; override;
31 procedure KeyDown(var Key: Word; Shift: TShiftState); override;
32 public
33 constructor Create(AOwner: TComponent); override;
34 destructor Destroy; override;
35 procedure SmartInvalidate; virtual;
36 end;
37
38 { TBaseMessgDlg }
39
40 TBaseMessgDlg = class(TDrawDlg)
41 procedure FormCreate(Sender: TObject);
42 procedure FormPaint(Sender: TObject);
43 public
44 MessgText: string;
45 protected
46 Lines, TopSpace: integer;
47 procedure SplitText(preview: boolean);
48 procedure CorrectHeight;
49 end;
50
51const
52 Border = 3;
53 MessageLineSpacing = 20;
54
55procedure Register;
56
57
58implementation
59
60procedure Register;
61begin
62 RegisterNoIcon([TDrawDlg]);
63 RegisterNoIcon([TBaseMessgDlg]);
64end;
65
66{ TDrawDlg }
67
68constructor TDrawDlg.Create(AOwner: TComponent);
69begin
70 inherited;
71 TitleHeight := 0;
72 MoveActive := False;
73 AddHandlerOnVisibleChanged(VisibleChangedHandler);
74end;
75
76destructor TDrawDlg.Destroy;
77begin
78 RemoveHandlerOnVisibleChanged(VisibleChangedHandler);
79 inherited Destroy;
80end;
81
82procedure TDrawDlg.OnEraseBkgnd(var m: TMessage);
83begin
84end;
85
86procedure TDrawDlg.OnHitTest(var Msg: TMessage);
87var
88 I: integer;
89 ControlBounds: TRect;
90 Pos: TPoint;
91begin
92 if BorderStyle <> bsNone then
93 inherited
94 else
95 begin
96 Pos := Point(Integer(Msg.LParam and $ffff),
97 Integer((Msg.LParam shr 16) and $ffff));
98 if Pos.Y >= Top + TitleHeight then
99 Msg.Result := HTCLIENT
100 else
101 begin
102 for I := 0 to ControlCount - 1 do
103 if Controls[I].Visible then
104 begin
105 ControlBounds := Controls[I].BoundsRect;
106 if (Pos.X >= Left + ControlBounds.Left) and
107 (Pos.X < Left + ControlBounds.Right) and
108 (Pos.Y >= Top + ControlBounds.Top) and
109 (Pos.Y < Top + ControlBounds.Bottom) then
110 begin
111 Msg.result := HTCLIENT;
112 Exit;
113 end;
114 end;
115 Msg.Result := HTCAPTION
116 end;
117 end;
118end;
119
120procedure TDrawDlg.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
121 Y: Integer);
122{$IFDEF LINUX}
123var
124 MousePosNew: TPoint;
125 NewFormPos: TPoint;
126{$ENDIF}
127begin
128 inherited;
129 {$IFDEF LINUX}
130 // Only if client is not doing own mouse move handling
131 if not Assigned(OnMouseDown) or not Assigned(OnMouseMove) or not Assigned(OnMouseUp) then begin
132 // HitTest is not supported under Linux GTK2 so use form inside move mechanizm
133 NewFormPos := ScreenToClient(Mouse.CursorPos);
134 if (NewFormPos.X >= 0) and (NewFormPos.X < Width) and
135 (NewFormPos.Y >= 0) and (NewFormPos.Y < Height) then begin
136 MoveMousePos := ClientToScreen(Point(X, Y));
137 MoveFormPos := Point(Left, Top);
138 MousePosNew := Mouse.CursorPos;
139 // Activate move only if mouse position was not changed during inherited call
140 if (MousePosNew.X = MoveMousePos.X) and (MousePosNew.Y = MoveMousePos.Y) then begin
141 MoveActive := True;
142 end;
143 end else MoveActive := False;
144 end;
145 {$ENDIF}
146end;
147
148procedure TDrawDlg.MouseMove(Shift: TShiftState; X, Y: Integer);
149var
150 MousePos: TPoint;
151begin
152 inherited;
153 if MoveActive then begin
154 MousePos := ClientToScreen(Point(X, Y));
155 SetBounds(MoveFormPos.X + MousePos.X - MoveMousePos.X,
156 MoveFormPos.Y + MousePos.Y - MoveMousePos.Y,
157 Width, Height);
158 end;
159end;
160
161procedure TDrawDlg.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
162 Y: Integer);
163begin
164 MoveActive := False;
165 inherited;
166end;
167
168procedure TDrawDlg.MouseLeave;
169begin
170 MoveActive := False;
171 inherited;
172end;
173
174procedure TDrawDlg.KeyDown(var Key: Word; Shift: TShiftState);
175begin
176 if Key = VK_ESCAPE then Close;
177 inherited KeyDown(Key, Shift);
178end;
179
180procedure TDrawDlg.VisibleChangedHandler(Sender: TObject);
181begin
182 MoveActive := False;
183end;
184
185procedure TDrawDlg.InitButtons;
186var
187 cix: integer;
188 // ButtonDownSound, ButtonUpSound: string;
189begin
190 // ButtonDownSound := Sounds.Lookup('BUTTON_DOWN');
191 // ButtonUpSound := Sounds.Lookup('BUTTON_UP');
192 for cix := 0 to ComponentCount - 1 do
193 if Components[cix] is TButtonBase then
194 begin
195 TButtonBase(Components[cix]).Graphic := GrExt[HGrSystem].Data;
196 // if ButtonDownSound <> '*' then
197 // DownSound := GetSoundsDir + DirectorySeparator + ButtonDownSound + '.wav';
198 // if ButtonUpSound <> '*' then
199 // UpSound := GetSoundsDir + DirectorySeparator + ButtonUpSound + '.wav';
200 if Components[cix] is TButtonA then
201 TButtonA(Components[cix]).Font := UniFont[ftButton];
202 if Components[cix] is TButtonB then
203 TButtonB(Components[cix]).Mask := GrExt[HGrSystem].Mask;
204 end;
205end;
206
207procedure TDrawDlg.SmartInvalidate;
208var
209 i: integer;
210 r0, r1: HRgn;
211begin
212 r0 := CreateRectRgn(0, 0, ClientWidth, ClientHeight);
213 for i := 0 to ControlCount - 1 do
214 if not(Controls[i] is TArea) and Controls[i].Visible then
215 begin
216 with Controls[i].BoundsRect do
217 r1 := CreateRectRgn(Left, Top, Right, Bottom);
218 CombineRgn(r0, r0, r1, RGN_DIFF);
219 DeleteObject(r1);
220 end;
221 InvalidateRgn(Handle, r0, false);
222 DeleteObject(r0);
223end;
224
225{ TBaseMessgDlg }
226
227procedure TBaseMessgDlg.FormCreate(Sender: TObject);
228begin
229 Left := (Screen.Width - Width) div 2;
230 Canvas.Font.Assign(UniFont[ftNormal]);
231 Canvas.Brush.Style := bsClear;
232 MessgText := '';
233 TopSpace := 0;
234 TitleHeight := Screen.Height;
235 if csDesigning in ComponentState then Exit;
236 InitButtons;
237end;
238
239procedure TBaseMessgDlg.FormPaint(Sender: TObject);
240var
241 i, cix: integer;
242begin
243 if csDesigning in ComponentState then Exit;
244 PaintBackground(self, 3 + Border, 3 + Border, ClientWidth - (6 + 2 * Border),
245 ClientHeight - (6 + 2 * Border));
246 for i := 0 to Border do
247 Frame(Canvas, i, i, ClientWidth - 1 - i, ClientHeight - 1 - i,
248 $000000, $000000);
249 Frame(Canvas, Border + 1, Border + 1, ClientWidth - (2 + Border),
250 ClientHeight - (2 + Border), MainTexture.clBevelLight,
251 MainTexture.clBevelShade);
252 Frame(Canvas, 2 + Border, 2 + Border, ClientWidth - (3 + Border),
253 ClientHeight - (3 + Border), MainTexture.clBevelLight,
254 MainTexture.clBevelShade);
255 SplitText(false);
256
257 for cix := 0 to ControlCount - 1 do
258 if (Controls[cix].Visible) and (Controls[cix] is TButtonBase) then
259 BtnFrame(Canvas, Controls[cix].BoundsRect, MainTexture);
260end;
261
262procedure TBaseMessgDlg.SplitText(preview: boolean);
263var
264 Start, Stop, OrdinaryStop, LinesCount: integer;
265 s: string;
266begin
267 Start := 1;
268 LinesCount := 0;
269 while Start < Length(MessgText) do
270 begin
271 Stop := Start;
272 while (Stop < Length(MessgText)) and (MessgText[Stop] <> '\') and
273 (BiColorTextWidth(Canvas, Copy(MessgText, Start, Stop - Start + 1)) <
274 ClientWidth - 56) do
275 inc(Stop);
276 if Stop <> Length(MessgText) then
277 begin
278 OrdinaryStop := Stop;
279 repeat
280 dec(OrdinaryStop)
281 until (MessgText[OrdinaryStop + 1] = ' ') or
282 (MessgText[OrdinaryStop + 1] = '\');
283 if (OrdinaryStop + 1 - Start) * 2 >= Stop - Start then
284 Stop := OrdinaryStop
285 end;
286 if not preview then
287 begin
288 s := Copy(MessgText, Start, Stop - Start + 1);
289 LoweredTextOut(Canvas, -1, MainTexture,
290 (ClientWidth - BiColorTextWidth(Canvas, s)) div 2,
291 19 + Border + TopSpace + LinesCount * MessageLineSpacing, s);
292 end;
293 Start := Stop + 2;
294 inc(LinesCount)
295 end;
296 if preview then
297 Lines := LinesCount;
298end;
299
300procedure TBaseMessgDlg.CorrectHeight;
301var
302 i: integer;
303begin
304 ClientHeight := 72 + Border + TopSpace + Lines * MessageLineSpacing;
305 Top := (Screen.Height - ClientHeight) div 2;
306 for i := 0 to ControlCount - 1 do
307 Controls[i].Top := ClientHeight - (34 + Border);
308end;
309
310end.
311
Note: See TracBrowser for help on using the repository browser.