{ ***************************************************************************** * Gtk3WSCalendar.pp * * ----------------- * * * * * ***************************************************************************** ***************************************************************************** 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. ***************************************************************************** } unit Gtk3WSCalendar; {$mode objfpc}{$H+} {$I gtk3defines.inc} interface uses // Bindings LazGlib2, LazGdk3, LazGtk3, // RTL, FCL, LCL SysUtils, Types, Classes, Controls, Calendar, LCLType, LMessages, InterfaceBase, LCLProc, // Widgetset WSCalendar, WSLCLClasses, WSProc; type { TGtk2WSCalendar } { TGtk3WSCustomCalendar } TGtk3WSCustomCalendar = class(TWSCustomCalendar) protected published class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override; class function GetDateTime(const ACalendar: TCustomCalendar): TDateTime; override; class function HitTest(const ACalendar: TCustomCalendar; const APoint: TPoint): TCalendarPart; override; class procedure SetDateTime(const ACalendar: TCustomCalendar; const ADateTime: TDateTime); override; class procedure SetDisplaySettings(const ACalendar: TCustomCalendar; const ADisplaySettings: TDisplaySettings); override; (* class procedure GetPreferredSize(const AWinControl: TWinControl; var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); override; *) end; implementation uses gtk3widgets; (* use private from gtk3 unit type TGtkCalendarPrivate = record header_win: PGdkWindow; day_name_win: PGdkWindow; main_win: PGdkWindow; week_win: PGdkWindow; arrow_win: array[0..3] of PGdkWindow; header_h: guint; day_name_h: guint; main_h: guint; arrow_state: array[0..3] of guint; arrow_width: guint; max_month_width: guint; max_year_width: guint; day_width: guint; week_width: guint; min_day_width: guint; max_day_char_width: guint; max_day_char_ascent: guint; max_day_char_descent: guint; max_label_char_ascent: guint; max_label_char_descent: guint; max_week_char_width: guint; end; PGtkCalendarPrivate = ^TGtkCalendarPrivate; *) { TGtk3WSCustomCalendar } (* class procedure TGtk3WSCustomCalendar.SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); begin TGtk2WSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject)); with TGtk2Widgetset(Widgetset) do begin SetCallback(LM_MONTHCHANGED, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject); SetCallback(LM_YEARCHANGED, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject); SetCallback(LM_DAYCHANGED, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject); end; g_signal_handlers_disconnect_by_func(PGtkObject(AWidgetInfo^.CoreWidget), TGTKSignalFunc(@GtkDragDataReceived), AWidgetInfo^.LCLObject); end; class function TGtk3WSCustomCalendar.GetCalendar(const ACalendar: TCustomCalendar): PGtkCalendar; //inline; begin Result := PGtkCalendar(GetWidgetInfo({%H-}PGtkWidget(ACalendar.Handle))^.CoreWidget); end; *) class function TGtk3WSCustomCalendar.CreateHandle( const AWinControl: TWinControl; const AParams: TCreateParams ): TLCLIntfHandle; (* var FrameWidget, CalendarWidget: PGtkWidget; WidgetInfo: PWidgetInfo; Allocation: TGtkAllocation; Requisition: TGtkRequisition; *) begin Result := TLCLIntfHandle(TGtk3Calendar.Create(AWinControl, AParams)); (* FrameWidget := gtk_frame_new(nil); CalendarWidget := gtk_calendar_new(); gtk_container_add(PGtkContainer(FrameWidget), CalendarWidget); gtk_widget_show_all(FrameWidget); // if we don't request it - we have a SIGFPE sometimes gtk_widget_size_request(CalendarWidget, @Requisition); Result := TLCLIntfHandle({%H-}PtrUInt(FrameWidget)); {$IFDEF DebugLCLComponents} DebugGtkWidgets.MarkCreated(FrameWidget, dbgsName(AWinControl)); {$ENDIF} WidgetInfo := CreateWidgetInfo(FrameWidget, AWinControl, AParams); WidgetInfo^.CoreWidget := CalendarWidget; SetMainWidget(FrameWidget, CalendarWidget); Allocation.X := AParams.X; Allocation.Y := AParams.Y; Allocation.Width := AParams.Width; Allocation.Height := AParams.Height; gtk_widget_size_allocate({%H-}PGtkWidget(Result), @Allocation); Set_RC_Name(AWinControl, FrameWidget); SetCallBacks(FrameWidget, WidgetInfo); *) end; class function TGtk3WSCustomCalendar.GetDateTime(const ACalendar: TCustomCalendar): TDateTime; var Year, Month, Day: Word; //used for csCalendar begin Result := 0; if not WSCheckHandleAllocated(ACalendar, 'GetDateTime') then Exit; TGtk3Calendar(ACalendar.Handle).GetDate(Year, Month, Day); DebugLn('TGtk3WSCustomCalendar.GetDateTime: Yr=',dbgs(Year),' Mo=',dbgs(Month),' Dy=',dbgs(Day)); // gtk_calendar_get_date(GetCalendar(ACalendar), @Year, @Month, @Day); //For some reason, the month is zero based. Result := EncodeDate(Year, Month + 1, Day); end; class function TGtk3WSCustomCalendar.HitTest(const ACalendar: TCustomCalendar; const APoint: TPoint): TCalendarPart; (* var GtkCalendar: PGtkCalendar; Style: PGtkStyle; FrameW, FrameH, BodyY, BodyX, DayH, ArrowW: Integer; Options: TGtkCalendarDisplayOptions; R: TRect; *) begin Result := cpNoWhere; if not WSCheckHandleAllocated(ACalendar, 'HitTest') then Exit; (* GtkCalendar := GetCalendar(ACalendar); Style := gtk_widget_get_style({%H-}PGtkWidget(ACalendar.Handle)); FrameW := gtk_widget_get_xthickness(Style); FrameH := gtk_widget_get_Ythickness(Style); Options := gtk_calendar_get_display_options(GtkCalendar); if Ord(Options) and Ord(GTK_CALENDAR_SHOW_HEADING) <> 0 then BodyY := PGtkCalendarPrivate(GtkCalendar^.private_data)^.header_h else BodyY := 0; if Ord(Options) and Ord(GTK_CALENDAR_SHOW_WEEK_NUMBERS) <> 0 then BodyX := PGtkCalendarPrivate(GtkCalendar^.private_data)^.week_width else BodyX := 0; if APoint.Y >= BodyY + FrameH then begin // we are in the body if Ord(Options) and Ord(GTK_CALENDAR_SHOW_DAY_NAMES) <> 0 then DayH := PGtkCalendarPrivate(GtkCalendar^.private_data)^.day_name_h else DayH := 0; if (APoint.Y - BodyY - DayH - FrameH >= 0) then begin if APoint.X >= BodyX + FrameW then Result := cpDate else Result := cpWeekNumber; end; end else if BodyY > 0 then begin Result := cpTitle; // we are in the header at least ArrowW := PGtkCalendarPrivate(GtkCalendar^.private_data)^.arrow_width; R.Top := 3 + FrameH; R.Bottom := BodyY - 7 + FrameH; R.Left := 3 + FrameW; // check month + buttons R.Right := R.Left + ArrowW + 1; if PtInRect(R, APoint) then Exit(cpTitleBtn); R.Left := R.Right + 1; R.Right := FrameW + ArrowW + integer(PGtkCalendarPrivate(GtkCalendar^.private_data)^.max_month_width) + 1; if PtInRect(R, APoint) then Exit(cpTitleMonth); R.Left := R.Right; R.Right := R.Left + ArrowW; if PtInRect(R, APoint) then Exit(cpTitleBtn); // check year + buttons Style := gtk_widget_get_style(PGtkWidget(GtkCalendar)); R.Right := PGtkWidget(GtkCalendar)^.allocation.width - 3 - 2 * gtk_widget_get_xthickness(Style) + FrameW + 1; R.Left := R.Right - ArrowW; if PtInRect(R, APoint) then Exit(cpTitleBtn); R.Right := R.Left; R.Left := R.Right - PGtkCalendarPrivate(GtkCalendar^.private_data)^.max_year_width; if PtInRect(R, APoint) then Exit(cpTitleYear); R.Right := R.Left; R.Left := R.Right - ArrowW; if PtInRect(R, APoint) then Exit(cpTitleBtn); end; *) end; class procedure TGtk3WSCustomCalendar.SetDateTime(const ACalendar: TCustomCalendar; const ADateTime: TDateTime); var Year, Month, Day: Word; GtkCalendar: PGtkCalendar; begin if not WSCheckHandleAllocated(ACalendar, 'SetDateTime') then Exit; // GtkCalendar := GetCalendar(ACalendar); Year := StrToInt(FormatDateTime('yyyy', ADateTime)); Month := StrToInt(FormatDateTime('mm', ADateTime)); Day := StrToInt(FormatDateTime('dd', ADateTime)); TGtk3Calendar(ACalendar.Handle).SetDate(Year, Month, Day); // gtk_calendar_select_month(GtkCalendar, StrtoInt(Month) - 1, StrToInt(Year)); // gtk_calendar_select_day(GtkCalendar, StrToInt(Day)); end; class procedure TGtk3WSCustomCalendar.SetDisplaySettings(const ACalendar: TCustomCalendar; const ADisplaySettings: TDisplaySettings); var num: dword; // gtkcalendardisplayoptions : TGtkCalendarDisplayOptions; begin if not WSCheckHandleAllocated(ACalendar, 'SetDisplaySettings') then Exit; num := 0; if (dsShowHeadings in ADisplaySettings) then num := Num or $01; if (dsShowDayNames in ADisplaySettings) then num := Num or $02; if (dsNoMonthChange in ADisplaySettings) then num := Num or $04; if (dsShowWeekNumbers in ADisplaySettings) then num := Num or $08; if (dsStartMonday in ADisplaySettings) then num := Num or $20; TGtk3Calendar(ACalendar.Handle).setDisplayOptions(TGtkCalendarDisplayOptions(num)); end; (* class procedure TGtk3WSCustomCalendar.GetPreferredSize( const AWinControl: TWinControl; var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); begin GetGTKDefaultWidgetSize(AWinControl, PreferredWidth, PreferredHeight, WithThemeSpace); end; *) end.