source: tags/1.3.1/Packages/CevoComponents/BaseWin.pas

Last change on this file was 442, checked in by chronos, 2 years ago
  • Modified: Code cleanup.
File size: 15.8 KB
Line 
1unit BaseWin;
2
3interface
4
5uses
6 ScreenTools, LCLIntf, LCLType, SysUtils, Classes, Graphics, Controls, Forms,
7 DrawDlg;
8
9type
10 TWindowMode = (wmNone, wmModal, wmPersistent, wmSubmodal);
11 TShowNewContent = procedure (NewMode: TWindowMode; HelpContext: string) of object;
12
13 { TBufferedDrawDlg }
14
15 TBufferedDrawDlg = class(TDrawDlg)
16 public
17 UserLeft: Integer;
18 UserTop: Integer;
19 constructor Create(AOwner: TComponent); override;
20 destructor Destroy; override;
21 procedure FormClose(Sender: TObject; var Action: TCloseAction);
22 procedure FormPaint(Sender: TObject);
23 procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
24 procedure FormDeactivate(Sender: TObject);
25 procedure SmartUpdateContent(ImmUpdate: Boolean = false);
26 procedure StayOnTop_Workaround;
27 protected
28 FWindowMode: TWindowMode;
29 ModalFrameIndent: Integer;
30 HelpContext: string;
31 procedure ShowNewContent(NewMode: TWindowMode; ForceClose: Boolean = False);
32 procedure MarkUsedOffscreen(xMax, yMax: Integer);
33 procedure OffscreenPaint; virtual;
34 procedure VPaint; virtual;
35 public
36 UsedOffscreenWidth: Integer;
37 UsedOffscreenHeight: Integer;
38 Offscreen: TBitmap;
39 OffscreenUser: TForm;
40 property WindowMode: TWindowMode read FWindowMode;
41 end;
42
43 TFramedDlg = class(TBufferedDrawDlg)
44 public
45 constructor Create(AOwner: TComponent); override;
46 procedure FormCreate(Sender: TObject);
47 procedure SmartInvalidate; override;
48 protected
49 CaptionLeft: Integer;
50 CaptionRight: Integer;
51 InnerWidth: Integer;
52 InnerHeight: integer;
53 WideBottom: Boolean;
54 FullCaption: Boolean;
55 TexOverride: Boolean;
56 ModalIndication: Boolean;
57 procedure InitWindowRegion;
58 procedure VPaint; override;
59 procedure FillOffscreen(Left, Top, Width, Height: Integer);
60 end;
61
62var
63 ShowNewContentProc: TShowNewContent;
64 MainFormKeyDown: TKeyEvent;
65
66const
67 yUnused = 161;
68 NarrowFrame = 11;
69 WideFrame = 36;
70 SideFrame = 9;
71
72procedure CreateOffscreen(var Offscreen: TBitmap);
73function WindowModeMakePersistent(Mode: TWindowMode): TWindowMode;
74procedure Register;
75
76
77implementation
78
79uses
80 ButtonBase, Area;
81
82function WindowModeMakePersistent(Mode: TWindowMode): TWindowMode;
83begin
84 if Mode = wmModal then Result := wmSubmodal
85 else Result := wmPersistent;
86end;
87
88procedure Register;
89begin
90 RegisterNoIcon([TBufferedDrawDlg]);
91 RegisterNoIcon([TFramedDlg]);
92end;
93
94constructor TBufferedDrawDlg.Create(AOwner: TComponent);
95begin
96 BaseWin.CreateOffscreen(Offscreen);
97 OnClose := FormClose;
98 OnPaint := FormPaint;
99 OnKeyDown := FormKeyDown;
100 OnDeactivate := FormDeactivate;
101 inherited;
102 FWindowMode := wmNone;
103 HelpContext := 'CONCEPTS';
104 TitleHeight := WideFrame;
105 ModalFrameIndent := 45;
106 UserLeft := (Screen.Width - Width) div 2;
107 UserTop := (Screen.Height - Height) div 2;
108end;
109
110destructor TBufferedDrawDlg.Destroy;
111begin
112 FreeAndNil(Offscreen);
113 inherited;
114end;
115
116procedure TBufferedDrawDlg.FormClose(Sender: TObject; var Action: TCloseAction);
117begin
118 if FWindowMode = wmPersistent then begin
119 UserLeft := Left;
120 UserTop := Top;
121 end;
122 if OffscreenUser = self then
123 OffscreenUser := nil;
124end;
125
126procedure TBufferedDrawDlg.FormPaint(Sender: TObject);
127begin
128 if OffscreenUser <> self then
129 OffscreenPaint;
130 VPaint;
131end;
132
133procedure TBufferedDrawDlg.FormKeyDown(Sender: TObject; var Key: Word;
134 Shift: TShiftState);
135begin
136 if Key = VK_ESCAPE then begin
137 if fsModal in FormState then
138 ModalResult := mrCancel;
139 end else
140 if Key = VK_RETURN then begin
141 if fsModal in FormState then
142 ModalResult := mrOK;
143 end else
144 if Key = VK_F1 then begin
145 if Assigned(ShowNewContentProc) then
146 ShowNewContentProc(WindowModeMakePersistent(FWindowMode), HelpContext);
147 end else
148 if FWindowMode = wmPersistent then begin
149 if Assigned(MainFormKeyDown) then
150 MainFormKeyDown(Sender, Key, Shift);
151 end;
152end;
153
154procedure TBufferedDrawDlg.FormDeactivate(Sender: TObject);
155begin
156 if FWindowMode = wmSubmodal then
157 Close;
158end;
159
160procedure TBufferedDrawDlg.OffscreenPaint;
161begin
162 if (OffscreenUser <> nil) and (OffscreenUser <> Self) then
163 OffscreenUser.Update; // complete working with old owner to prevent rebound
164 OffscreenUser := Self;
165end;
166
167procedure TBufferedDrawDlg.VPaint;
168begin
169 BitBltCanvas(Canvas, 0, 0, ClientWidth, ClientHeight, Offscreen.Canvas, 0, 0);
170end;
171
172procedure TBufferedDrawDlg.ShowNewContent(NewMode: TWindowMode;
173 ForceClose: Boolean);
174begin
175 if Visible then begin
176 Assert((NewMode = wmModal) or (FWindowMode <> wmModal));
177 // don't make modal window non-modal
178 if (NewMode = wmModal) and (forceclose or (FWindowMode <> wmModal)) then
179 begin // make modal
180 UserLeft := Left;
181 UserTop := Top;
182 Visible := false;
183 FWindowMode := NewMode;
184 ShowModal;
185 end
186 else if forceclose then
187 begin // make modal
188 Visible := false;
189 FWindowMode := NewMode;
190 Left := UserLeft;
191 Top := UserTop;
192 Show;
193 end
194 else
195 begin
196 FWindowMode := NewMode;
197 if @OnShow <> nil then
198 OnShow(nil);
199 Invalidate;
200 BringToFront;
201 end;
202 end
203 else
204 begin
205 FWindowMode := NewMode;
206 Left := UserLeft;
207 Top := UserTop;
208 if FWindowMode = wmModal then begin
209 Gtk2Fix;
210 ShowModal;
211 end
212 else
213 Show;
214 end;
215end;
216
217procedure TBufferedDrawDlg.SmartUpdateContent(ImmUpdate: Boolean);
218begin
219 if Visible then begin
220 OffscreenPaint;
221 SmartInvalidate;
222 if ImmUpdate then
223 Update;
224 end;
225end;
226
227procedure TBufferedDrawDlg.MarkUsedOffscreen(xMax, yMax: Integer);
228begin
229 if xMax > UsedOffscreenWidth then
230 UsedOffscreenWidth := xMax;
231 if yMax > UsedOffscreenHeight then
232 UsedOffscreenHeight := yMax;
233end;
234
235procedure TBufferedDrawDlg.StayOnTop_Workaround;
236// stayontop doesn't work when window is shown for the first time
237// after application lost focus, so show all stayontop-windows in first turn
238var
239 SaveOnShow, SaveOnPaint: TNotifyEvent;
240begin
241 Top := Screen.Height;
242 SaveOnShow := OnShow;
243 OnShow := nil;
244 SaveOnPaint := OnPaint;
245 OnPaint := nil;
246 FWindowMode := wmNone;
247 Show;
248 Hide;
249 OnShow := SaveOnShow;
250 OnPaint := SaveOnPaint;
251end;
252
253constructor TFramedDlg.Create;
254begin
255 OnCreate := FormCreate;
256 inherited;
257end;
258
259procedure TFramedDlg.FormCreate(Sender: TObject);
260begin
261 CaptionLeft := 0;
262 CaptionRight := $FFFF;
263 WideBottom := False;
264 FullCaption := True;
265 TexOverride := False;
266 ModalIndication := True;
267 Canvas.Brush.Style := bsClear;
268 InnerWidth := Width - 2 * SideFrame;
269 InnerHeight := Height - TitleHeight - NarrowFrame;
270end;
271
272procedure TFramedDlg.SmartInvalidate;
273var
274 i, BottomFrame: integer;
275 r0, r1: HRgn;
276begin
277 if WideBottom then
278 BottomFrame := WideFrame
279 else
280 BottomFrame := NarrowFrame;
281 r0 := CreateRectRgn(SideFrame, TitleHeight, ClientWidth - SideFrame,
282 ClientHeight - BottomFrame);
283 for i := 0 to ControlCount - 1 do
284 if not(Controls[i] is TArea) and Controls[i].Visible then
285 begin
286 with Controls[i].BoundsRect do
287 r1 := CreateRectRgn(Left, Top, Right, Bottom);
288 CombineRgn(r0, r0, r1, RGN_DIFF);
289 DeleteObject(r1);
290 end;
291 InvalidateRgn(Handle, r0, False);
292 DeleteObject(r0);
293end;
294
295procedure TFramedDlg.VPaint;
296
297 procedure CornerFrame(x0, y0, x1, y1: integer);
298 begin
299 Frame(Canvas, x0 + 1, y0 + 1, x1 - 2, y1 - 2, MainTexture.ColorBevelLight,
300 MainTexture.ColorBevelShade);
301 Frame(Canvas, x0 + 2, y0 + 2, x1 - 3, y1 - 3, MainTexture.ColorBevelLight,
302 MainTexture.ColorBevelShade);
303 Corner(Canvas, x0 + 1, y0 + 1, 0, MainTexture);
304 Corner(Canvas, x1 - 9, y0 + 1, 1, MainTexture);
305 Corner(Canvas, x0 + 1, y1 - 9, 2, MainTexture);
306 Corner(Canvas, x1 - 9, y1 - 9, 3, MainTexture);
307 end;
308
309var
310 i, l, FrameTop, FrameBottom, InnerBottom, Cut, xTexOffset,
311 yTexOffset: integer;
312 R: TRect;
313begin
314 if not TexOverride then
315 begin
316 if (FWindowMode = wmModal) and ModalIndication then
317 MainTexture := MainTexture
318 else
319 MainTexture := MainTexture;
320 MainTexture := MainTexture;
321 end;
322 Canvas.Font.Assign(UniFont[ftCaption]);
323 l := BiColorTextWidth(Canvas, Caption);
324 Cut := (ClientWidth - l) div 2;
325 xTexOffset := (Maintexture.Width - ClientWidth) div 2;
326 yTexOffset := (Maintexture.Height - ClientHeight) div 2;
327 if WideBottom then
328 InnerBottom := ClientHeight - WideFrame
329 else
330 InnerBottom := ClientHeight - NarrowFrame;
331 if FullCaption then
332 begin
333 FrameTop := 0;
334 FrameBottom := ClientHeight;
335 end
336 else
337 begin
338 FrameTop := TitleHeight - NarrowFrame;
339 if WideBottom then
340 FrameBottom := ClientHeight - (WideFrame - NarrowFrame)
341 else
342 FrameBottom := ClientHeight;
343 end;
344 Fill(Canvas, 3, InnerBottom + 1, ClientWidth - 6, ClientHeight - InnerBottom -
345 4, xTexOffset, yTexOffset);
346 Fill(Canvas, 3, TitleHeight - 2, SideFrame - 3, InnerBottom - TitleHeight + 4,
347 xTexOffset, yTexOffset);
348 Fill(Canvas, ClientWidth - SideFrame, TitleHeight - 2, SideFrame - 3,
349 InnerBottom - TitleHeight + 4, xTexOffset, yTexOffset);
350 Frame(Canvas, 0, FrameTop, ClientWidth - 1, FrameBottom - 1, 0, 0);
351 Frame(Canvas, SideFrame - 1, TitleHeight - 1, ClientWidth - SideFrame,
352 InnerBottom, MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
353 // RFrame(Canvas,SideFrame-2,TitleHeight-2,ClientWidth-SideFrame+1,
354 // InnerBottom+1,MainTexture.ColorBevelShade,MainTexture.ColorBevelLight);
355 if FullCaption then begin
356 if (FWindowMode <> wmModal) or not ModalIndication then
357 begin
358 Fill(Canvas, 3, 3 + FrameTop, ClientWidth - 6, TitleHeight - FrameTop - 4,
359 xTexOffset, yTexOffset);
360 CornerFrame(0, FrameTop, ClientWidth, FrameBottom);
361 end
362 else
363 with Canvas do
364 begin
365 Fill(Canvas, 3 + ModalFrameIndent, 3 + FrameTop,
366 ClientWidth - 6 - 2 * ModalFrameIndent, TitleHeight - FrameTop - 4,
367 xTexOffset, yTexOffset);
368 Fill(Canvas, ClientWidth - 3 - ModalFrameIndent, 3 + FrameTop,
369 ModalFrameIndent, TitleHeight - FrameTop - 4, xTexOffset, yTexOffset);
370 Fill(Canvas, 3, 3 + FrameTop, ModalFrameIndent, TitleHeight - FrameTop -
371 4, xTexOffset, yTexOffset);
372 CornerFrame(0, FrameTop, ClientWidth, FrameBottom);
373 Pen.Color := MainTexture.ColorBevelShade;
374 MoveTo(3 + ModalFrameIndent, 2);
375 LineTo(3 + ModalFrameIndent, TitleHeight);
376 Pen.Color := MainTexture.ColorBevelShade;
377 MoveTo(4 + ModalFrameIndent, TitleHeight - 1);
378 LineTo(ClientWidth - 4 - ModalFrameIndent, TitleHeight - 1);
379 LineTo(ClientWidth - 4 - ModalFrameIndent, 1);
380 Pen.Color := MainTexture.ColorBevelLight;
381 MoveTo(ClientWidth - 5 - ModalFrameIndent, 2);
382 LineTo(4 + ModalFrameIndent, 2);
383 LineTo(4 + ModalFrameIndent, TitleHeight);
384 MoveTo(ClientWidth - 4 - ModalFrameIndent, 1);
385 LineTo(3 + ModalFrameIndent, 1);
386 Pen.Color := MainTexture.ColorBevelLight;
387 MoveTo(ClientWidth - 3 - ModalFrameIndent, 3);
388 LineTo(ClientWidth - 3 - ModalFrameIndent, TitleHeight);
389 end;
390 end
391 else
392 begin
393 Fill(Canvas, 3, 3 + FrameTop, ClientWidth - 6, TitleHeight - FrameTop - 4,
394 xTexOffset, yTexOffset);
395 CornerFrame(0, FrameTop, ClientWidth, FrameBottom);
396
397 Frame(Canvas, CaptionLeft, 0, ClientWidth - CaptionLeft - 1,
398 FrameTop, 0, 0);
399 Fill(Canvas, CaptionLeft + 3, 3, ClientWidth - 2 * (CaptionLeft) - 6,
400 TitleHeight - 4, xTexOffset, yTexOffset);
401
402 Frame(Canvas, CaptionLeft + 1, 0 + 1, ClientWidth - CaptionLeft - 2,
403 TitleHeight - 1, MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
404 Frame(Canvas, CaptionLeft + 2, 0 + 2, ClientWidth - CaptionLeft - 3,
405 TitleHeight - 1, MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
406 Corner(Canvas, CaptionLeft + 1, 0 + 1, 0, MainTexture);
407 Corner(Canvas, ClientWidth - CaptionLeft - 9, 0 + 1, 1, MainTexture);
408
409 with Canvas do
410 begin
411 Pen.Color := MainTexture.ColorBevelShade;
412 MoveTo(CaptionLeft + 1, FrameTop + 2);
413 LineTo(CaptionLeft + 1, TitleHeight);
414 Pen.Color := MainTexture.ColorBevelLight;
415 MoveTo(ClientWidth - CaptionLeft - 2, FrameTop + 2);
416 LineTo(ClientWidth - CaptionLeft - 2, TitleHeight);
417 end;
418 if WideBottom then
419 begin
420 Frame(Canvas, CaptionLeft, FrameBottom, ClientWidth - CaptionLeft - 1,
421 ClientHeight - 1, 0, 0);
422 Fill(Canvas, CaptionLeft + 3, ClientHeight - 3 - (WideFrame - 5),
423 ClientWidth - 2 * (CaptionLeft) - 6, WideFrame - 5, xTexOffset,
424 yTexOffset);
425 Frame(Canvas, CaptionLeft + 1, ClientHeight - WideFrame - 1 + 1,
426 ClientWidth - CaptionLeft - 2, ClientHeight - 2,
427 MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
428 Frame(Canvas, CaptionLeft + 2, ClientHeight - WideFrame - 1 + 1,
429 ClientWidth - CaptionLeft - 3, ClientHeight - 3,
430 MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
431 Corner(Canvas, CaptionLeft + 1, ClientHeight - 9, 2, MainTexture);
432 Corner(Canvas, ClientWidth - CaptionLeft - 9, ClientHeight - 9, 3,
433 MainTexture);
434
435 with Canvas do
436 begin
437 Pen.Color := MainTexture.ColorBevelShade;
438 MoveTo(CaptionLeft + 1, ClientHeight - WideFrame);
439 LineTo(CaptionLeft + 1, FrameBottom - 2);
440 Pen.Color := MainTexture.ColorBevelLight;
441 MoveTo(ClientWidth - CaptionLeft - 2, ClientHeight - WideFrame);
442 LineTo(ClientWidth - CaptionLeft - 2, FrameBottom - 2);
443 end;
444 end;
445 end;
446 RisedTextOut(Canvas, Cut - 1, 7, Caption);
447
448 for i := 0 to ControlCount - 1 do
449 if Controls[i].Visible and (Controls[i] is TButtonBase) then
450 begin
451 R := Controls[i].BoundsRect;
452 if (R.Bottom <= TitleHeight) or (R.Top >= InnerBottom) then
453 BtnFrame(Canvas, R, MainTexture);
454 end;
455
456 BitBltCanvas(Canvas, SideFrame, TitleHeight, ClientWidth - 2 * SideFrame,
457 InnerBottom - TitleHeight, Offscreen.Canvas, 0, 0);
458end;
459
460procedure TFramedDlg.InitWindowRegion;
461var
462 r0, r1: HRgn;
463begin
464 if FullCaption then
465 exit;
466 r0 := CreateRectRgn(0, 0, ClientWidth, ClientHeight);
467 r1 := CreateRectRgn(0, 0, CaptionLeft, TitleHeight - NarrowFrame);
468 CombineRgn(r0, r0, r1, RGN_DIFF);
469 // DeleteObject(r1);
470 r1 := CreateRectRgn(ClientWidth - CaptionLeft, 0, ClientWidth,
471 TitleHeight - NarrowFrame);
472 CombineRgn(r0, r0, r1, RGN_DIFF);
473 // DeleteObject(r1);
474 if WideBottom then
475 begin
476 r1 := CreateRectRgn(0, ClientHeight - (WideFrame - NarrowFrame),
477 CaptionLeft, ClientHeight);
478 CombineRgn(r0, r0, r1, RGN_DIFF);
479 // DeleteObject(r1);
480 r1 := CreateRectRgn(ClientWidth - CaptionLeft,
481 ClientHeight - (WideFrame - NarrowFrame), ClientWidth, ClientHeight);
482 CombineRgn(r0, r0, r1, RGN_DIFF);
483 // DeleteObject(r1);
484 end;
485 SetWindowRgn(Handle, r0, False);
486 // DeleteObject(r0); // causes crash with Windows 95
487end;
488
489procedure TFramedDlg.FillOffscreen(Left, Top, Width, Height: Integer);
490begin
491 Fill(Offscreen.Canvas, Left, Top, Width, Height,
492 SideFrame + (Maintexture.Width - ClientWidth) div 2,
493 TitleHeight + (Maintexture.Height - ClientHeight) div 2);
494end;
495
496procedure CreateOffscreen(var Offscreen: TBitmap);
497begin
498 if Offscreen <> nil then
499 Exit;
500 Offscreen := TBitmap.Create;
501 Offscreen.PixelFormat := pf24bit;
502 if Screen.Height - yUnused < 480 then
503 Offscreen.SetSize(Screen.Width, 480)
504 else
505 Offscreen.SetSize(Screen.Width, Screen.Height - yUnused);
506 Offscreen.Canvas.FillRect(0, 0, Offscreen.Width, OffScreen.Height);
507 Offscreen.Canvas.Brush.Style := bsClear;
508end;
509
510initialization
511
512ShowNewContentProc := nil;
513MainFormKeyDown := nil;
514
515end.
Note: See TracBrowser for help on using the repository browser.