UNPKG

nativescript-ui-calendar

Version:

Month, year, week and day views. Single, multiple and range date Selection. Special and disabled dates.

1,177 lines 71.8 kB
import { Color, ObservableArray, Utils } from '@nativescript/core'; import * as commonModule from './common'; export * from './common'; //////////////////////////////////////////////////////////////////////////////////////////////////// export class CalendarEvent extends commonModule.CalendarEvent { get ios() { if (!this._ios) { this._ios = TKCalendarEvent.new(); } return this._ios; } _setIsAllDay(value) { this.ios.allDay = value; } _getIsAllDay() { return this.ios.allDay; } _setEndDate(date) { this.ios.endDate = date; } _getEndDate() { return this.ios.endDate; } _setStartDate(date) { this.ios.startDate = date; } _getStartDate() { return this.ios.startDate; } _setTitle(value) { this.ios.title = value; } _getTitle() { return this.ios.title; } _setEventColor(value) { this.ios.eventColor = value.ios; } _getEventColor() { if (this.ios.eventColor) { let a = new interop.Reference(); let r = new interop.Reference(); let g = new interop.Reference(); let b = new interop.Reference(); this.ios.eventColor.getRedGreenBlueAlpha(r, g, b, a); return new Color(Math.round(a.value * 255), Math.round(r.value * 255), Math.round(g.value * 255), Math.round(b.value * 255)); } else { return null; } } } /** * Helper methods */ class Tools { static createFont(fontName, fontStyle, fontSize) { let font = null; let size = fontSize || 10; if (fontName) { font = UIFont.fontWithNameSize(fontName, size); } else { font = UIFont.systemFontOfSize(size); } if (!font) { console.log('WARNING: Cannot create font with given name: ' + font + '. System font will be used instead.'); font = UIFont.systemFontOfSize(size); return font; } if (fontStyle) { let traits = 0 /* UIFontDescriptorSymbolicTraits.ClassUnknown */; switch (fontStyle) { case commonModule.CalendarFontStyle.Bold: traits = 2 /* UIFontDescriptorSymbolicTraits.TraitBold */; break; case commonModule.CalendarFontStyle.Italic: traits = 1 /* UIFontDescriptorSymbolicTraits.TraitItalic */; break; case commonModule.CalendarFontStyle.BoldItalic: traits = 2 /* UIFontDescriptorSymbolicTraits.TraitBold */ | 1 /* UIFontDescriptorSymbolicTraits.TraitItalic */; break; } let newFont = UIFont.fontWithDescriptorSize(font.fontDescriptor.fontDescriptorWithSymbolicTraits(traits), size); if (newFont) { font = newFont; } } return font; } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // STYLES FOR DIFFERENT CELL TYPES ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// export class CellStyleInitializer { onCellBorderWidthChanged(oldValue, newValue, style) { if (!isNaN(+newValue)) { style.ios.leftBorderWidth = newValue; style.ios.rightBorderWidth = newValue; style.ios.topBorderWidth = newValue; style.ios.bottomBorderWidth = newValue; } else { style.ios.leftBorderWidth = 0; style.ios.rightBorderWidth = 0; style.ios.topBorderWidth = 0; style.ios.bottomBorderWidth = 0; } } onCellBorderColorChanged(oldValue, newValue, style) { if (newValue) { style.ios.leftBorderColor = newValue.ios; style.ios.rightBorderColor = newValue.ios; style.ios.topBorderColor = newValue.ios; style.ios.bottomBorderColor = newValue.ios; } else { let color = new Color('#00000000'); style.ios.leftBorderColor = color.ios; style.ios.rightBorderColor = color.ios; style.ios.topBorderColor = color.ios; style.ios.bottomBorderColor = color.ios; } } onCellBackgroundColorChanged(oldValue, newValue, style) { if (newValue) { style.ios.backgroundColor = newValue.ios; } else { let color = new Color('#00000000'); style.ios.backgroundColor = color.ios; } } onCellAlignmentChanged(oldValue, newValue, style) { if (!newValue) { return; } switch (newValue) { case commonModule.CalendarCellAlignment.Bottom: style.ios.textAlignment = 8 /* TKCalendarCellAlignment.Bottom */; break; case commonModule.CalendarCellAlignment.Top: style.ios.textAlignment = 4 /* TKCalendarCellAlignment.Top */; break; case commonModule.CalendarCellAlignment.Left: style.ios.textAlignment = 1 /* TKCalendarCellAlignment.Left */; break; case commonModule.CalendarCellAlignment.Right: style.ios.textAlignment = 2 /* TKCalendarCellAlignment.Right */; break; case commonModule.CalendarCellAlignment.HorizontalCenter: style.ios.textAlignment = 16 /* TKCalendarCellAlignment.HorizontalCenter */; break; case commonModule.CalendarCellAlignment.VerticalCenter: style.ios.textAlignment = 32 /* TKCalendarCellAlignment.VerticalCenter */; break; case commonModule.CalendarCellAlignment.Center: style.ios.textAlignment = 16 /* TKCalendarCellAlignment.HorizontalCenter */ | 32 /* TKCalendarCellAlignment.VerticalCenter */; break; default: console.log('WARNING: Unsupported cell alignment value: ' + newValue); } } onCellPaddingHorizontalChanged(oldValue, newValue, style) { let vertPadding = !isNaN(+style.cellPaddingVertical) ? style.cellPaddingVertical : 0; if (!isNaN(+newValue)) { style.ios.textInsets = UIEdgeInsetsFromString('{' + vertPadding + ', ' + newValue + ', ' + vertPadding + ', ' + newValue + '}'); // in android you cannot set event paddings exclusively, there is only cell paddings. That's why we apply the paddings to all of the cell content, including events if (style instanceof DayCellStyle) { style.ios.eventInsets = UIEdgeInsetsFromString('{' + vertPadding + ', ' + newValue + ', ' + vertPadding + ', ' + newValue + '}'); } } else { style.ios.textInsets = UIEdgeInsetsFromString('{' + vertPadding + ', ' + 0 + ', ' + vertPadding + ', ' + 0 + '}'); // in android you cannot set event paddings exclusively, there is only cell paddings. That's why we apply the paddings to all of the cell content, including events if (style instanceof DayCellStyle) { style.ios.eventInsets = UIEdgeInsetsFromString('{' + vertPadding + ', ' + 0 + ', ' + vertPadding + ', ' + 0 + '}'); } } } onCellPaddingVerticalChanged(oldValue, newValue, style) { let horzPadding = !isNaN(+style.cellPaddingHorizontal) ? style.cellPaddingHorizontal : 0; if (!isNaN(+newValue)) { style.ios.textInsets = UIEdgeInsetsFromString('{' + newValue + ', ' + horzPadding + ', ' + newValue + ', ' + horzPadding + '}'); // in android you cannot set event paddings exclusively, there is only cell paddings. That's why we apply the paddings to all of the cell content, including events if (style instanceof DayCellStyle) { style.ios.eventInsets = UIEdgeInsetsFromString('{' + newValue + ', ' + horzPadding + ', ' + newValue + ', ' + horzPadding + '}'); } } else { style.ios.textInsets = UIEdgeInsetsFromString('{' + 0 + ', ' + horzPadding + ', ' + 0 + ', ' + horzPadding + '}'); // in android you cannot set event paddings exclusively, there is only cell paddings. That's why we apply the paddings to all of the cell content, including events if (style instanceof DayCellStyle) { style.ios.eventInsets = UIEdgeInsetsFromString('{' + 0 + ', ' + horzPadding + ', ' + 0 + ', ' + horzPadding + '}'); } } } onCellTextColorChanged(oldValue, newValue, style) { if (newValue) { style.ios.textColor = newValue.ios; } } onCellTextFontNameChanged(oldValue, newValue, style) { if (newValue) { style.ios.textFont = Tools.createFont(newValue, style.cellTextFontStyle, style.cellTextSize); } } onCellTextFontStyleChanged(oldValue, newValue, style) { if (newValue) { style.ios.textFont = Tools.createFont(style.cellTextFontName, newValue, style.cellTextSize); } } onCellTextSizeChanged(oldValue, newValue, style) { if (!isNaN(+newValue)) { style.ios.textFont = Tools.createFont(style.cellTextFontName, style.cellTextFontStyle, newValue); } } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// export class CellStyle extends commonModule.CellStyle { constructor() { super(); this._ios = TKCalendarCellStyle.alloc().init(); } get initializer() { if (!this._initializer) { this._initializer = new CellStyleInitializer(); } return this._initializer; } get ios() { return this._ios; } onCellBorderWidthChanged(oldValue, newValue) { this.initializer.onCellBorderWidthChanged(oldValue, newValue, this); } onCellBorderColorChanged(oldValue, newValue) { this.initializer.onCellBorderColorChanged(oldValue, newValue, this); } onCellBackgroundColorChanged(oldValue, newValue) { this.initializer.onCellBackgroundColorChanged(oldValue, newValue, this); } onCellTextColorChanged(oldValue, newValue) { this.initializer.onCellTextColorChanged(oldValue, newValue, this); } onCellTextFontNameChanged(oldValue, newValue) { this.initializer.onCellTextFontNameChanged(oldValue, newValue, this); } onCellTextFontStyleChanged(oldValue, newValue) { this.initializer.onCellTextFontStyleChanged(oldValue, newValue, this); } onCellTextSizeChanged(oldValue, newValue) { this.initializer.onCellTextSizeChanged(oldValue, newValue, this); } onCellPaddingHorizontalChanged(oldValue, newValue) { this.initializer.onCellPaddingHorizontalChanged(oldValue, newValue, this); } onCellPaddingVerticalChanged(oldValue, newValue) { this.initializer.onCellPaddingVerticalChanged(oldValue, newValue, this); } onCellAlignmentChanged(oldValue, newValue) { this.initializer.onCellAlignmentChanged(oldValue, newValue, this); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// export class DayEventsViewStyle extends commonModule.DayEventsViewStyle { // @ts-ignore set owner(value) { this._owner = value; this.updateNativePresenter(); } updateNativePresenter() { if (this._owner && this._owner._nativeView.presenter instanceof TKCalendarDayViewPresenter) { let dayPresenter = this._owner._nativeView.presenter; if (this.backgroundColor) { dayPresenter.dayView.eventsView.backgroundColor = this.backgroundColor.ios; } if (this.timeLabelFormat) { let dateFormatter = NSDateFormatter.alloc().init(); dateFormatter.dateFormat = this.timeLabelFormat; dayPresenter.dayView.eventsView.style.labelFormatter = dateFormatter; } if (this.timeLabelTextColor) { dayPresenter.dayView.eventsView.style.labelTextColor = this.timeLabelTextColor.ios; } if (this.timeLabelTextSize) { dayPresenter.dayView.eventsView.style.labelTextSize = this.timeLabelTextSize; } dayPresenter.dayView.eventsView.updateLayout(); } } onBackgroundColorChanged(oldValue, newValue) { if (newValue && this._owner && this._owner._nativeView.presenter instanceof TKCalendarDayViewPresenter) { this._owner._nativeView.presenter.dayView.eventsView.backgroundColor = newValue.ios; this._owner._nativeView.presenter.dayView.eventsView.updateLayout(); } } onTimeLabelTextColorChanged(oldValue, newValue) { if (newValue && this._owner && this._owner._nativeView.presenter instanceof TKCalendarDayViewPresenter) { this._owner._nativeView.presenter.dayView.eventsView.style.labelTextColor = newValue.ios; this._owner._nativeView.presenter.dayView.eventsView.updateLayout(); } } onTimeLabelTextSizeChanged(oldValue, newValue) { if (newValue && this._owner && this._owner._nativeView.presenter instanceof TKCalendarDayViewPresenter) { this._owner._nativeView.presenter.dayView.eventsView.style.labelTextSize = newValue; this._owner._nativeView.presenter.dayView.eventsView.updateLayout(); } } onTimeLabelFormatChanged(oldValue, newValue) { if (newValue && this._owner && this._owner._nativeView.presenter instanceof TKCalendarDayViewPresenter) { let dateFormatter = NSDateFormatter.alloc().init(); dateFormatter.dateFormat = this.timeLabelFormat; this._owner._nativeView.presenter.dayView.eventsView.style.labelFormatter = dateFormatter; this._owner._nativeView.presenter.dayView.eventsView.updateLayout(); } } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// export class AllDayEventsViewStyle extends commonModule.AllDayEventsViewStyle { // @ts-ignore set owner(value) { this._owner = value; this.updateNativePresenter(); } updateNativePresenter() { if (this._owner && this._owner._nativeView.presenter instanceof TKCalendarDayViewPresenter) { let dayPresenter = this._owner._nativeView.presenter; if (this.backgroundColor) { dayPresenter.dayView.allDayEventsView.backgroundColor = this.backgroundColor.ios; } if (this.allDayText !== AllDayEventsViewStyle.ALL_DAY_TEXT) { dayPresenter.dayView.allDayEventsView.labelView.text = this.allDayText; } if (this.allDayTextIsVisible !== undefined) { dayPresenter.dayView.allDayEventsView.style.labelWidth = this.allDayTextIsVisible ? 60 : 0; } dayPresenter.dayView.allDayEventsView.updateLayout(); } } onBackgroundColorChanged(oldValue, newValue) { if (newValue && this._owner && this._owner._nativeView.presenter instanceof TKCalendarDayViewPresenter) { this._owner._nativeView.presenter.dayView.allDayEventsView.backgroundColor = newValue.ios; } } onAllDayTextChanged(oldValue, newValue) { if (newValue && this._owner && this._owner._nativeView.presenter instanceof TKCalendarDayViewPresenter) { this._owner._nativeView.presenter.dayView.allDayEventsView.labelView.text = newValue; } } onAllDayTextIsVisibleChanged(oldValue, newValue) { if (newValue && this._owner && this._owner._nativeView.presenter instanceof TKCalendarDayViewPresenter) { this._owner._nativeView.presenter.dayView.allDayEventsView.style.labelWidth = this.allDayTextIsVisible ? 60 : 0; } } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// export class DayCellStyle extends commonModule.DayCellStyle { constructor() { super(); this._ios = TKCalendarDayCellStyle.alloc().init(); } get initializer() { if (!this._initializer) { this._initializer = new CellStyleInitializer(); } return this._initializer; } get ios() { return this._ios; } onCellBorderWidthChanged(oldValue, newValue) { this.initializer.onCellBorderWidthChanged(oldValue, newValue, this); } onCellBorderColorChanged(oldValue, newValue) { this.initializer.onCellBorderColorChanged(oldValue, newValue, this); } onCellBackgroundColorChanged(oldValue, newValue) { this.initializer.onCellBackgroundColorChanged(oldValue, newValue, this); } onCellTextColorChanged(oldValue, newValue) { this.initializer.onCellTextColorChanged(oldValue, newValue, this); } onCellTextFontNameChanged(oldValue, newValue) { this.initializer.onCellTextFontNameChanged(oldValue, newValue, this); } onCellTextFontStyleChanged(oldValue, newValue) { this.initializer.onCellTextFontStyleChanged(oldValue, newValue, this); } onCellTextSizeChanged(oldValue, newValue) { this.initializer.onCellTextSizeChanged(oldValue, newValue, this); } onCellPaddingHorizontalChanged(oldValue, newValue) { this.initializer.onCellPaddingHorizontalChanged(oldValue, newValue, this); } onCellPaddingVerticalChanged(oldValue, newValue) { this.initializer.onCellPaddingVerticalChanged(oldValue, newValue, this); } onCellAlignmentChanged(oldValue, newValue) { this.initializer.onCellAlignmentChanged(oldValue, newValue, this); } // day cell specific properties onShowEventsTextChanged(oldValue, newValue) { this.ios.displayEventsAsText = newValue; } onEventTextColorChanged(oldValue, newValue) { if (newValue) { this.ios.eventTextColor = newValue.ios; } } onEventFontNameChanged(oldValue, newValue) { if (newValue) { this.ios.eventFont = Tools.createFont(newValue, this.eventFontStyle, this.eventTextSize); } } onEventFontStyleChanged(oldValue, newValue) { if (newValue) { this.ios.eventFont = Tools.createFont(this.eventFontName, newValue, this.eventTextSize); } } onEventTextSizeChanged(oldValue, newValue) { if (!isNaN(+newValue)) { this.ios.eventFont = Tools.createFont(this.eventFontName, this.eventFontStyle, newValue); } } } /** * Cell style class for months in year view mode */ export class MonthCellStyle extends commonModule.MonthCellStyle { // @ts-ignore set owner(value) { this._owner = value; this.updateNativePresenter(); } updateNativePresenter() { if (this._owner && this._owner._nativeView.presenter instanceof TKCalendarYearPresenter) { if (this.dayTextColor) this._owner._nativeView.presenter.style.dayTextColor = this.dayTextColor.ios; if (this.weekendTextColor) this._owner._nativeView.presenter.style.weekendTextColor = this.weekendTextColor.ios; if (this.todayTextColor) this._owner._nativeView.presenter.style.todayTextColor = this.todayTextColor.ios; if (this.dayNameTextColor) this._owner._nativeView.presenter.style.dayNameTextColor = this.dayNameTextColor.ios; if (this.monthNameTextColor) this._owner._nativeView.presenter.style.monthNameTextColor = this.monthNameTextColor.ios; this._owner._nativeView.presenter.style.dayFont = Tools.createFont(this.dayFontName, this.dayFontStyle, this.dayTextSize); this._owner._nativeView.presenter.style.dayNameFont = Tools.createFont(this.dayNameFontName, this.dayNameFontStyle, this.dayNameTextSize); this._owner._nativeView.presenter.style.monthNameFont = Tools.createFont(this.monthNameFontName, this.monthNameFontStyle, this.monthNameTextSize); // note: since android calendar in year view doesn't support shape color, we disable it for ios too this._owner._nativeView.presenter.style.todayShapeFill = null; } } onWeekendTextColorChanged(oldValue, newValue) { if (newValue && this._owner) { this._owner._nativeView.presenter.style.weekendTextColor = newValue.ios; } } onTodayTextColorChanged(oldValue, newValue) { if (newValue && this._owner) { this._owner._nativeView.presenter.style.todayTextColor = newValue.ios; } } onDayTextColorChanged(oldValue, newValue) { if (newValue && this._owner) { this._owner._nativeView.presenter.style.dayTextColor = newValue.ios; } } onDayFontNameChanged(oldValue, newValue) { if (this._owner && newValue) { this._owner._nativeView.presenter.style.dayFont = Tools.createFont(newValue, this.dayFontStyle, this.dayTextSize); } } onDayFontStyleChanged(oldValue, newValue) { if (this._owner && newValue) { this._owner._nativeView.presenter.style.dayFont = Tools.createFont(this.dayFontName, newValue, this.dayTextSize); } } onDayTextSizeChanged(oldValue, newValue) { if (this._owner && !isNaN(+newValue)) { this._owner._nativeView.presenter.style.dayFont = Tools.createFont(this.dayFontName, this.dayFontStyle, newValue); } } onDayNameTextColorChanged(oldValue, newValue) { if (newValue && this._owner) { this._owner._nativeView.presenter.style.dayNameTextColor = newValue.ios; } } onDayNameFontNameChanged(oldValue, newValue) { if (this._owner && newValue) { this._owner._nativeView.presenter.style.dayNameFont = Tools.createFont(newValue, this.dayNameFontStyle, this.dayNameTextSize); } } onDayNameFontStyleChanged(oldValue, newValue) { if (this._owner && newValue) { this._owner._nativeView.presenter.style.dayNameFont = Tools.createFont(this.dayNameFontName, newValue, this.dayNameTextSize); } } onDayNameTextSizeChanged(oldValue, newValue) { if (this._owner && !isNaN(+newValue)) { this._owner._nativeView.presenter.style.dayNameFont = Tools.createFont(this.dayNameFontName, this.dayNameFontStyle, newValue); } } onMonthNameTextColorChanged(oldValue, newValue) { if (newValue && this._owner) { this._owner._nativeView.presenter.style.monthNameTextColor = newValue.ios; } } onMonthNameFontNameChanged(oldValue, newValue) { if (this._owner && newValue) { this._owner._nativeView.presenter.style.monthNameFont = Tools.createFont(newValue, this.monthNameFontStyle, this.monthNameTextSize); } } onMonthNameFontStyleChanged(oldValue, newValue) { if (this._owner && newValue) { this._owner._nativeView.presenter.style.monthNameFont = Tools.createFont(this.monthNameFontName, newValue, this.monthNameTextSize); } } onMonthNameTextSizeChanged(oldValue, newValue) { if (this._owner && !isNaN(+newValue)) { this._owner._nativeView.presenter.style.monthNameFont = Tools.createFont(this.monthNameFontName, this.monthNameFontStyle, newValue); } } } /** * Cell style class for inline events cells in month view * property values are used by TKCalendarMonthPresenterDelegateImplementation delegate that's why we don't need extra actions for update */ export class InlineEventCellStyle extends commonModule.InlineEventCellStyle { onCellBackgroundColorChanged(oldValue, newValue) { } onEventTextColorChanged(oldValue, newValue) { } onEventFontNameChanged(oldValue, newValue) { } onEventFontStyleChanged(oldValue, newValue) { } onEventTextSizeChanged(oldValue, newValue) { } onTimeTextColorChanged(oldValue, newValue) { } onTimeFontNameChanged(oldValue, newValue) { } onTimeFontStyleChanged(oldValue, newValue) { } onTimeTextSizeChanged(oldValue, newValue) { } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // STYLES FOR DIFFERENT VIEW MODES ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Class for month view style */ export class CalendarMonthViewStyle extends commonModule.CalendarMonthViewStyle { // @ts-ignore set owner(value) { this._owner = value; this.updateNativeOwner(); if (!this.selectedDayCellStyle) { this.selectedDayCellStyle = new DayCellStyle(); } } updateViewStyles(forceUpdate) { this.updateNativeOwner(); } updateNativeOwner() { if (this._owner && this._owner._nativeView && this._owner._nativeView.presenter instanceof TKCalendarMonthPresenter) { if (this.showWeekNumbers !== undefined) this._owner._nativeView.presenter.weekNumbersHidden = !this.showWeekNumbers; if (this.showTitle !== undefined) this._owner._nativeView.presenter.titleHidden = !this.showTitle; if (this.showDayNames !== undefined) this._owner._nativeView.presenter.dayNamesHidden = !this.showDayNames; if (this.backgroundColor) this._owner._nativeView.presenter.style.backgroundColor = this.backgroundColor.ios; this._owner.updateCalendar(); } } updateOwner() { if (this._owner) { this._owner.updateCalendar(); } } onSelectionShapeChanged(oldValue, newValue) { super.onSelectionShapeChanged(oldValue, newValue); this.updateOwner(); } onSelectionShapeSizeChanged(oldValue, newValue) { super.onSelectionShapeSizeChanged(oldValue, newValue); this.updateOwner(); } onSelectionShapeColorChanged(oldValue, newValue) { super.onSelectionShapeColorChanged(oldValue, newValue); this.updateOwner(); } onShowWeekNumbersChanged(oldValue, newValue) { if (this._owner && this._owner._nativeView) { this._owner._nativeView.presenter.weekNumbersHidden = !newValue; } this.updateOwner(); } onShowTitleChanged(oldValue, newValue) { if (this._owner && this._owner._nativeView) { this._owner._nativeView.presenter.titleHidden = !newValue; } this.updateOwner(); } onShowDayNamesChanged(oldValue, newValue) { if (this._owner && this._owner._nativeView) { this._owner._nativeView.presenter.dayNamesHidden = !newValue; } this.updateOwner(); } onBackgroundColorChanged(oldValue, newValue) { if (newValue && this._owner && this._owner._nativeView) { this._owner._nativeView.presenter.style.backgroundColor = newValue.ios; } this.updateOwner(); } onDayCellStyleChanged(oldValue, newValue) { this.updateOwner(); } onSelectedDayCellStyleChanged(oldValue, newValue) { this.updateOwner(); } onTodayCellStyleChanged(oldValue, newValue) { this.updateOwner(); } onWeekNumberCellStyleChanged(oldValue, newValue) { this.updateOwner(); } onWeekendCellStyleChanged(oldValue, newValue) { this.updateOwner(); } onDayNameCellStyleChanged(oldValue, newValue) { this.updateOwner(); } onTitleCellStyleChanged(oldValue, newValue) { this.updateOwner(); } onInlineEventCellStyleChanged(oldValue, newValue) { this.updateOwner(); } } /** * The style class for week mode. * NOTE: we should consider if we need an explicit class that is the same as the base one */ export class CalendarWeekViewStyle extends CalendarMonthViewStyle { updateNativeOwner() { if (this._owner && this._owner._nativeView.presenter instanceof TKCalendarWeekPresenter) { super.updateNativeOwner(); } } } /** * The style class for day mode. */ export class CalendarDayViewStyle extends commonModule.CalendarDayViewStyle { // @ts-ignore set owner(value) { this._owner = value; if (this.dayEventsViewStyle) { this.dayEventsViewStyle.owner = this._owner; } if (this.allDayEventsViewStyle) { this.allDayEventsViewStyle.owner = this._owner; } this.updateNativeOwner(); } updateNativeOwner() { if (this._owner && this._owner._nativeView && this._owner._nativeView.presenter instanceof TKCalendarDayViewPresenter) { if (this.showWeekNumbers !== undefined) this._owner._nativeView.presenter.weekNumbersHidden = !this.showWeekNumbers; if (this.showTitle !== undefined) this._owner._nativeView.presenter.titleHidden = !this.showTitle; if (this.showDayNames !== undefined) this._owner._nativeView.presenter.dayNamesHidden = !this.showDayNames; if (this.backgroundColor) this._owner._nativeView.presenter.style.backgroundColor = this.backgroundColor.ios; this._owner._nativeView.presenter.weekHidden = !this.showWeek; } this.updateOwner(); } updateViewStyles(forceUpdate) { if (this.dayEventsViewStyle) { this.dayEventsViewStyle['updateNativePresenter'](); } if (this.allDayEventsViewStyle) { this.allDayEventsViewStyle['updateNativePresenter'](); } this.updateNativeOwner(); } updateOwner() { if (this._owner) { this._owner.updateCalendar(); } } onShowWeekNumbersChanged(oldValue, newValue) { if (this._owner && this._owner._nativeView && this._owner._nativeView.presenter instanceof TKCalendarDayViewPresenter) { this._owner._nativeView.presenter.weekNumbersHidden = !newValue; } this.updateOwner(); } onShowTitleChanged(oldValue, newValue) { if (this._owner && this._owner._nativeView && this._owner._nativeView.presenter instanceof TKCalendarDayViewPresenter) { this._owner._nativeView.presenter.titleHidden = !newValue; } this.updateOwner(); } onShowDayNamesChanged(oldValue, newValue) { if (this._owner && this._owner._nativeView && this._owner._nativeView.presenter instanceof TKCalendarDayViewPresenter) { this._owner._nativeView.presenter.dayNamesHidden = !newValue; } this.updateOwner(); } onBackgroundColorChanged(oldValue, newValue) { if (newValue && this._owner && this._owner._nativeView && this._owner._nativeView.presenter instanceof TKCalendarDayViewPresenter) { this._owner._nativeView.presenter.style.backgroundColor = newValue.ios; } this.updateOwner(); } onTitleCellStyleChanged(oldValue, newValue) { this.updateOwner(); } onDayEventsViewStyleChanged(oldValue, newValue) { if (newValue && this._owner) { this.dayEventsViewStyle.owner = this._owner; } this.updateOwner(); } onAllDayEventsViewStyleChanged(oldValue, newValue) { if (newValue && this._owner) { this.allDayEventsViewStyle.owner = this._owner; } this.updateOwner(); } onShowWeekChanged(oldValue, newValue) { this.changeShowWeek(oldValue, newValue); } changeShowWeek(oldValue, newValue) { if (this._owner && this._owner._nativeView && this._owner._nativeView.presenter instanceof TKCalendarDayViewPresenter) { this._owner._nativeView.presenter.weekHidden = !newValue; } this.updateOwner(); } } /** * The style class for month name view mode. * NOTE: we should consider if we need an explicit class that is the same as the base one */ export class CalendarMonthNamesViewStyle extends commonModule.CalendarMonthNamesViewStyle { constructor() { super(); } // @ts-ignore set owner(value) { this._owner = value; } updateViewStyles(forceUpdate) { this.updateOwner(); } updateOwner() { if (this._owner && this._owner.viewMode === commonModule.CalendarViewMode.MonthNames) { this._owner.updateCalendar(); } } onTitleCellStyleChanged(oldValue, newValue) { this.updateOwner(); } onMonthNameCellStyleChanged(oldValue, newValue) { this.updateOwner(); } } /** * The year mode style class */ export class CalendarYearViewStyle extends commonModule.CalendarYearViewStyle { constructor() { super(); } // @ts-ignore set owner(value) { this._owner = value; if (this.monthCellStyle) { this.monthCellStyle.owner = this._owner; } } updateViewStyles(forceUpdate) { this.monthCellStyle['updateNativePresenter'](); this.updateOwner(); } updateOwner() { if (this._owner) { this._owner.updateCalendar(); } } onTitleCellStyleChanged(oldValue, newValue) { this.updateOwner(); } onMonthCellStyleChanged(oldValue, newValue) { if (newValue && this._owner) { this.monthCellStyle.owner = this._owner; } this.updateOwner(); } } //////////////////////////////////////////////////////////////////////////////////////////////////// export class RadCalendar extends commonModule.RadCalendar { constructor() { super(); this._ios = TKCalendar.alloc().init(); this._nativeDelegate = TKCalendarNativeDelegateImplementation.initWithOwner(new WeakRef(this)); this._nativePresenterDelegate = TKCalendarMonthPresenterDelegateImplementation.initWithOwner(new WeakRef(this)); this._dayViewDelegate = TKCalendarDayViewDelegateImplementation.initWithOwner(new WeakRef(this)); this._ios.delegate = this._nativeDelegate; this._currentCalendar = NSCalendar.currentCalendar; this._dateComponents = NSDateComponents.alloc().init(); if (this.displayedDate === undefined) { this.loadNativeDisplayedDate(); } this.setNativeLocale(this.locale); } // TODO: Remove this and implement native setters for properties get _nativeView() { return this._ios; } createNativeView() { return this._ios; } onLoaded() { super.onLoaded(); this._ios.delegate = this._nativeDelegate; this._ios.dataSource = this._dataSource; this._ios.presenter.delegate = this._nativePresenterDelegate; this._calendarLoaded = true; } onUnloaded() { super.onUnloaded(); this._ios.dataSource = null; this._calendarLoaded = false; if (this._ios.presenter instanceof TKCalendarPresenterBase) { this._ios.presenter.delegate = null; } } updateCalendar() { if (this._calendarLoaded && this._nativeView.presenter) { this._nativeView.presenter.update(false); } } onLocalePropertyChanged(oldValue, newValue) { super.onLocalePropertyChanged(oldValue, newValue); this.setNativeLocale(newValue); } setNativeLocale(locale) { if (locale) { this._nativeView.locale = NSLocale.alloc().initWithLocaleIdentifier(locale); this.updateCalendar(); } } onDisplayedDateChanged(oldValue, newValue) { if (newValue) { this._nativeView.navigateToDateAnimated(newValue, false); } } getDisplayedDate() { return this._nativeView.displayedDate; } onSelectionModeChanged(oldValue, newValue) { this.clearSelection(); switch (newValue) { case commonModule.CalendarSelectionMode.None: this._nativeView.selectionMode = 0 /* TKCalendarSelectionMode.None */; break; case commonModule.CalendarSelectionMode.Single: this._nativeView.selectionMode = 1 /* TKCalendarSelectionMode.Single */; break; case commonModule.CalendarSelectionMode.Multiple: this._nativeView.selectionMode = 2 /* TKCalendarSelectionMode.Multiple */; break; case commonModule.CalendarSelectionMode.Range: this._nativeView.selectionMode = 3 /* TKCalendarSelectionMode.Range */; break; default: console.log('WARNING: Unsupported selection mode: ' + newValue); } } onTransitionModeChanged(oldValue, newValue) { if (newValue) { let typedPresenter = this._nativeView.presenter; switch (newValue) { case commonModule.CalendarTransitionMode.None: typedPresenter.transitionMode = 0 /* TKCalendarTransitionMode.None */; break; case commonModule.CalendarTransitionMode.Slide: typedPresenter.transitionMode = 6 /* TKCalendarTransitionMode.Scroll */; break; case commonModule.CalendarTransitionMode.Stack: typedPresenter.transitionMode = 4 /* TKCalendarTransitionMode.Card */; break; case commonModule.CalendarTransitionMode.Flip: typedPresenter.transitionMode = 1 /* TKCalendarTransitionMode.Flip */; break; case commonModule.CalendarTransitionMode.Fold: typedPresenter.transitionMode = 2 /* TKCalendarTransitionMode.Fold */; break; case commonModule.CalendarTransitionMode.Float: typedPresenter.transitionMode = 3 /* TKCalendarTransitionMode.Float */; break; case commonModule.CalendarTransitionMode.Rotate: typedPresenter.transitionMode = 5 /* TKCalendarTransitionMode.Rotate */; break; default: console.log('WARNING: Unsupported transitionMode mode: ' + newValue); } } } onViewModeChanged(oldValue, newValue) { let viewStyle; switch (newValue) { case commonModule.CalendarViewMode.Month: this._nativeView.viewMode = 1 /* TKCalendarViewMode.Month */; viewStyle = this.monthViewStyle; break; case commonModule.CalendarViewMode.MonthNames: this._nativeView.viewMode = 2 /* TKCalendarViewMode.MonthNames */; viewStyle = this.monthNamesViewStyle; break; case commonModule.CalendarViewMode.Week: this._nativeView.viewMode = 0 /* TKCalendarViewMode.Week */; viewStyle = this.weekViewStyle; break; case commonModule.CalendarViewMode.Year: this._nativeView.viewMode = 3 /* TKCalendarViewMode.Year */; viewStyle = this.yearViewStyle; break; case commonModule.CalendarViewMode.Day: this._nativeView.viewMode = 6 /* TKCalendarViewMode.Day */; viewStyle = this.dayViewStyle; if (this._nativeView.presenter instanceof TKCalendarDayViewPresenter) { this._nativeView.presenter.dayView.delegate = this._dayViewDelegate; } break; // case commonModule.CalendarViewMode.Flow.toLocaleLowerCase(): // this.ios.viewMode = TKCalendarViewMode.TKCalendarViewModeFlow; // break; // case commonModule.CalendarViewMode.YearNumbers.toLocaleLowerCase(): // this.ios.viewMode = TKCalendarViewMode.TKCalendarViewModeYearNumbers; // break; default: console.log('WARNING: Unsupported view mode: ' + newValue); } if (viewStyle) { viewStyle.updateViewStyles(); } } onEventsViewModeChanged(oldValue, newValue) { if (this._nativeView.viewMode !== 1 /* TKCalendarViewMode.Month */ || newValue === undefined) { return; } let typedPresenter = this._nativeView.presenter; switch (newValue) { case commonModule.CalendarEventsViewMode.None: typedPresenter.inlineEventsViewMode = 0 /* TKCalendarInlineEventsViewMode.None */; break; case commonModule.CalendarEventsViewMode.Inline: typedPresenter.inlineEventsViewMode = 1 /* TKCalendarInlineEventsViewMode.Inline */; break; case commonModule.CalendarEventsViewMode.Popover: typedPresenter.inlineEventsViewMode = 2 /* TKCalendarInlineEventsViewMode.Popover */; console.log('WARNING: Popover mode for events is not supported for iPhone.'); break; default: console.log('WARNING: Unsupported events view mode: ' + newValue); } } onSelectedDateRangeChanged(oldValue, newValue) { if (this._forbidDateSelection) { return; } if (!newValue) { this.clearSelection(); return; } if (newValue instanceof commonModule.DateRange) { let tkDateRange = TKDateRange.alloc().initWithStartEnd(newValue.startDate, newValue.endDate); this._nativeView.selectedDatesRange = tkDateRange; } } onSelectedDatesChanged(oldValue, newValue) { if (this._forbidDateSelection) { return; } if (!newValue) { this.clearSelection(); return; } let newDates = newValue; if (typeof newDates === 'string') { newDates = newDates.split(','); } let selectedDates = NSMutableArray.new(); for (let i = 0; i < newDates.length; i++) { let date = new Date(newDates[i]); selectedDates.addObject(date); } this._nativeView.selectedDates = selectedDates; } onSelectedDateChanged(oldValue, newValue) { if (this._forbidDateSelection) { return; } this._nativeView.selectedDate = newValue; } onMaxDateChanged(oldValue, newValue) { this._nativeView.maxDate = newValue; } onMinDateChanged(oldValue, newValue) { this._nativeView.minDate = newValue; } updateEventSource() { if (!this._nativeView) { return; } if (this.eventSource) { if (!this._dataSource) { this._dataSource = CalendarNativeDataSourceImplementation.new().initWithOwner(this); this._dataSource.itemsSource = this.eventSource; this._ios.dataSource = this._dataSource; if (this.viewMode === commonModule.CalendarViewMode.Day) { this._ios.presenter.update(true); } } else { this._dataSource.itemsSource = this.eventSource; this._ios.presenter.update(false); } } } onHorizontalTransitionChanged(oldValue, newValue) { let horizontalTransition = newValue; this._nativeView.presenter['transitionIsVertical'] = !horizontalTransition; } onMonthViewStyleChanged(oldValue, newValue) { if (newValue && newValue instanceof CalendarMonthViewStyle) { this.monthViewStyle.owner = this; } } onMonthNamesViewStyleChanged(oldValue, newValue) { if (newValue && newValue instanceof CalendarMonthNamesViewStyle) { this.monthNamesViewStyle.owner = this; } } onWeekViewStyleChanged(oldValue, newValue) { if (newValue && newValue instanceof CalendarWeekViewStyle) { this.weekViewStyle.owner = this; } } onDayViewStyleChanged(oldValue, newValue) { if (newValue && newValue instanceof CalendarDayViewStyle) { this.dayViewStyle.owner = this; } } onYearViewStyleChanged(oldValue, newValue) { if (newValue && newValue instanceof CalendarYearViewStyle) { this.yearViewStyle.owner = this; } } loadNativeDisplayedDate() { let nativeDate = this.dateWithoutHours(this._ios.displayedDate); if (this.displayedDate !== nativeDate) { this.displayedDate = nativeDate; } } dateWithoutHours(originalDate) { this._dateComponents.day = originalDate.getDate(); this._dateComponents.month = originalDate.getMonth() + 1; this._dateComponents.year = originalDate.getFullYear(); return this._currentCalendar.dateFromComponents(this._dateComponents); } reload() { if (this._nativeView) { this._nativeView.reloadData(); } this.clearSelection(); } clearSelection() { super.clearSelection(); if (this._nativeView) { this._nativeView.clearSelection(); } } navigateForward() { this._nativeView.navigateForward(true); } navigateBack() { this._nativeView.navigateBack(true); } goToDate(date) { this._nativeView.navigateToDateAnimated(date, true); } getEventsForDate(date) { let nativeResult = this._nativeView.eventsForDate(date); let result = new Array(); let a = new interop.Reference(); let r = new interop.Reference(); let g = new interop.Reference(); let b = new interop.Reference(); let nativeEvent; let event; for (let i = 0; i < nativeResult.count; i++) { nativeEvent = nativeResult.objectAtIndex(i); if (nativeEvent.eventColor) { nativeEvent.eventColor.getRedGreenBlueAlpha(r, g, b, a); } let color = nativeEvent.eventColor ? new Color(Math.round(a.value * 255), Math.round(r.value * 255), Math.round(g.value * 255), Math.round(b.value * 255)) : null; event = nativeEventToNSEvent(nativeEvent, this.eventSource); event.eventColor = color; result.push(event); } return result; } } var CalendarNativeDataSourceImplementation = /** @class */ (function (_super) { __extends(CalendarNativeDataSourceImplementation, _super); function CalendarNativeDataSourceImplementation() { return _super !== null && _super.apply(this, arguments) || this; } CalendarNativeDataSourceImplementation.new = function () { return _super.new.call(this); }; CalendarNativeDataSourceImplementation.prototype.initWithSourceAndOwner = function (source, owner) { this.itemsSource = source; this._owner = owner; return this; }; CalendarNativeDataSourceImplementation.prototype.initWithOwner = function (owner) { this._owner = owner; return this; }; Object.defineProperty(CalendarNativeDataSourceImplementation.prototype, "itemsSource", { get: function () { return this._itemsSource; }, set: function (value) { if (value instanceof ObservableArray) { var list = new Array(); for (var i = 0; i < value.length; i++) { list.push(value.getItem(i)); } this._itemsSource = list; } else { this._itemsSource = value; } }, enumerable: true, configurable: true }); CalendarNativeDataSourceImplementation.prototype.calendarEventsForDate = function (calendar, date) { var nativeEvents = NSMutableArray.alloc().init(); for (var event in this.itemsSource) { var startDate = this.itemsSource[event].startDate; var endDate = this.itemsSource[event].endDate; if (startDate && endDate) { // check if the date is between the start/end dates or exactly equal to either start or end if ((endDate.getTime() >= date.getTime() && startDate.getTime() <= date.getTime()) || (startDate.getDate() === date.getDate() && startDate.getMonth() === date.getMonth() && startDate.getFullYear() === date.getFullYear()) || (endDate.getDate() === date.getDate() && endDate.getMonth() === date.getMonth() && endDate.getFullYear() === date.getFullYear())) { nativeEvents.addObject(this.itemsSource[event].ios); } } } return nativeEvents; }; CalendarNativeDataSourceImplementation.prototype.calendarEventsFromDateToDateWithCallback = function (calendar, fromDate, toDate, callback) { var nativeEvents = NSMutableArray.alloc().init(); for (var event in this.itemsSource) { var startDate = this.itemsSource[event].startDate; var endDate = this.itemsSource[event].endDate; // SD - startDate // ED - endDate // FD - fromDate // TD - toDate // -----SD----FD--------ED-----------------------------------------TD--------- if ((startDate.getTime() <= fromDate.getTime() && endDate.getTime() >= fromDate.getTime()) |