This was not enough for me and I wrote a new DateGadget. This must be explicitly deleted with FreeDateGadget to release all resources.
Update v1.02.1
- Fix calendar position
MyDateGadget
Code: Select all
;-TOP
; Comment : MyDateGadget (Big Date Range)
; Author : mk-soft
; Version : v1.02.1
; create : 21.03.2021
; Update :
;
; OS : macOS
; *******
EnableExplicit
;- MacOS Date funtions
; Mask:
; Year = yyyy
; Month = MM (1..12), MMM (Short Name), MMMM (Long Name)
; Day = dd
; Hour = hh (0..23), HH (0..11); a = period (AM, PM)
; Minute = mm
; Second = ss
;
; Day ot the year = DDD (1..3)
; Week of Year = ww
; Week of Month = W
Macro CocoaString(NSString)
PeekS(CocoaMessage(0, NSString, "UTF8String"), -1, #PB_UTF8)
EndMacro
Procedure.s GetStringFromDate(Date, Mask.s = "yyyy-MM-dd")
Protected NSPool, NSDateFormatter, NSString
Protected r1.s
NSPool = CocoaMessage(0, 0, "NSAutoreleasePool new")
NSDateFormatter = CocoaMessage(0, 0, "NSDateFormatter new")
; Convert PB date format
If FindString(Mask, "%")
mask = LCase(mask)
mask = ReplaceString(mask, "m", "M")
mask = ReplaceString(mask, "i", "m")
mask = RemoveString(mask, "%")
EndIf
If Date = 0
Date = CocoaMessage(0, 0, "NSDate date")
EndIf
CocoaMessage(0, NSDateFormatter, "setDateFormat:$", @Mask)
NSString = CocoaMessage(0, NSDateFormatter, "stringFromDate:@", @Date)
r1 = CocoaString(NSString)
CocoaMessage(0, NSDateFormatter, "release")
CocoaMessage(0, NSPool, "release")
ProcedureReturn r1
EndProcedure
Procedure GetDateFromString(Date.s, Mask.s = "yyyy-MM-dd")
Protected NSPool, NSDate, NSDateFormatter
Protected r1
NSPool = CocoaMessage(0, 0, "NSAutoreleasePool new")
NSDateFormatter = CocoaMessage(0, 0, "NSDateFormatter new")
; Convert PB date format
If FindString(Mask, "%")
mask = LCase(mask)
mask = ReplaceString(mask, "m", "M")
mask = ReplaceString(mask, "i", "m")
mask = RemoveString(mask, "%")
EndIf
CocoaMessage(0, NSDateFormatter, "setDateFormat:$", @Mask)
r1 = CocoaMessage(0, NSDateFormatter, "dateFromString:$", @Date)
CocoaMessage(0, NSDateFormatter, "release")
CocoaMessage(0, NSPool, "release")
ProcedureReturn r1
EndProcedure
; ----
Structure udtMyDateGadget
Gadget.i
Button.i
Calendar.i
Mask.s
EndStructure
;- Events
Procedure MyDateGadget_CalendarEvent()
Protected *Data.udtMyDateGadget
Protected date
Static click
With *Data
click + 1
If click >= 3
*Data.udtMyDateGadget = GetGadgetData(EventGadget())
date = CocoaMessage(0, GadgetID(\Calendar), "dateValue")
SetGadgetText(\Gadget, GetStringFromDate(date, \Mask))
FreeGadget(\Calendar)
\Calendar = 0
click = 0
EndIf
EndWith
EndProcedure
Procedure MyDateGadget_ButtonEvent()
Protected *Data.udtMyDateGadget
Protected NSCurrentLocale, NSLocale, NSString
Protected button, x, y, dx, dy, date
button = EventGadget()
*Data.udtMyDateGadget = GetGadgetData(button)
With *Data
If \Calendar
FreeGadget(\Calendar)
\Calendar = 0
Else
\Calendar = CalendarGadget(#PB_Any, GadgetX(\Gadget), GadgetY(\Gadget) + GadgetHeight(\Gadget), 0, 0)
; Set Language
NSCurrentLocale = CocoaMessage(0, 0, "NSLocale currentLocale")
NSString = CocoaMessage(0, NSCurrentLocale, "localeIdentifier")
If CocoaString(NSString) = "en_DE"
NSLocale = CocoaMessage(0, 0, "NSLocale localeWithLocaleIdentifier:$", @"de_DE")
Else
NSLocale = NSCurrentLocale
EndIf
CocoaMessage(0, GadgetID(\Calendar), "setLocale:", NSLocale)
; Resize Gadget
dx = GadgetWidth(\Calendar, #PB_Gadget_RequiredSize)
dy = GadgetHeight(\Calendar, #PB_Gadget_RequiredSize)
x = GadgetX(\Gadget) + GadgetWidth(\Gadget) + GadgetWidth(\Button) - dx
ResizeGadget(\Calendar, x, #PB_Ignore, dx, dy)
; Set date
date = GetDateFromString(GetGadgetText(\Gadget), \Mask)
CocoaMessage(0, GadgetID(\Calendar), "setDateValue:", date)
SetGadgetData(\Calendar, *Data)
; Bind Event
BindGadgetEvent(\Calendar, @MyDateGadget_CalendarEvent())
EndIf
EndWith
EndProcedure
;- Create DateGadget
Procedure MyDateGadget(Gadget, x, y, Width, Height, Mask.s = "YYYY-MM-dd", Date = 0)
Protected id, *Data.udtMyDateGadget
With *Data
id = StringGadget(Gadget, x, y, Width - Height * 1.5, Height, "")
If id
; allocate data
*Data = AllocateStructure(udtMydateGadget)
If Gadget = #PB_Any
\Gadget = id
Else
\Gadget = Gadget
EndIf
SetGadgetData(\Gadget, *Data)
\Mask = Mask
SetGadgetText(\Gadget, GetStringFromDate(Date, \Mask))
; Create button for open calendar
\Button = ButtonGadget(#PB_Any, x + Width - Height * 1.5, y + 2, Height * 1.5, Height, ">")
SetGadgetData(\Button, *Data)
; Bind events
BindGadgetEvent(\Button, @MyDateGadget_ButtonEvent(), #PB_EventType_LeftClick)
EndIf
EndWith
ProcedureReturn id
EndProcedure
;- Free DateGadget
Procedure FreeDateGadget(Gadget)
Protected *Data.udtMyDateGadget
With *Data
*Data = GetGadgetData(Gadget)
If *Data
If IsGadget(\Calendar) : FreeGadget(\Calendar) : EndIf
If IsGadget(\Button) : FreeGadget(\Button) : EndIf
If IsGadget(\Gadget) : FreeGadget(\Gadget) : EndIf
EndIf
FreeStructure(*Data)
EndWith
EndProcedure
; ********
;-Example
CompilerIf #PB_Compiler_IsMainFile
Define Date
If OpenWindow(0, 0, 0, 250, 250, "DateGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Date = GetDateFromString("1965-08-20")
MyDateGadget(0, 10, 10, 220, 25, "%dd.%mm.%yyyy", Date)
;MyDateGadget(0, 10, 10, 180, 25, "dd. MMM yyyy", Date)
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
CompilerEndIf