mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 09:18:02 +02:00
194 lines
5.5 KiB
ObjectPascal
194 lines
5.5 KiB
ObjectPascal
{ $Id$}
|
|
{
|
|
*****************************************************************************
|
|
This file is part of the Lazarus Component Library (LCL)
|
|
|
|
See the file COPYING.modifiedLGPL.txt, included in this distribution,
|
|
for details about the license.
|
|
*****************************************************************************
|
|
|
|
Author: Vincent Snijders
|
|
|
|
Abstract:
|
|
Shows a non-modal calendar popup for a TDateEdit
|
|
}
|
|
|
|
unit CalendarPopup;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Calendar, LCLProc, LCLType;
|
|
|
|
type
|
|
TReturnDateEvent = procedure (Sender: TObject; const Date: TDateTime) of object;
|
|
|
|
{ TCalendarPopupForm }
|
|
|
|
TCalendarPopupForm = class(TForm)
|
|
Calendar: TCalendar;
|
|
procedure CalendarDblClick(Sender: TObject);
|
|
procedure CalendarKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure FormDeactivate(Sender: TObject);
|
|
private
|
|
FCaller: TControl;
|
|
FClosed: boolean;
|
|
FOnReturnDate: TReturnDateEvent;
|
|
procedure Initialize(ADate: TDateTime;
|
|
const DisplaySettings: TDisplaySettings;
|
|
AMinDate, AMaxDate: TDateTime);
|
|
procedure KeepInView(const PopupOrigin: TPoint);
|
|
procedure ReturnDate;
|
|
end;
|
|
|
|
procedure ShowCalendarPopup(const APosition: TPoint; ADate: TDateTime;
|
|
const CalendarDisplaySettings: TDisplaySettings;
|
|
AMinDate, AMaxDate: TDateTime;
|
|
const OnReturnDate: TReturnDateEvent; const OnShowHide: TNotifyEvent = nil;
|
|
ACaller: TControl = nil);
|
|
|
|
procedure ShowCalendarPopup(const APosition: TPoint; ADate: TDateTime;
|
|
const CalendarDisplaySettings: TDisplaySettings;
|
|
const OnReturnDate: TReturnDateEvent; const OnShowHide: TNotifyEvent = nil;
|
|
ACaller: TControl = nil);
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
|
|
procedure ShowCalendarPopup(const APosition: TPoint; ADate: TDateTime;
|
|
const CalendarDisplaySettings: TDisplaySettings;
|
|
AMinDate, AMaxDate: TDateTime;
|
|
const OnReturnDate: TReturnDateEvent; const OnShowHide: TNotifyEvent;
|
|
ACaller: TControl);
|
|
var
|
|
PopupForm: TCalendarPopupForm;
|
|
begin
|
|
PopupForm := TCalendarPopupForm.Create(nil);
|
|
PopupForm.FCaller := ACaller;
|
|
PopupForm.Initialize(ADate, CalendarDisplaySettings, AMinDate, AMaxDate);
|
|
PopupForm.FOnReturnDate := OnReturnDate;
|
|
PopupForm.OnShow := OnShowHide;
|
|
PopupForm.OnHide := OnShowHide;
|
|
PopupForm.Show;
|
|
PopupForm.KeepInView(APosition); // must be after Show for PopupForm.AutoSize to be in effect.
|
|
end;
|
|
|
|
procedure ShowCalendarPopup(const APosition: TPoint; ADate: TDateTime;
|
|
const CalendarDisplaySettings: TDisplaySettings;
|
|
const OnReturnDate: TReturnDateEvent; const OnShowHide: TNotifyEvent = nil;
|
|
ACaller: TControl = nil);
|
|
begin
|
|
ShowCalendarPopup(APosition, ADate, CalendarDisplaySettings, 0.0, 0.0, OnReturnDate, OnShowHide, Acaller)
|
|
end;
|
|
|
|
{ TCalendarPopupForm }
|
|
|
|
procedure TCalendarPopupForm.FormCreate(Sender: TObject);
|
|
begin
|
|
FClosed := false;
|
|
Application.AddOnDeactivateHandler(@FormDeactivate);
|
|
end;
|
|
|
|
procedure TCalendarPopupForm.FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
|
begin
|
|
//DebugLn(['TCalendarPopupForm.FormClose ']);
|
|
FClosed := true;
|
|
Application.RemoveOnDeactivateHandler(@FormDeactivate);
|
|
CloseAction := caFree;
|
|
end;
|
|
|
|
procedure TCalendarPopupForm.CalendarDblClick(Sender: TObject);
|
|
var
|
|
P: TPoint;
|
|
htRes: TCalendarPart;
|
|
begin
|
|
P := Calendar.ScreenToClient(Mouse.CursorPos);
|
|
htRes := Calendar.HitTest(P);
|
|
if {(htRes = cpNoWhere) or }((htRes = cpDate) and (Calendar.GetCalendarView = cvMonth)) then
|
|
ReturnDate;
|
|
end;
|
|
|
|
procedure TCalendarPopupForm.CalendarKeyDown(Sender: TObject; var Key: Word;
|
|
Shift: TShiftState);
|
|
var
|
|
Handled: Boolean;
|
|
begin
|
|
if Shift=[] then
|
|
begin
|
|
Handled := true;
|
|
case Key of
|
|
VK_ESCAPE:
|
|
Close;
|
|
VK_RETURN, VK_SPACE:
|
|
if (Calendar.GetCalendarView = cvMonth) then
|
|
ReturnDate
|
|
else
|
|
Handled := False;
|
|
else
|
|
Handled := false;
|
|
end;
|
|
if Handled then
|
|
Key := 0;
|
|
end;
|
|
end;
|
|
|
|
procedure TCalendarPopupForm.FormDeactivate(Sender: TObject);
|
|
begin
|
|
//DebugLn(['TCalendarPopupForm.FormDeactivate ',DbgSName(GetCaptureControl)]);
|
|
//Immediately hide the form, otherwise it stays visible while e.g. user is draging
|
|
//another form (Issue #0020647)
|
|
Hide;
|
|
if (not FClosed) then
|
|
Close;
|
|
end;
|
|
|
|
procedure TCalendarPopupForm.Initialize(ADate: TDateTime;
|
|
const DisplaySettings: TDisplaySettings; AMinDate, AMaxDate: TDateTime);
|
|
begin
|
|
Calendar.DateTime := ADate;
|
|
Calendar.DisplaySettings:=DisplaySettings;
|
|
Calendar.MinDate := AMinDate;
|
|
Calendar.MaxDate := AMaxDate;
|
|
end;
|
|
|
|
procedure TCalendarPopupForm.KeepInView(const PopupOrigin: TPoint);
|
|
var
|
|
ABounds: TRect;
|
|
P: TPoint;
|
|
begin
|
|
ABounds := Screen.MonitorFromPoint(PopupOrigin).WorkAreaRect; // take care of taskbar
|
|
if PopupOrigin.X + Width > ABounds.Right then
|
|
Left := ABounds.Right - Width
|
|
else if PopupOrigin.X < ABounds.Left then
|
|
Left := ABounds.Left
|
|
else
|
|
Left := PopupOrigin.X;
|
|
if PopupOrigin.Y + Height > ABounds.Bottom then
|
|
begin
|
|
if Assigned(FCaller) then
|
|
Top := PopupOrigin.Y - FCaller.Height - Height
|
|
else
|
|
Top := ABounds.Bottom - Height;
|
|
end else if PopupOrigin.Y < ABounds.Top then
|
|
Top := ABounds.Top
|
|
else
|
|
Top := PopupOrigin.Y;
|
|
if Left < ABounds.Left then Left := 0;
|
|
if Top < ABounds.Top then Top := 0;
|
|
end;
|
|
|
|
procedure TCalendarPopupForm.ReturnDate;
|
|
begin
|
|
if Assigned(FOnReturnDate) then
|
|
FOnReturnDate(Self, Calendar.DateTime);
|
|
if not FClosed then
|
|
Close;
|
|
end;
|
|
|
|
end.
|