1 {
2 /***************************************************************************
3 extdlgs.pas
4 -----------
5 Component Library Extended dialogs Controls
6
7
8 ***************************************************************************/
9
10 *****************************************************************************
11 This file is part of the Lazarus Component Library (LCL)
12
13 See the file COPYING.modifiedLGPL.txt, included in this distribution,
14 for details about the license.
15 *****************************************************************************
16 }
17 unit ExtDlgs;
18
19 {$mode objfpc}{$H+}
20
21 interface
22
23 uses
24 Types, Classes, SysUtils, LCLProc, LResources, LCLType, LCLStrConsts,
25 FileUtil, LazFileUtils, Controls, Dialogs, GraphType, Graphics, ExtCtrls,
26 StdCtrls, Forms, Calendar, Buttons, Masks, CalcForm;
27
28 type
29
30 { TPreviewFileControl }
31
32 TPreviewFileDialog = class;
33
34 TPreviewFileControl = class(TWinControl)
35 private
36 FPreviewFileDialog: TPreviewFileDialog;
37 protected
38 class procedure WSRegisterClass; override;
GetControlClassDefaultSizenull39 class function GetControlClassDefaultSize: TSize; override;
40 procedure SetPreviewFileDialog(const AValue: TPreviewFileDialog);
41 procedure CreateParams(var Params: TCreateParams); override;
42 public
43 constructor Create(TheOwner: TComponent); override;
44 property PreviewFileDialog: TPreviewFileDialog read FPreviewFileDialog
45 write SetPreviewFileDialog;
46 end;
47
48 { TPreviewFileDialog }
49
50 TPreviewFileDialog = class(TOpenDialog)
51 private
52 FPreviewFileControl: TPreviewFileControl;
GetPreviewFileControlnull53 function GetPreviewFileControl:TPreviewFileControl;
54 protected
55 class procedure WSRegisterClass; override;
56 procedure CreatePreviewControl; virtual;
57 procedure InitPreviewControl; virtual;
DoExecutenull58 function DoExecute: boolean; override;
59 public
60 constructor Create(TheOwner: TComponent); override;
61 property PreviewFileControl: TPreviewFileControl read GetPreviewFileControl;
62 end;
63
64 { TOpenPictureDialog }
65
66 TOpenPictureDialog = class(TPreviewFileDialog)
67 private
68 FDefaultFilter: string;
69 FImageCtrl: TImage;
70 FPictureGroupBox: TGroupBox;
71 FPreviewFilename: string;
72 protected
73 class procedure WSRegisterClass; override;
IsFilterStorednull74 function IsFilterStored: Boolean; virtual;
75 property ImageCtrl: TImage read FImageCtrl;
76 property PictureGroupBox: TGroupBox read FPictureGroupBox;
77 procedure InitPreviewControl; override;
78 procedure ClearPreview; virtual;
79 procedure UpdatePreview; virtual;
80 public
81 constructor Create(TheOwner: TComponent); override;
82 procedure DoClose; override;
83 procedure DoSelectionChange; override;
84 procedure DoShow; override;
GetFilterExtnull85 function GetFilterExt: String;
86 property DefaultFilter: string read FDefaultFilter;
87 published
88 property Filter stored IsFilterStored;
89 end;
90
91 { TSavePictureDialog }
92
93 TSavePictureDialog = class(TOpenPictureDialog)
94 protected
95 class procedure WSRegisterClass; override;
DefaultTitlenull96 function DefaultTitle: string; override;
97 public
98 constructor Create(TheOwner: TComponent); override;
99 end;
100
101 { TExtCommonDialog }
102
103 // A common base class for custom drawn dialogs (Calculator and Calendar).
104 TExtCommonDialog = class(TCommonDialog)
105 private
106 FDialogPosition: TPosition;
107 FLeft: Integer;
108 FTop: Integer;
109 FDlgForm: TCustomForm;
110 protected
GetLeftnull111 function GetLeft: Integer; virtual;
GetHeightnull112 function GetHeight: Integer; override;
GetTopnull113 function GetTop: Integer; virtual;
GetWidthnull114 function GetWidth: Integer; override;
115 procedure SetLeft(AValue: Integer); virtual;
116 procedure SetTop(AValue: Integer); virtual;
117 property DlgForm: TCustomForm read FDlgForm write FDlgForm;
118 public
119 constructor Create(AOwner: TComponent); override;
120 destructor Destroy; override;
121 property Left: Integer read GetLeft write SetLeft;
122 property Top: Integer read GetTop write SetTop;
123 published
124 property DialogPosition: TPosition read FDialogPosition write FDialogPosition default poMainFormCenter;
125 end;
126
127 { TCalculatorDialog }
128
129 TCalculatorDialog = class(TExtCommonDialog)
130 private
131 FLayout: TCalculatorLayout;
132 FValue: Double;
133 FMemory: Double;
134 FPrecision: Byte;
135 FBeepOnError: Boolean;
136 FOnChange: TNotifyEvent;
137 FOnCalcKey: TKeyPressEvent;
138 FOnDisplayChange: TNotifyEvent;
139 FDialogScale: integer;
140 FColorBtnDigits,
141 FColorBtnOthers,
142 FColorBtnMemory,
143 FColorBtnOk,
144 FColorBtnCancel,
145 FColorBtnClear,
146 FColorDisplayText,
147 FColorDisplayBack: TColor;
GetDisplaynull148 function GetDisplay: Double;
149 procedure SetDialogScale(AValue: integer);
150 protected
151 class procedure WSRegisterClass; override;
152 procedure OnDialogClose(Sender: TObject; var CloseAction: TCloseAction);
153 procedure OnDialogShow(Sender: TObject);
154 procedure OnDialogCloseQuery(Sender : TObject; var CanClose : boolean);
155 procedure Change; virtual;
156 procedure CalcKey(var Key: char); virtual;
DefaultTitlenull157 function DefaultTitle: string; override;
158 procedure DisplayChange; virtual;
159 public
160 constructor Create(AOwner: TComponent); override;
161 destructor Destroy; override;
Executenull162 function Execute: Boolean; override;
163 property CalcDisplay: Double read GetDisplay;
164 property Memory: Double read FMemory;
165 published
166 property BeepOnError: Boolean read FBeepOnError write FBeepOnError default True;
167 property CalculatorLayout: TCalculatorLayout read FLayout write FLayout default clNormal;
168 property Precision: Byte read FPrecision write FPrecision default CalcDefPrecision;
169 property Title;
170 property Value: Double read FValue write FValue;
171 property OnCalcKey: TKeyPressEvent read FOnCalcKey write FOnCalcKey;
172 property OnChange: TNotifyEvent read FOnChange write FOnChange;
173 property OnDisplayChange: TNotifyEvent read FOnDisplayChange write FOnDisplayChange;
174 property DialogScale: integer read FDialogScale write SetDialogScale default 100;
175 property ColorBtnDigits: TColor read FColorBtnDigits write FColorBtnDigits;
176 property ColorBtnMemory: TColor read FColorBtnMemory write FColorBtnMemory;
177 property ColorBtnOk: TColor read FColorBtnOk write FColorBtnOk;
178 property ColorBtnCancel: TColor read FColorBtnCancel write FColorBtnCancel;
179 property ColorBtnClear: TColor read FColorBtnClear write FColorBtnClear;
180 property ColorBtnOthers: TColor read FColorBtnOthers write FColorBtnOthers;
181 property ColorDisplayText: TColor read FColorDisplayText write FColorDisplayText;
182 property ColorDisplayBack: TColor read FColorDisplayBack write FColorDisplayBack;
183 end;
184
185 { TCalendarDialog }
186
187 TCalendarDialog = class(TExtCommonDialog)
188 private
189 FDate: TDateTime;
190 FDayChanged: TNotifyEvent;
191 FDisplaySettings: TDisplaySettings;
192 FMonthChanged: TNotifyEvent;
193 FYearChanged: TNotifyEvent;
194 FOnChange: TNotifyEvent;
195 FOKCaption: TCaption;
196 FCancelCaption: TCaption;
197 FCalendar: TCalendar;
198 procedure OnDialogClose(Sender: TObject; var CloseAction: TCloseAction);
199 procedure OnDialogCloseQuery(Sender : TObject; var CanClose : boolean);
200 procedure OnDialogShow(Sender: TObject);
201 procedure OnCalendarDayChanged(Sender: TObject);
202 procedure OnCalendarMonthChanged(Sender: TObject);
203 procedure OnCalendarYearChanged(Sender: TObject);
204 procedure OnCalendarChange(Sender: TObject);
205 protected
206 class procedure WSRegisterClass; override;
207 procedure GetNewDate(Sender:TObject);//or onClick
208 procedure CalendarDblClick(Sender: TObject);
DefaultTitlenull209 function DefaultTitle: string; override;
210 public
211 constructor Create(AOwner: TComponent); override;
Executenull212 function Execute: Boolean; override;
213 property Left: Integer read GetLeft write SetLeft;
214 property Top: Integer read GetTop write SetTop;
215 published
216 property Date: TDateTime read FDate write FDate;
217 property DisplaySettings: TDisplaySettings read FDisplaySettings write FDisplaySettings default DefaultDisplaySettings;
218 property OnDayChanged: TNotifyEvent read FDayChanged write FDayChanged;
219 property OnMonthChanged: TNotifyEvent read FMonthChanged write FMonthChanged;
220 property OnYearChanged: TNotifyEvent read FYearChanged write FYearChanged;
221 property OnChange: TNotifyEvent read FOnChange write FOnChange;
222 property OKCaption: TCaption read FOKCaption write FOKCaption;
223 property CancelCaption: TCaption read FCancelCaption write FCancelCaption;
224 end;
225
226 procedure Register;
227
228 implementation
229
230 //no need as buttons don't have glyphs now
231 //{$R lcl_calc_images.res}
232
233 uses
234 WSExtDlgs, Math;
235
236 procedure Register;
237 begin
238 RegisterComponents('Dialogs',[TOpenPictureDialog,TSavePictureDialog,
239 TCalendarDialog,TCalculatorDialog]);
240 end;
241
242 { TPreviewFileControl }
243
244 class procedure TPreviewFileControl.WSRegisterClass;
245 begin
246 inherited WSRegisterClass;
247 RegisterPreviewFileControl;
248 end;
249
250 procedure TPreviewFileControl.SetPreviewFileDialog(
251 const AValue: TPreviewFileDialog);
252 begin
253 if FPreviewFileDialog=AValue then exit;
254 FPreviewFileDialog:=AValue;
255 end;
256
257 procedure TPreviewFileControl.CreateParams(var Params: TCreateParams);
258 begin
259 inherited CreateParams(Params);
260 if Params.WndParent = 0 then
261 Params.Style := Params.Style and not WS_CHILD;
262 end;
263
264 class function TPreviewFileControl.GetControlClassDefaultSize: TSize;
265 begin
266 Result.CX := 200;
267 Result.CY := 200;
268 end;
269
270 constructor TPreviewFileControl.Create(TheOwner: TComponent);
271 begin
272 inherited Create(TheOwner);
273 FCompStyle:=csPreviewFileControl;
274 SetInitialBounds(0, 0, GetControlClassDefaultSize.CX, GetControlClassDefaultSize.CY);
275 end;
276
277 { TPreviewFileDialog }
278
GetPreviewFileControlnull279 function TPreviewFileDialog.GetPreviewFileControl: TPreviewFileControl;
280 begin
281 if not Assigned(fPreviewFileControl) then
282 Self.CreatePreviewControl;
283 Result:=fPreviewFileControl;
284 end;
285
286 class procedure TPreviewFileDialog.WSRegisterClass;
287 begin
288 inherited WSRegisterClass;
289 RegisterPreviewFileDialog;
290 end;
291
292 procedure TPreviewFileDialog.CreatePreviewControl;
293 begin
294 if FPreviewFileControl<>nil then exit;
295 FPreviewFileControl:=TPreviewFileControl.Create(Self);
296 FPreviewFileControl.PreviewFileDialog:=Self;
297 InitPreviewControl;
298 end;
299
300 procedure TPreviewFileDialog.InitPreviewControl;
301 begin
302 FPreviewFileControl.Name:='PreviewFileControl';
303 end;
304
DoExecutenull305 function TPreviewFileDialog.DoExecute: boolean;
306 begin
307 CreatePreviewControl;
308 Result:=inherited DoExecute;
309 end;
310
311 constructor TPreviewFileDialog.Create(TheOwner: TComponent);
312 begin
313 inherited Create(TheOwner);
314 FCompStyle:=csPreviewFileDialog;
315 end;
316
317 { TOpenPictureDialog }
318
319 class procedure TOpenPictureDialog.WSRegisterClass;
320 begin
321 inherited WSRegisterClass;
322 RegisterOpenPictureDialog;
323 end;
324
IsFilterStorednull325 function TOpenPictureDialog.IsFilterStored: Boolean;
326 begin
327 Result := (Filter<>FDefaultFilter);
328 end;
329
330 procedure TOpenPictureDialog.DoClose;
331 begin
332 ClearPreview;
333 inherited DoClose;
334 end;
335
336 procedure TOpenPictureDialog.DoSelectionChange;
337 begin
338 UpdatePreview;
339 inherited DoSelectionChange;
340 end;
341
342 procedure TOpenPictureDialog.DoShow;
343 begin
344 ClearPreview;
345 inherited DoShow;
346 end;
347
348 procedure TOpenPictureDialog.InitPreviewControl;
349 begin
350 inherited InitPreviewControl;
351 FPictureGroupBox.Parent:=PreviewFileControl;
352 end;
353
354 procedure TOpenPictureDialog.ClearPreview;
355 begin
356 FPictureGroupBox.Caption:='None';
357 FImageCtrl.Picture:=nil;
358 end;
359
360 procedure TOpenPictureDialog.UpdatePreview;
361 var
362 CurFilename: String;
363 FileIsValid: boolean;
364 begin
365 CurFilename := FileName;
366 if CurFilename = FPreviewFilename then exit;
367
368 FPreviewFilename := CurFilename;
369 FileIsValid := FileExistsUTF8(FPreviewFilename)
370 and (not DirPathExists(FPreviewFilename))
371 and FileIsReadable(FPreviewFilename);
372 if FileIsValid then
373 try
374 FImageCtrl.Picture.LoadFromFile(FPreviewFilename);
375 FPictureGroupBox.Caption := Format('(%dx%d)',
376 [FImageCtrl.Picture.Width, FImageCtrl.Picture.Height]);
377 except
378 FileIsValid := False;
379 end;
380 if not FileIsValid then
381 ClearPreview;
382 end;
383
384 constructor TOpenPictureDialog.Create(TheOwner: TComponent);
385 begin
386 inherited Create(TheOwner);
387 FDefaultFilter := GraphicFilter(TGraphic)+'|'+
388 Format(rsAllFiles,[GetAllFilesMask, GetAllFilesMask,'']);
389 Filter:=FDefaultFilter;
390
391 FPictureGroupBox:=TGroupBox.Create(Self);
392 with FPictureGroupBox do begin
393 Name:='FPictureGroupBox';
394 Align:=alClient;
395 end;
396
397 FImageCtrl:=TImage.Create(Self);
398 with FImageCtrl do begin
399 Name:='FImageCtrl';
400 Parent:=FPictureGroupBox;
401 Align:=alClient;
402 Center:=true;
403 Proportional:=true;
404 end;
405 end;
406
GetFilterExtnull407 function TOpenPictureDialog.GetFilterExt: String;
408 var
409 ParsedFilter: TParseStringList;
410 begin
411 Result := '';
412
413 ParsedFilter := TParseStringList.Create(Filter, '|');
414 try
415 if (FilterIndex > 0) and (FilterIndex * 2 <= ParsedFilter.Count) then
416 begin
417 Result := AnsiLowerCase(ParsedFilter[FilterIndex * 2 - 1]);
418 // remove *.*
419 if (Result <> '') and (Result[1] = '*') then Delete(Result, 1, 1);
420 if (Result <> '') and (Result[1] = '.') then Delete(Result, 1, 1);
421 if (Result <> '') and (Result[1] = '*') then Delete(Result, 1, 1);
422 // remove all after ;
423 if Pos(';', Result) > 0 then Delete(Result, Pos(';', Result), MaxInt);
424 end;
425
426 if Result = '' then Result := DefaultExt;
427 finally
428 ParsedFilter.Free;
429 end;
430 end;
431
432 { TSavePictureDialog }
433
434 class procedure TSavePictureDialog.WSRegisterClass;
435 begin
436 inherited WSRegisterClass;
437 RegisterSavePictureDialog;
438 end;
439
DefaultTitlenull440 function TSavePictureDialog.DefaultTitle: string;
441 begin
442 Result := rsfdFileSaveAs;
443 end;
444
445 constructor TSavePictureDialog.Create(TheOwner: TComponent);
446 begin
447 inherited Create(TheOwner);
448 fCompStyle:=csSaveFileDialog;
449 end;
450
451 { ---------------------------------------------------------------------
452 Auxiliary
453 ---------------------------------------------------------------------}
454
455 procedure SetDefaultFont(AFont: TFont; Layout: TCalculatorLayout);
456
457 begin
458 with AFont do
459 begin
460 Color := clWindowText;
461 Name := 'MS Sans Serif';
462 Size := 8;
463 Style := [fsBold];
464 end;
465 end;
466
467
468 { TExtCommonDialog }
469
GetLeftnull470 function TExtCommonDialog.GetLeft: Integer;
471 begin
472 if Assigned(FDlgForm) then FLeft := FDlgForm.Left;
473 Result := FLeft;
474 end;
475
GetHeightnull476 function TExtCommonDialog.GetHeight: Integer;
477 begin
478 if Assigned(DlgForm) then
479 Result := DlgForm.Height
480 else
481 Result := inherited GetHeight;
482 end;
483
GetTopnull484 function TExtCommonDialog.GetTop: Integer;
485 begin
486 if Assigned(FDlgForm) then FTop := FDlgForm.Top;
487 Result := FTop;
488 end;
489
GetWidthnull490 function TExtCommonDialog.GetWidth: Integer;
491 begin
492 if Assigned(DlgForm) then
493 Result := DlgForm.Width
494 else
495 Result := inherited GetWidth;
496 end;
497
498 procedure TExtCommonDialog.SetLeft(AValue: Integer);
499 begin
500 if Assigned(FDlgForm) then FDlgForm.Left := AValue;
501 FLeft := AValue;
502 end;
503
504 procedure TExtCommonDialog.SetTop(AValue: Integer);
505 begin
506 if Assigned(FDlgForm) then FDlgForm.Top := AValue;
507 FTop := AValue;
508 end;
509
510 constructor TExtCommonDialog.Create(AOwner: TComponent);
511 begin
512 inherited Create(AOwner);
513 FDialogPosition := poMainFormCenter; // Set the initial location on screen.
514 end;
515
516 destructor TExtCommonDialog.Destroy;
517 begin
518 inherited Destroy;
519 end;
520
521
522 { TCalculatorDialog }
523
524 constructor TCalculatorDialog.Create(AOwner: TComponent);
525 begin
526 inherited Create(AOwner);
527 FPrecision:=CalcDefPrecision;
528 FBeepOnError:=True;
529 FDialogScale:=100;
530 FLayout:=clNormal;
531
532 FColorBtnDigits:=cColorBtnDigits;
533 FColorBtnOthers:=cColorBtnOthers;
534 FColorBtnMemory:=cColorBtnMemory;
535 FColorBtnOk:=cColorBtnOk;
536 FColorBtnCancel:=cColorBtnCancel;
537 FColorBtnClear:=cColorBtnClear;
538 FColorDisplayText:=cColorDisplayText;
539 FColorDisplayBack:=cColorDisplayBack;
540 end;
541
542 destructor TCalculatorDialog.Destroy;
543 begin
544 FOnChange:=nil;
545 FOnDisplayChange:=nil;
546 inherited Destroy;
547 end;
548
549 class procedure TCalculatorDialog.WSRegisterClass;
550 begin
551 inherited WSRegisterClass;
552 RegisterCalculatorDialog;
553 end;
554
555 procedure TCalculatorDialog.OnDialogClose(Sender: TObject;
556 var CloseAction: TCloseAction);
557 begin
558 DoClose;
559 end;
560
561 procedure TCalculatorDialog.OnDialogShow(Sender: TObject);
562 begin
563 DoShow;
564 end;
565
566 procedure TCalculatorDialog.OnDialogCloseQuery(Sender: TObject;
567 var CanClose: boolean);
568 begin
569 UserChoice := DlgForm.ModalResult;
570 DoCanClose(CanClose);
571 end;
572
GetDisplaynull573 function TCalculatorDialog.GetDisplay: Double;
574 begin
575 if Assigned(DlgForm) then
576 Result:=TCalculatorForm(DlgForm).CalcPanel.DisplayValue
577 else Result:=FValue;
578 end;
579
580 procedure TCalculatorDialog.SetDialogScale(AValue: integer);
581 const
582 cMinSize = 80;
583 cMaxSize = 400;
584 begin
585 if FDialogScale=AValue then Exit;
586 FDialogScale:=Max(cMinSize, Min(cMaxSize, AValue));
587 end;
588
589 procedure TCalculatorDialog.CalcKey(var Key: char);
590 begin
591 if Assigned(FOnCalcKey) then FOnCalcKey(Self, Key);
592 end;
593
DefaultTitlenull594 function TCalculatorDialog.DefaultTitle: string;
595 begin
596 Result := rsCalculator;
597 end;
598
599 procedure TCalculatorDialog.DisplayChange;
600 begin
601 if Assigned(FOnDisplayChange) then FOnDisplayChange(Self);
602 end;
603
604
605 procedure TCalculatorDialog.Change;
606 begin
607 if Assigned(FOnChange) then FOnChange(Self);
608 end;
609
Executenull610 function TCalculatorDialog.Execute: Boolean;
611 var
612 CPanel: TCalculatorPanel;
613 begin
614 cColorBtnDigits:=FColorBtnDigits;
615 cColorBtnOthers:=FColorBtnOthers;
616 cColorBtnMemory:=FColorBtnMemory;
617 cColorBtnOk:=FColorBtnOk;
618 cColorBtnCancel:=FColorBtnCancel;
619 cColorBtnClear:=FColorBtnClear;
620 cColorDisplayText:=FColorDisplayText;
621 cColorDisplayBack:=FColorDisplayBack;
622
623 DlgForm:=CreateCalculatorForm(Application, FLayout, HelpContext);
624 try
625 ResetShowCloseFlags;
626 (DlgForm as TCalculatorForm).OnCalcKey:= @Self.CalcKey;
627 (DlgForm as TCalculatorForm).OnDisplayChange:= @Self.DisplayChange;
628 (DlgForm as TCalculatorForm).OnShow := @Self.OnDialogShow;
629 (DlgForm as TCalculatorForm).OnClose := @Self.OnDialogClose;
630 (DlgForm as TCalculatorForm).OnCloseQuery :=@Self.OnDialogCloseQuery;
631
632 if FDialogScale<>100 then
633 DlgForm.ScaleBy(FDialogScale,100);
634 if (csDesigning in ComponentState) then
635 DlgForm.Position:=poScreenCenter
636 else
637 DlgForm.Position:=DialogPosition;
638 if (DlgForm.Position=poDesigned) then begin
639 DlgForm.Left:=FLeft;
640 DlgForm.Top:=FTop;
641 end else begin
642 FLeft:=DlgForm.Left;
643 FTop:=DlgForm.Top;
644 end;
645 CPanel:=TCalculatorForm(DlgForm).CalcPanel;
646
647 DlgForm.Caption:=Title;
648 CPanel.Memory:=FMemory;
649 CPanel.UpdateMemoryLabel;
650 If Precision>2 then
651 CPanel.Precision:=Precision
652 else
653 CPanel.Precision:=2;
654 CPanel.BeepOnError:=BeepOnError;
655 if FValue <> 0 then begin
656 CPanel.DisplayValue:=FValue;
657 CPanel.Status:=csFirst;
658 CPanel.OperatorChar:='=';
659 end;
660 Result := (DlgForm.ShowModal = mrOk);
661 FLeft := DlgForm.Left;
662 FTop := DlgForm.Top;
663 //update private fields FHeight and FWidth of ancestor
664 SetHeight(DlgForm.Height);
665 SetWidth(DlgForm.Width);
666 if Result then begin
667 FMemory:=CPanel.Memory;
668 if CPanel.DisplayValue <> FValue then begin
669 FValue:=CPanel.DisplayValue;
670 Change;
671 end;
672 end;
673 finally
674 DlgForm.Free;
675 DlgForm:=nil;
676 end;
677 end;
678
679
680 { ---------------------------------------------------------------------
681 TCalendarDialog
682 ---------------------------------------------------------------------}
683
684 { TCalendarDialog }
685
686 constructor TCalendarDialog.Create(AOwner: TComponent);
687 begin
688 inherited Create(AOwner);
689 DisplaySettings := DefaultDisplaySettings;
690 Date := trunc(Now);
691 OKCaption := rsMbOK;
692 CancelCaption := rsMbCancel;
693 end;
694
695 procedure TCalendarDialog.GetNewDate(Sender:TObject);//or onClick
696 begin
697 Date:=FCalendar.DateTime;
698 end;
699
700 procedure TCalendarDialog.CalendarDblClick(Sender: TObject);
701 var
702 CalendarForm: TForm;
703 P: TPoint;
704 htRes: TCalendarPart;
705 begin
706 P := FCalendar.ScreenToClient(Mouse.CursorPos);
707 //if FCalendar.HitTest(P) in [cpNoWhere, cpDate] then
708 htRes := FCalendar.HitTest(P);
709 if {(htRes = cpNoWhere) or }((htRes = cpDate) and (FCalendar.GetCalendarView = cvMonth)) then
710 begin
711 GetNewDate(Sender);
712 CalendarForm:=TForm(TComponent(Sender).Owner);
713 // close the calendar dialog
714 CalendarForm.ModalResult:=mrOk;
715 end;
716 end;
717
DefaultTitlenull718 function TCalendarDialog.DefaultTitle: string;
719 begin
720 Result := rsPickDate;
721 end;
722
723 procedure TCalendarDialog.OnDialogClose(Sender: TObject;
724 var CloseAction: TCloseAction);
725 begin
726 //if Assigned(OnClose) then OnClose(Self);
727 DoClose;
728 end;
729
730 procedure TCalendarDialog.OnDialogCloseQuery(Sender: TObject;
731 var CanClose: boolean);
732 begin
733 //if Assigned(OnCanClose) then OnCanClose(Sender, CanClose);
734 if DlgForm.ModalResult = mrOK then
735 UserChoice := mrOk
736 else
737 UserChoice := mrCancel;
738 DoCanClose(CanClose);
739 end;
740
741 procedure TCalendarDialog.OnDialogShow(Sender: TObject);
742 begin
743 DoShow;
744 end;
745
746 procedure TCalendarDialog.OnCalendarDayChanged(Sender: TObject);
747 begin
748 GetNewDate(Self);
749 if Assigned(FDayChanged) then FDayChanged(Self);
750 end;
751
752 procedure TCalendarDialog.OnCalendarMonthChanged(Sender: TObject);
753 begin
754 GetNewDate(Self);
755 if Assigned(FMonthChanged) then FMonthChanged(Self);
756 end;
757
758 procedure TCalendarDialog.OnCalendarYearChanged(Sender: TObject);
759 begin
760 GetNewDate(Self);
761 if Assigned(FYearChanged) then FYearChanged(Self);
762 end;
763
764 procedure TCalendarDialog.OnCalendarChange(Sender: TObject);
765 begin
766 //Date already updated in OnCalendarXXXChanged
767 if Assigned(FOnChange) then FOnChange(Self);
768 end;
769
770
771 class procedure TCalendarDialog.WSRegisterClass;
772 begin
773 inherited WSRegisterClass;
774 RegisterCalendarDialog;
775 end;
776
Executenull777 function TCalendarDialog.Execute:boolean;
778 const
779 dw=8;
780 bbs=2;
781 var
782 okButton,cancelButton: TButton;
783 panel: TPanel;
784 begin
785 DlgForm:=TForm.CreateNew(Application, 0);
786 try
787 ResetShowCloseFlags;
788 DlgForm.DisableAlign;
789 DlgForm.Caption:=Title;
790 if (csDesigning in ComponentState) then
791 DlgForm.Position:=poScreenCenter
792 else
793 DlgForm.Position:=DialogPosition;
794 if (DlgForm.Position=poDesigned) then begin
795 DlgForm.Left:=FLeft;
796 DlgForm.Top:=FTop;
797 end else begin
798 FLeft:=DlgForm.Left;
799 FTop:=DlgForm.Top;
800 end;
801 DlgForm.BorderStyle:=bsDialog;
802 DlgForm.AutoScroll:=false;
803 DlgForm.AutoSize:=true;
804 DlgForm.OnShow := @OnDialogShow;
805 DlgForm.OnClose:=@OnDialogClose;
806 DlgForm.OnCloseQuery:=@OnDialogCloseQuery;
807
808 FCalendar:=TCalendar.Create(DlgForm);
809 with FCalendar do begin
810 Parent:=DlgForm;
811 Align:=alTop;
812 DateTime:=Self.Date;
813 TabStop:=True;
814 DisplaySettings:=Self.DisplaySettings;
815 OnDayChanged:=@Self.OnCalendarDayChanged;
816 OnMonthChanged:=@Self.OnCalendarMonthChanged;
817 OnYearChanged:=@Self.OnCalendarYearChanged;
818 OnChange:=@Self.OnCalendarChange;
819 OnDblClick:=@CalendarDblClick;
820 end;
821
822 panel:=TPanel.Create(DlgForm);
823 with panel do begin
824 Parent:=DlgForm;
825 Caption:='';
826 Height:=32;
827 AnchorToCompanion(akTop, 0, FCalendar);
828 BevelOuter:=bvLowered;
829 end;
830
831 okButton:=TButton.Create(DlgForm);
832 with okButton do begin
833 Parent:=panel;
834 Caption:=OKCaption;
835 Constraints.MinWidth:=75;
836 Constraints.MaxWidth:=FCalendar.Width div 2 - bbs;
837 Width:=DlgForm.Canvas.TextWidth(OKCaption)+2*dw;
838 ModalResult:=mrOK;
839 OnClick:=@GetNewDate;
840 //Align:=alRight;
841 Anchors := [akTop,akRight];
842 BorderSpacing.Right:=bbs;
843 AnchorSide[akRight].Side:=asrRight;
844 AnchorSide[akRight].Control:=panel;
845 AnchorVerticalCenterTo(panel);
846 Default:=True;
847 end;
848
849 cancelButton:=TButton.Create(DlgForm);
850 with cancelButton do begin
851 Parent:=panel;
852 Caption:=CancelCaption;
853 Constraints.MinWidth:=75;
854 Constraints.MaxWidth:=FCalendar.Width div 2;
855 Width:=DlgForm.Canvas.TextWidth(CancelCaption)+2*dw;;
856 ModalResult:=mrCancel;
857 //Align:=alLeft;
858 BorderSpacing.Left:=bbs;
859 Anchors:=[akLeft,akTop];
860 AnchorSide[akLeft].Side:=asrLeft;
861 AnchorSide[akLeft].Control:=panel;
862 AnchorVerticalCenterTo(panel);
863 Cancel:=True;
864 end;
865 DlgForm.ClientWidth := FCalendar.Width;
866 DlgForm.ClientHeight := panel.Top+panel.Height;
867
868 DlgForm.EnableAlign;
869 Result:=DlgForm.ShowModal=mrOK;
870 FLeft:=DlgForm.Left;
871 FTop:=DlgForm.Top;
872 //update private fields FHeight and FWidth of ancestor
873 SetHeight(DlgForm.Height);
874 SetWidth(DlgForm.Width);
875 finally
876 DlgForm.Free;
877 DlgForm := nil;
878 end;
879 end;
880
881
882 end.
883