new change to use intaleq_map sdk 04-16-4

This commit is contained in:
Hamza-Ayed
2026-04-16 19:45:03 +03:00
parent 0aa1f15f25
commit a54a7a4189
850 changed files with 83282 additions and 3075 deletions

View File

@@ -0,0 +1,14 @@
import '../models/cb_config.dart';
import 'package:get/get.dart';
///Main controller for all the datas
class CbController extends GetxController {
///data configuration for [cbcontroller]
CbConfig? cbConfig;
///add config
void changeConfig(CbConfig config) {
cbConfig = config;
}
}

View File

@@ -0,0 +1,179 @@
import 'package:get/get.dart';
import '../../calendar_builder.dart';
/// State manager or controller of MonthBuilder
class MonthBuilderController extends GetxController {
///startDate of month
DateTime mStartDate = DateTime(DateTime.now().year);
/// EndDate of month
/// default one year greater than [mStartDate]
/// [endDate] should be greater than [startDate]
DateTime mEndDate =
DateTime(DateTime.now().year + 20).subtract(const Duration(days: 1));
///Current day/Todays Date of Birth"
///default = now
DateTime mCurrentDay = DateTime.now();
///this contains all the [DateTime] from [mStartDate] to [mEndDate] with [mEndDate]+its full year
///!minimum 1 year dates will be there
late List<DateTime> mAllDates;
///this contains all the [DateTime] from [mStartDate] to [mEndDate]
late List<DateTime> mStartToEndDates;
///this contains all the dateTime sorted in the basis of years from [mStartDate] to [mEndDate]
///!minimum 1 year will be there
late List<DateTime> mAllYears;
///lits of 16 dates for year dropDown
late List<DateTime> m16DateTimeYears;
///Slected Date
///default = [mStartDate]
DateTime mSelectedDate = DateTime.now();
///Slected Year
///default = [DateTime(mStartDate.year)]
DateTime mSelectedYear = DateTime(DateTime.now().year);
///all events dates
List<DateTime> mEventDates = [];
///all disabled dates
List<DateTime> mDisabledDates = [];
///all hilighted dates
List<DateTime> mHighlightedDates = [];
///weeek start from
///default = `WeekStartsFrom.sunday`
WeekStartsFrom mWeekStartsFrom = WeekStartsFrom.sunday;
///used to improve the performance of [monthBuilder]
///wee add all the datas using [addToSavedMonthDates] function
///and theen [savedMonthRemover] this function removers dates
///if [savedMonthDatas.length] exceeds 3
///
List<DateTime> savedMonthDatas = [];
///removed date from [savedMonthDatas]
DateTime? removedDate;
///all month start up logic
void _logicInitialization() {
///alll the dates form [mStartDate] to [mEndDate]
mStartToEndDates =
DateUtilsCB.getDaysInBeteween(startDate: mStartDate, endDate: mEndDate);
///all the dates in each the year
mAllDates = DateUtilsCB.getAllDaysInBetweenYears(
startDate: mStartDate, endDate: mEndDate);
///gets all the years form [mStartDate] to [mEndDate]
mAllYears = DateUtilsCB.getYearsInBeteween(
startDate: mStartDate, endDate: mEndDate);
_yearBuilderLogic();
}
///configaration for month builder
void config({CbConfig? config, bool useOnHotReload = false}) {
if (useOnHotReload == false) {
mStartDate = config?.startDate ?? DateTime(DateTime.now().year);
}
mEndDate = config?.endDate ??
DateTime(DateTime.now().year + 20).subtract(const Duration(days: 1));
///
if (useOnHotReload == false) {
mSelectedDate = config?.selectedDate ?? DateTime.now();
mSelectedYear = config?.selectedYear ?? DateTime(mStartDate.year);
}
mCurrentDay = config?.currentDay ?? DateTime.now();
mWeekStartsFrom = config?.weekStartsFrom ?? WeekStartsFrom.sunday;
mEventDates = config?.eventDates ?? [];
mHighlightedDates = config?.highlightedDates ?? [];
mDisabledDates = config?.disabledDates ?? [];
_logicInitialization();
}
///For Improving Performace
///Add selectedYear to savedMonthDatas --- to save data
void addToSavedMonthDates(DateTime date) {
savedMonthDatas.add(date);
savedMonthDatas = savedMonthDatas.toSet().toList();
}
///For Improving Performace
///to check wether the saved month size exceeds 3
///if excedes it removes previous cached datas
void savedMonthRemover(DateTime date) {
CalendarGlobals.debugLogs('-----$date');
if (savedMonthDatas.length > 3) {
if (savedMonthDatas[0] != date) {
removedDate = savedMonthDatas[0];
savedMonthDatas.removeAt(0);
update(['removedDate:$removedDate!']);
CalendarGlobals.debugLogs('removedDate:$removedDate!');
} else {
removedDate = null;
}
} else {
removedDate = null;
}
}
///Checking [mAllYears]
///because to get alll the 16 days to fill the boxes in [UI]
void _yearBuilderLogic() {
if (mAllYears.length < 16) {
m16DateTimeYears = DateUtilsCB.getYearsInBeteween(
startDate: mStartDate,
endDate: DateTime(mAllYears.last.year + (16 - (mAllYears.length))),
);
} else {
m16DateTimeYears = [];
}
}
///fuction to update Selected Date [mSelectedDate]
void changeSelectedDate({
required DateTime selectedDate,
DateTime? oldSelectedDate,
required String commonUpdateId,
String? updateId,
bool updateByID = false,
}) {
mSelectedDate = selectedDate;
//common update Id for date changes
update([commonUpdateId]);
CalendarGlobals.debugLogs('old:$oldSelectedDate');
CalendarGlobals.debugLogs('selcted:$selectedDate');
if (updateByID && oldSelectedDate != null && updateId != null) {
update([selectedDate, oldSelectedDate, updateId]);
} else {
update();
}
}
///fuction to update Selected Date [mSelectedYear]
void changeSelectedYear({
required DateTime selectedYear,
DateTime? oldSelectedYear,
required String commonUpdateId,
String? updateId,
bool updateByID = false,
}) {
mSelectedYear = selectedYear;
//common update Id for date changes
update([commonUpdateId]);
if (updateByID && oldSelectedYear != null && updateId != null) {
update([selectedYear, oldSelectedYear, updateId]);
} else {
update();
}
}
}

View File

@@ -0,0 +1,46 @@
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import '../../calendar_builder.dart';
///this controller is used to controll the state of the [month_builder] ui
class MonthUiController extends GetxController {
///checking wether the yer picker is expanded or not
bool isYearPickerExpanded = false;
///Page controller for Month
late PageController mPageController;
///callback when year header is expanded
void Function(bool isExpanded)? onYearHeaderExpanded;
/// callback when year button is clicked
void Function(DateTime selectedYear, bool isSelected)? onYearButtonClicked;
/// callback when date button is clicked
void Function(OnDateSelected onDateSelected)? onDateClicked;
///used to chage the expanded or not-expanded , state of year picker
void chageYearExpanded(
{String? updateId,
required String commonUpdateId,
required bool isExpanded}) {
///if its aldready in the same state then it will not update
if (isYearPickerExpanded != isExpanded) {
isYearPickerExpanded = isExpanded;
///common update Id for year picker expanded
update([commonUpdateId]);
if (updateId != null) {
update([updateId]);
} else {
update();
}
}
}
///checking for year dropdown should be expanded initially or not
void expandInitiaally(bool isExpanded) {
isYearPickerExpanded = isExpanded;
}
}

View File

@@ -0,0 +1,82 @@
import '../utils/date_utils_cb.dart';
///Global configuration class for [calendar_builder]
class CbConfig {
///startDate of month
final DateTime startDate;
/// EndDate of month
/// [endDate] should be greater than [startDate]
final DateTime endDate;
///Current day/Todays Date
///default = now
final DateTime? currentDay;
///Slected Date
///default = [startDate]
final DateTime selectedDate;
///Slected Year
///default = [DateTime(StartDate.year)]
final DateTime selectedYear;
///Add events
final List<DateTime>? eventDates;
///Add disabled dates
final List<DateTime>? disabledDates;
///Add hilighted dates
final List<DateTime>? highlightedDates;
///weeek start from
///default = `WeekStartsFrom.sunday`
///
///------options---------
///
/// `WeekStartsFrom.monday`
///
/// `WeekStartsFrom.tuesday`
///
/// `WeekStartsFrom.wednesday`
///
/// `WeekStartsFrom.thursday`
///
/// `WeekStartsFrom.friday`
///
/// `WeekStartsFrom.saturday`
///
/// `WeekStartsFrom.sunday`
final WeekStartsFrom weekStartsFrom;
///
CbConfig({
required this.startDate,
required this.endDate,
required this.selectedDate,
required this.selectedYear,
this.currentDay,
this.eventDates,
this.disabledDates,
this.highlightedDates,
this.weekStartsFrom = WeekStartsFrom.sunday,
}) : assert(startDate.isBefore(endDate),
'\n\nERROR ( Calendar Builder ):\n---------\nInside CbConfig()\nEndDate Should be greater than StartDate\n---------\n_'),
assert(
DateUtilsCB.checkDayisSelected(
dateSelected: selectedDate,
loopedDay: endDate,
) ||
selectedDate.isBefore(endDate),
'\n\nERROR ( Calendar Builder ):\n---------\nInside CbConfig()\nSelectedDate Should be in B/w StartDate and EndDate\n---------\n_'),
assert(
DateUtilsCB.checkDayisSelected(
dateSelected: selectedDate,
loopedDay: startDate,
) ||
selectedDate.isAfter(startDate),
'\n\nERROR ( Calendar Builder ):\n---------\nInside CbConfig()\nSelectedDate Should be in B/w StartDate and EndDate\n---------\n_'),
assert(selectedYear.year >= startDate.year &&
selectedYear.year <= endDate.year);
}

View File

@@ -0,0 +1,685 @@
import 'package:flutter/material.dart';
///Year Header Builder
typedef WidgetCbYearHeader = Widget Function(
bool isYearPickerExpanded,
DateTime selectedDate,
DateTime selectedYear,
String year,
);
///year button builder
typedef WidgetCbYearButton = Widget Function(
DateTime dateTime,
double heightResponsive,
double widthResponsive,
bool isYearDisabled,
bool isYearSelected,
);
///Month button builder
typedef WidgetCbMonthButton = Widget Function(
DateTime dateTime,
double childHeight,
double childWidth,
bool isSelected,
bool isDisabled,
bool hasEvent,
bool isHighlighted,
bool isCurrentDate);
/// Month week builder
typedef WidgetCbMonthWeek = Widget Function(
int index,
String weeks,
double weekHeight,
double weekWidth,
);
///Month Header builder
typedef WeidgetCbMonthHeader = Widget Function(
String month,
double headerHeight,
double headerWidth,
double paddingLeft,
);
///A data class for customizing buttons of [CbYearDropDown]
class YearButtonCustomizer {
///constructor
YearButtonCustomizer({
this.borderColorOnSelected,
this.borderColorOnDisabled,
this.borderColorOnEnabled,
this.textColorOnSelected,
this.textColorOnDisabled,
this.textColorOnEnabled,
this.splashColor,
this.hoverColor,
this.onPressed,
this.shrinkOnButtonPressed = true,
});
///Apply border color to button When buttton is [selected]
final Color? borderColorOnSelected;
///Apply border color to button When buttton is [Disabled]
final Color? borderColorOnDisabled;
///Apply border color to button When buttton is [Enabled]
final Color? borderColorOnEnabled;
///change text color of [selected] year inside Button
final Color? textColorOnSelected;
///change text color of [Disabled] year inside Button
final Color? textColorOnDisabled;
///change text color of [enabled] year inside Button
final Color? textColorOnEnabled;
///Change spalash color of button
final Color? splashColor;
///Change hover color of button
final Color? hoverColor;
///onPress calback when buttton is pressed
final void Function(bool isButtonDisabled, DateTime selectedYear)? onPressed;
///shrink expanded On Buttton Pressed [bool]
///default [true]
final bool shrinkOnButtonPressed;
}
///A data class for customizing year Header of [CbYearDropDown]
class YearHeaderCustomizer {
///
YearHeaderCustomizer({
this.titleTextStyle,
this.height = 40,
this.width,
this.downIcon = Icons.arrow_drop_down_outlined,
this.upIcon = Icons.arrow_drop_up_outlined,
});
///change TextStyle of year title
final TextStyle? titleTextStyle;
///change height of year Headder
final double height;
///change width of year Headder
final double? width;
///change expanded down icons
final IconData downIcon;
///change expanded up icons
final IconData upIcon;
}
///Customize year DropDown
class YearDropDownCustomizer {
///
const YearDropDownCustomizer({
this.yearHeaderCustomizer,
this.yearButtonCustomizer,
this.yearHeaderBuilder,
this.yearButtonBuilder,
this.expandedYearHeight = 200,
this.expandedYearWidth,
this.expandYearInitially = false,
});
///customise year Header style [YearHeaderCustomizer]
///```dart
///
///YearHeaderCustomizer(),
///
///
/// ```
/// {@end-tool}
final YearHeaderCustomizer? yearHeaderCustomizer;
///customise year button style [YearButtonCustomizer]
///```dart
///
///YearButtonCustomizer(),
///
///
/// ```
/// {@end-tool}
final YearButtonCustomizer? yearButtonCustomizer;
///Build your custom YearDropDown Header
///
///* NOTE: COPY & PASTE
///* ### Sample code
///
/// ```dart
/// yearHeaderBuilder: (isYearPickerExpanded, selectedDate, selectedYear, year) {
/// return SizedBox(
/// height: 40,
/// child: Row(
/// mainAxisAlignment: MainAxisAlignment.center,
/// crossAxisAlignment: CrossAxisAlignment.center,
/// children: [
/// Text(
/// year,
/// style: const TextStyle(fontWeight: FontWeight.bold),
/// ),
/// Icon(!isYearPickerExpanded
/// ? Icons.arrow_drop_down_outlined
/// : Icons.arrow_drop_up_outlined)
/// ],
/// ),
/// );
/// },
/// ```
/// {@end-tool}
///
final WidgetCbYearHeader? yearHeaderBuilder;
///Build your own year buttons
///
///* NOTE: COPY & PASTE
///* ### Sample code
///
/// ```dart
/// yearButtonBuilder: (dateTime, heightResponsive,widthResponsive, isyearDisabled, isYearselected) {
/// final txtTheme = Theme.of(context).textTheme;
/// final colorTheme = Theme.of(context);
/// return SizedBox(
/// height: heightResponsive,
/// width: widthResponsive,
/// child: DecoratedBox(
/// decoration: BoxDecoration(
/// borderRadius: BorderRadius.all(
/// Radius.circular(heightResponsive),
/// ),
/// border: Border.all(
/// color: isyearDisabled
/// ? colorTheme.disabledColor.withOpacity(0.1)
/// : isYearselected
/// ? (colorTheme.brightness ==
/// Brightness.dark
/// ? colorTheme.accentColor
/// : Colors.black)
/// : Colors.grey,
/// width: isyearDisabled
/// ? 1
/// : isYearselected
/// ? 1.5
/// : 1),
/// ),
/// child: FittedBox(
/// fit: BoxFit.scaleDown,
/// child: Text(dateTime.year.toString(),
/// style: isyearDisabled
/// ? txtTheme.caption
/// : isYearselected
/// ? txtTheme.button
/// : txtTheme.button,),
/// ),
/// ),
/// );
/// },
/// ```
/// {@end-tool}
///
final WidgetCbYearButton? yearButtonBuilder;
///Expanded Height of year dropDown
///default = 200
final double expandedYearHeight;
///Expanded Width of year dropDown
final double? expandedYearWidth;
///default = `false`
///Expande year Drop Down initially
final bool expandYearInitially;
}
///customozer calss for Month button
class MonthButtonCustomizer {
///height of month button
final double? height;
///width of month button
final double? width;
///Text Style on Enabled
final TextStyle? textStyleOnEnabled;
///Text Style on Disabled
final TextStyle? textStyleOnDisabled;
///Text Style on Selected
final TextStyle? textStyleOnSelected;
///Text Style on CurrentDay
final TextStyle? currentDayTextStyle;
///Text Style on Highlighted
final TextStyle? highlightedTextStyle;
/// color on Disabled
final Color? colorOnDisabled;
/// border color on Enabled
final Color? borderColorOnEnabled;
/// Highlight Color/Border Color
final Color? highlightedColor;
///Current Day Color/BorderColor
final Color? currentDayColor;
///color on selected
final Color? colorOnSelected;
///event dot color on Enabled
final Color? eventColor;
///event color on Disabled
final Color? eventColorOnDisabled;
///border Stroke width on Enabled
final double borderStrokeWidth;
/// default = `PaintingStyle.stroke`
final PaintingStyle paintStyleOnEnabled;
///Highlighted Button Painting Style
///default = `PaintingStyle.stroke`
final PaintingStyle highlightedPaintingStyle;
///CurrentDay Button Painting Style
///default = `PaintingStyle.fill`
final PaintingStyle currentDayPaintingStyle;
/// default = `PaintingStyle.fill`
final PaintingStyle paintStyleOnDisabled;
///on month Button pressed
final void Function(DateTime selectedDate)? onPressed;
///
MonthButtonCustomizer({
this.onPressed,
this.textStyleOnEnabled,
this.textStyleOnDisabled,
this.textStyleOnSelected,
this.currentDayTextStyle,
this.highlightedTextStyle,
this.colorOnDisabled,
this.borderColorOnEnabled,
this.colorOnSelected,
this.eventColor,
this.eventColorOnDisabled,
this.highlightedColor,
this.currentDayColor,
this.highlightedPaintingStyle = PaintingStyle.stroke,
this.currentDayPaintingStyle = PaintingStyle.fill,
this.borderStrokeWidth = 1,
this.paintStyleOnEnabled = PaintingStyle.stroke,
this.paintStyleOnDisabled = PaintingStyle.fill,
this.height,
this.width,
});
}
///CUstomiser class for month
class MonthCustomizer {
///CUstomiser class for month
MonthCustomizer({
this.montMinhHeight = 300,
this.monthMinWidth,
this.scrollToSelectedMonth = false,
this.shrinkYearDropDownOnScroll = true,
this.mainAxisSpacing = 20,
this.crossAxisSpacing = 20,
this.padding = EdgeInsets.zero,
this.monthButtonCustomizer,
this.monthButtonBuilder,
this.monthHeaderCustomizer,
this.monthHeaderBuilder,
this.monthWeekBuilder,
this.monthWeekCustomizer,
});
///heigh of single month
final double montMinhHeight;
///width of single month depend on the device you use
final double? monthMinWidth;
///default `scrollToSelectedMonth = false`
///
///if [scrollToSelectedMonth = true] month will scroll to selected date
final bool scrollToSelectedMonth;
///default = `true`
///wether year DropDown Should shrink While Scrolling
final bool shrinkYearDropDownOnScroll;
///The number of logical pixels between each month along the main axis.
///
///give top & bottom space between months
final double mainAxisSpacing;
///The number of logical pixels between each month along the cross axis.
///
///give left & right space between months
final double crossAxisSpacing;
///set padding arround month
final EdgeInsetsGeometry padding;
///Customise month buttons
final MonthButtonCustomizer? monthButtonCustomizer;
///Customize month Header
final MonthHeaderCustomizer? monthHeaderCustomizer;
///Customize month week
final MonthWeekCustomizer? monthWeekCustomizer;
///Build your own month buttons
///
///* NOTE: COPY & PASTE
///* ### Sample code
///
/// ```dart
/// monthButtonBuilder: (dateTime,childHeight,childWidth,isSelected,isDisabled,hasEvent,isHighlighted,isCurrentDay) {
/// //Text Theme
/// final txtTheme = Theme.of(context).textTheme;
/// //color theme
/// final colorTheme = Theme.of(context);
///
/// var daysText = Align(
/// child: Text(
/// '${dateTime.day}',
/// style: isDisabled
/// ? txtTheme.caption
/// : isSelected
/// ? txtTheme.bodyText1!.copyWith(
/// fontWeight: FontWeight.bold,
/// color:
/// colorTheme.brightness == Brightness.dark
/// ? Colors.black
/// : Colors.white)
/// : isHighlighted
/// ? txtTheme.bodyText2 //Highlighted TextStyle
/// : isCurrentDay
/// ? txtTheme
/// .bodyText2 //CurrentDay TextStyle
/// : txtTheme.bodyText2,
/// ),
/// );
/// return Stack(
/// children: [
/// //if button is Enabled or Disabled
/// isDisabled || !isSelected
/// ? CustomPaint(
/// painter: CirclePainter(
/// color: isDisabled
/// ? colorTheme.disabledColor
/// .withOpacity(0.03)
/// : isHighlighted
/// ? colorTheme.accentColor
/// : isCurrentDay
/// ? colorTheme.accentColor
/// .withOpacity(0.5)
/// : colorTheme.disabledColor
/// .withOpacity(0.05),
/// style: isDisabled
/// ? PaintingStyle.fill
/// : isHighlighted
/// ? PaintingStyle.stroke
/// : isCurrentDay
/// ? PaintingStyle.fill
/// : PaintingStyle.stroke,
/// strokeWidth: 1,
/// radius: childHeight / 2,
/// ),
/// child: daysText,
/// )
/// //if button is Selected
/// : Align(
/// child: SizedBox(
/// height: childHeight,
/// width: childWidth,
/// child: TweenAnimationBuilder<Decoration>(
/// duration: const Duration(milliseconds: 200),
/// tween: DecorationTween(
/// begin: BoxDecoration(
/// color: colorTheme.accentColor,
/// shape: BoxShape.circle,
/// boxShadow: [
/// BoxShadow(
/// blurRadius: 5,
/// color: colorTheme.accentColor
/// .withOpacity(0.6),
/// spreadRadius: 3,
/// ),
/// ]),
/// end: BoxDecoration(
/// color: colorTheme.accentColor,
/// shape: BoxShape.circle,
/// ),
/// ),
/// builder: (context, value, child) =>
/// DecoratedBox(
/// decoration: value,
/// child: daysText,
/// ),
/// ),
/// ),
/// ),
/// //event button
/// if (hasEvent)
/// Align(
/// alignment: Alignment.bottomCenter,
/// child: CustomPaint(
/// painter: CirclePainter(
/// color: isDisabled
/// ? colorTheme.disabledColor.withOpacity(0.05)
/// : colorTheme.accentColor,
/// style: PaintingStyle.fill,
/// strokeWidth: 0,
/// radius: 3,
/// offset: const Offset(0, -4),
/// ),
/// ),
/// ),
/// ],
/// );
/// },
/// ```
/// {@end-tool}
///
final WidgetCbMonthButton? monthButtonBuilder;
///Build your own weeks
///
///* NOTE: COPY & PASTE
///* ### Sample code
///
/// ```dart
/// monthWeekBuilder: (index, weeks, weekHeight, weekWidth) {
/// return SizedBox(
/// height: weekHeight,
/// width: weekWidth,
/// child: Align(
/// child: Text(
/// weeks,
/// style: const TextStyle(
/// fontSize: 14,
/// color: Colors.grey,
/// fontWeight: FontWeight.w500,
/// ),
/// overflow: TextOverflow.ellipsis,
/// maxLines: 1,
/// ),
/// ),
/// );
/// },
/// ```
/// {@end-tool}
///
final WidgetCbMonthWeek? monthWeekBuilder;
///Build your own month Headers
///
///* NOTE: COPY & PASTE
///* ### Sample code
///
/// ```dart
/// monthHeaderBuilder:
/// (month, headerHeight, headerWidth, paddingLeft) {
/// return SizedBox(
/// height: headerHeight,
/// width: headerWidth,
/// child: Padding(
/// padding: EdgeInsets.only(left: paddingLeft),
/// child: Align(
/// alignment: Alignment.centerLeft,
/// child: Text(
/// month,
/// style: const TextStyle(
/// fontSize: 22,
/// fontWeight: FontWeight.w600,
/// ),
/// ),
/// ),
/// ),
/// );
/// },
/// ```
/// {@end-tool}
///
final WeidgetCbMonthHeader? monthHeaderBuilder;
}
///Customizer class for moth header
class MonthHeaderCustomizer {
///height of year Header
final double height;
///width of year header
final double? width;
///padding o fHeader Text
final EdgeInsetsGeometry? padding;
///Text style of Header Text
final TextStyle? textStyle;
///insert All 12 Months
///
///* Example
///```dart
///[
/// 'January',
/// 'February',
/// 'March',
/// 'April',
/// 'May',
/// 'June',
/// 'July',
/// 'August',
/// 'September',
/// 'October',
/// 'November',
/// 'December',
///]
///````
/// {@end-tool}
///
final List<String>? monthList;
///
MonthHeaderCustomizer({
this.height = 40,
this.width,
this.padding,
this.textStyle,
this.monthList,
});
}
///Month Weeek customiser
class MonthWeekCustomizer {
///height of year Header
final double height;
///Text style of Header Text
final TextStyle? textStyle;
///insert All 7 weeks
///
///* Example
///```dart
///[
/// 'SUN',
/// 'MON',
/// 'TUE',
/// 'WED',
/// 'THU',
/// 'FRI',
/// 'SAT',
///]
///````
/// {@end-tool}
///
final List<String>? weekList;
///
MonthWeekCustomizer({
this.height = 40,
this.textStyle,
this.weekList,
});
}
///OnDateSelected
class OnDateSelected {
///Selected data on calendar
final DateTime selectedDate;
///return true if Selected date is equal
final bool isSelected;
///return true if Selected date is disabled
final bool isDisabled;
///return true if Selected date has event
final bool hasEvent;
///return true if Selected date is highlighted
final bool isHighlighted;
///return true if Selected date is current day
final bool isCurrentDate;
/// constructor of OnDateSelected
OnDateSelected({
required this.selectedDate,
required this.isSelected,
required this.isDisabled,
required this.hasEvent,
required this.isHighlighted,
required this.isCurrentDate,
});
}

View File

@@ -0,0 +1,293 @@
///calendar week start from [monday,....,saturday,sunday]
enum WeekStartsFrom {
///week starts from [monday]
monday,
///
tuesday,
///
wednesday,
///
thursday,
///
friday,
///week starts from [saturday]
saturday,
///week starts from [sunday]
sunday,
}
///contails all the logic of this calendar_builder package
class DateUtilsCB {
///returns all dates from [startDate - endDate] in the form of List of DateTime
static List<DateTime> getDaysInBeteween({
required DateTime startDate,
required DateTime endDate,
}) {
List<DateTime> days = [];
for (var i = 0; i <= (endDate.difference(startDate).inDays); i++) {
days.add(
DateTime(
startDate.year,
startDate.month,
// In Dart you can set more than. 30 days, DateTime will do the trick
startDate.day + i,
),
);
}
return days;
}
///this function return all the dates in a year from [startDate - endDate]
///if `endDate = DateTime(2021,3,3)` this function will return dates till `endDate` as `DateTime(2022).subtract(Duration`
static List<DateTime> getAllDaysInBetweenYears({
required DateTime startDate,
required DateTime endDate,
}) {
startDate = DateTime(startDate.year);
endDate = DateTime(endDate.year + 1);
List<DateTime> days = [];
for (var i = 0; i <= (endDate.difference(startDate).inDays) - 1; i++) {
days.add(DateTime(
startDate.year,
startDate.month,
// In Dart you can set more than. 30 days, DateTime will do the trick
startDate.day + i,
));
}
return days;
}
///returns all Years from [startDate - endDate] in the form of List of DateTime
static List<DateTime> getYearsInBeteween({
required DateTime startDate,
required DateTime endDate,
}) {
List<DateTime> years = [];
for (int i = startDate.year; i <= endDate.year; i++) {
years.add(DateTime(i));
}
return years;
}
///Checking for [dateSelected] in [loopedDays]
///if it contains the same date
///then
///it returns true
///else
///returns false
static bool checkDayisSelected({
bool isDisabled = false,
required DateTime dateSelected,
required DateTime loopedDay,
}) {
if (!isDisabled) {
return dateSelected.year == loopedDay.year &&
dateSelected.month == loopedDay.month &&
dateSelected.day == loopedDay.day;
} else {
return false;
}
}
///check year is selected
static bool checkYearIsSelected({
bool isDisabled = false,
required DateTime dateSelected,
required DateTime loopedDay,
}) {
if (!isDisabled) {
return dateSelected.year == loopedDay.year;
} else {
return false;
}
}
///Checking for [date] in [listOfDates]
///if it contains the same date
///then
///it returns true
///else
///returns false
static bool checkDayisDisabled(
{required List<DateTime> listOfDates, required DateTime date}) {
return !listOfDates.any((element) => (element.year == date.year &&
element.month == date.month &&
element.day == date.day));
}
///checking [listOfDates] has matching [date] in it
static bool checkListContainsDate(
{required List<DateTime> listOfDates, required DateTime date}) {
return listOfDates.any((element) => (element.year == date.year &&
element.month == date.month &&
element.day == date.day));
}
///Checking for [date] in [listOfDates]
///if it contains the same year
///then
///it returns false
///else
///returns true
static bool checkYearisDisabled(
{required List<DateTime> listOfDates, required DateTime date}) {
return !listOfDates.any((element) => (element.year == date.year));
}
///!latest removed #1
// ///This function will return all the DateTime in one year [yearDate]
// static List<DateTime> getAllDatesIn1Year(
// {required DateTime yearDate, required List<DateTime> allDates}) {
// List<DateTime> dates =
// allDates.where((element) => element.year == yearDate.year).toList();
// return dates;
// }
///If [selectedYear] is 2021 then this function will return all the dates of months in 2021 in the form of [List<Map<String, List<DateTime>>>]
static List<Map<String, List<DateTime>>> getAllMonthsIn1Year(
{required DateTime selectedYear}) {
///returns all the dates in a year
///!latest removed #1
// List<DateTime> _listOfDatesInYear = getAllDatesIn1Year(
// yearDate: selectedYear,
// allDates: allDates,
// );
///!replaced
List<DateTime> _listOfDatesInYear = DateUtilsCB.getAllDaysInBetweenYears(
startDate: DateTime(selectedYear.year),
endDate:
DateTime(selectedYear.year + 1).subtract(const Duration(days: 1)));
///genrating Dates in each months as List<DateTime>
List<DateTime> _listOfJan = _listOfDatesInYear
.where((element) => element.month == DateTime.january)
.toList();
List<DateTime> _listOfFeb = _listOfDatesInYear
.where((element) => element.month == DateTime.february)
.toList();
List<DateTime> _listOfMarch = _listOfDatesInYear
.where((element) => element.month == DateTime.march)
.toList();
List<DateTime> _listOfApril = _listOfDatesInYear
.where((element) => element.month == DateTime.april)
.toList();
List<DateTime> _listOfMay = _listOfDatesInYear
.where((element) => element.month == DateTime.may)
.toList();
List<DateTime> _listOfJune = _listOfDatesInYear
.where((element) => element.month == DateTime.june)
.toList();
List<DateTime> _listOfJuly = _listOfDatesInYear
.where((element) => element.month == DateTime.july)
.toList();
List<DateTime> _listOfAugust = _listOfDatesInYear
.where((element) => element.month == DateTime.august)
.toList();
List<DateTime> _listOfSept = _listOfDatesInYear
.where((element) => element.month == DateTime.september)
.toList();
List<DateTime> _listOfOct = _listOfDatesInYear
.where((element) => element.month == DateTime.october)
.toList();
List<DateTime> _listOfNov = _listOfDatesInYear
.where((element) => element.month == DateTime.november)
.toList();
List<DateTime> _listOfDec = _listOfDatesInYear
.where((element) => element.month == DateTime.december)
.toList();
List<Map<String, List<DateTime>>> _months = [
{'Jan': _listOfJan},
{'Feb': _listOfFeb},
{'March': _listOfMarch},
{'April': _listOfApril},
{'May': _listOfMay},
{'June': _listOfJune},
{'July': _listOfJuly},
{'August': _listOfAugust},
{'Sept': _listOfSept},
{'Oct': _listOfOct},
{'Nov': _listOfNov},
{'Dec': _listOfDec},
];
return _months;
}
///This [getAll42DaysIn1Month] function will return all the 42 days in a m
static List<DateTime> getAll42DaysIn1Month({
required List<DateTime> month,
WeekStartsFrom weekStartsFrom = WeekStartsFrom.sunday,
}) {
List<DateTime> aMonthDaysList = month;
DateTime firstDayOfaMonth = aMonthDaysList.first;
///For finding first Disabled Day
late DateTime firstDisableDay;
int weekSelectedIndex = (WeekStartsFrom.values.indexOf(weekStartsFrom) + 1);
firstDisableDay = firstDayOfaMonth.subtract(
///Adding +7 to [firstDayOfaMonth.weekday]
///to avoid -ve result
Duration(days: ((firstDayOfaMonth.weekday + 7) - weekSelectedIndex) % 7),
);
/* -----old-----
// if (weekStartsFrom == WeekStartsFrom.monday) {
// ///Starts week with [Monday]
// firstDisableDay = firstDayOfaMonth
// .subtract(Duration(days: firstDayOfaMonth.weekday - 1));
// } else if (weekStartsFrom == WeekStartsFrom.sunday) {
// ///Starts week with [Sunday]
// if (firstDayOfaMonth.weekday == 7) {
// firstDisableDay = firstDayOfaMonth;
// } else {
// firstDisableDay =
// firstDayOfaMonth.subtract(Duration(days: firstDayOfaMonth.weekday));
// }
// } else if (weekStartsFrom == WeekStartsFrom.saturday) {
// ///Starts week with [Saturday]
// if (firstDayOfaMonth.weekday == 6) {
// firstDisableDay = firstDayOfaMonth;
// } else if (firstDayOfaMonth.weekday == 7) {
// firstDisableDay = firstDayOfaMonth.subtract(const Duration(days: 1));
// } else {
// firstDisableDay = firstDayOfaMonth
// .subtract(Duration(days: firstDayOfaMonth.weekday + 1));
// }
// }
*/
DateTime lastDayOfaMonth = aMonthDaysList.last;
///Algorithm to find Disabled Days
List<DateTime> firstDisabledToLastDayOfMonth =
getDaysInBeteween(startDate: firstDisableDay, endDate: lastDayOfaMonth);
int lastlength = firstDisabledToLastDayOfMonth.length;
int disabledDays = 42 - lastlength;
///not used
// while (lastlength % 7 != 0) {
// lastlength++;
// disabledDays++;
// }
///To find the last Disabled Days of the month
DateTime lastDisabledDay =
lastDayOfaMonth.add(Duration(days: disabledDays));
///!geting all 42 days
List<DateTime> all42DaysOfMonth =
getDaysInBeteween(startDate: firstDisableDay, endDate: lastDisabledDay);
return all42DaysOfMonth;
}
}

View File

@@ -0,0 +1,104 @@
import 'package:flutter/material.dart';
///A global theme classs for all colors [Theme]
class CalendarGlobals {
///Minumum duration
static const kMinDuration = Duration(milliseconds: 400);
///maximum duration
static const kMaxDuration = Duration(milliseconds: 800);
///orange color
static const Color kOrange = Color(0xffFF5917);
///list of months
static const List<String> months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
];
///list of Weeks
static const List<List<String>> weeksStarter = [
[
'MON',
'TUE',
'WED',
'THU',
'FRI',
'SAT',
'SUN',
],
[
'TUE',
'WED',
'THU',
'FRI',
'SAT',
'SUN',
'MON',
],
[
'WED',
'THU',
'FRI',
'SAT',
'SUN',
'MON',
'TUE',
],
[
'THU',
'FRI',
'SAT',
'SUN',
'MON',
'TUE',
'WED',
],
[
'FRI',
'SAT',
'SUN',
'MON',
'TUE',
'WED',
'THU',
],
[
'SAT',
'SUN',
'MON',
'TUE',
'WED',
'THU',
'FRI',
],
[
'SUN',
'MON',
'TUE',
'WED',
'THU',
'FRI',
'SAT',
],
];
///Enable or disable dev logs
static bool showLogs = false;
///Enable or disable dev logs
static void debugLogs(Object _log) {
if (showLogs) debugPrint(_log.toString());
}
}

View File

@@ -0,0 +1,115 @@
import 'package:flutter/material.dart';
///easy Mod of [OutlinedButton]
class ModOutlineButton extends StatelessWidget {
///easy Mod of [OutlinedButton]
const ModOutlineButton({
Key? key,
required this.height,
required this.width,
this.onPressed,
this.shape,
this.borderSide,
required this.child,
this.overlayColor,
}) : super(key: key);
///Height of button
final double height;
///Width of button
final double width;
///Callback on button pressed
final VoidCallback? onPressed;
/// Shape of button
final OutlinedBorder? shape;
/// set border forbutton
final BorderSide? borderSide;
/// add Child widget
final Widget child;
/// Overlay color of button
final Color? overlayColor;
OutlinedBorder _handelButtonShape(Set<MaterialState> state) {
return shape ?? const StadiumBorder();
}
BorderSide _handelBorderSide(Set<MaterialState> state) {
return borderSide ??
BorderSide(
color: Colors.grey[300]!,
);
}
@override
Widget build(BuildContext context) {
return SizedBox(
height: height,
width: width,
child: FittedBox(
fit: BoxFit.scaleDown,
child: OutlinedButton(
onPressed: onPressed,
style: ButtonStyle(
shape: MaterialStateProperty.resolveWith(_handelButtonShape),
overlayColor: MaterialStateProperty.all<Color>(
overlayColor ?? Colors.blue[100]!),
side: MaterialStateProperty.resolveWith(_handelBorderSide),
),
child: child,
),
),
);
}
}
///for faster performance
///we can add
///-- borders
///-- colors
class CirclePainter extends CustomPainter {
///
CirclePainter({
required this.color,
required this.style,
required this.strokeWidth,
required this.radius,
this.offset,
});
///add color
final Color color;
///Painting style
final PaintingStyle style;
///border width
final double strokeWidth;
///radius of the circle
final double radius;
///offset
final Offset? offset;
@override
void paint(Canvas canvas, Size size) {
final _paint = Paint()
..strokeWidth = strokeWidth
..color = color
..style = style;
canvas.drawCircle(
offset ?? Offset((size.width / 2), (size.height / 2)), radius, _paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,568 @@
import '../controllers/month_builder_controller.dart';
import '../controllers/month_ui_controller.dart';
import 'package:get/get.dart';
import '../../calendar_builder.dart';
import 'package:flutter/material.dart';
//Todo: Add Image Documentation
///A year Drop down class--- default used in [CbMonthBuilder]
class CbYearDropDown extends StatefulWidget {
///
const CbYearDropDown({
Key? key,
this.matchId,
this.yearHeaderCustomizer,
this.yearHeaderBuilder,
this.yearButtonCustomizer,
this.yearButtonBuilder,
this.uiStateTag,
this.expandedYearHeight = 200,
this.expandedYearWidth,
}) : super(key: key);
/// if u want to use same data between your Calendar Builder -- make sure to give same [matchId]
final String? matchId;
///customise year Header style [YearHeaderCustomizer]
final YearHeaderCustomizer? yearHeaderCustomizer;
///customise year button style [YearButtonCustomizer]
final YearButtonCustomizer? yearButtonCustomizer;
///Build your custom YearDropDown Header
final WidgetCbYearHeader? yearHeaderBuilder;
///Build your own year buttons
final WidgetCbYearButton? yearButtonBuilder;
///Expanded Height of year dropDown
///default = 200
final double expandedYearHeight;
///Expanded Width of year dropDown
final double? expandedYearWidth;
///UI controller tag
final String? uiStateTag;
@override
_CbYearDropDownState createState() => _CbYearDropDownState();
}
class _CbYearDropDownState extends State<CbYearDropDown> {
late String matchingId;
late String uiStateTag;
@override
void initState() {
super.initState();
initControlers();
}
void initControlers() {
uiStateTag = widget.uiStateTag ?? UniqueKey().toString();
Get.put(MonthUiController(), tag: uiStateTag);
matchingId = widget.matchId ?? UniqueKey().toString();
Get.put(MonthBuilderController(), tag: matchingId);
}
@override
void dispose() {
super.dispose();
Get.delete<MonthUiController>(tag: uiStateTag);
Get.delete<MonthBuilderController>(tag: matchingId);
}
@override
Widget build(BuildContext context) {
String matchingId = widget.matchId ?? UniqueKey().toString();
final mUiCtr = Get.find<MonthUiController>(tag: uiStateTag);
final size = MediaQuery.of(context).size;
Widget _ifBuilderEmpty = SizedBox(
height: widget.yearHeaderCustomizer?.height ?? 40,
width: widget.yearHeaderCustomizer?.width ?? size.width,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GetBuilder<MonthBuilderController>(
tag: matchingId,
id: 'dateChangeId',
builder: (mCtr) {
String preMonth = mCtr.mSelectedDate.year ==
mCtr.mSelectedYear.year
? '${CalendarGlobals.months[mCtr.mSelectedDate.month - 1]} - '
: '';
String year = '$preMonth${mCtr.mSelectedYear.year}';
return Text(
year,
style: widget.yearHeaderCustomizer?.titleTextStyle ??
const TextStyle(fontWeight: FontWeight.bold),
);
}),
GetBuilder<MonthUiController>(
tag: uiStateTag,
id: 'monthExpanded',
builder: (mCtr) => Icon(!mCtr.isYearPickerExpanded
? widget.yearHeaderCustomizer?.downIcon ??
Icons.arrow_drop_down_outlined
: widget.yearHeaderCustomizer?.upIcon ??
Icons.arrow_drop_up_outlined)),
],
),
);
return Column(
children: [
InkWell(
onTap: () {
mUiCtr.onYearHeaderExpanded?.call(!mUiCtr.isYearPickerExpanded);
mUiCtr.chageYearExpanded(
isExpanded: !mUiCtr.isYearPickerExpanded,
commonUpdateId: 'commonId',
updateId: 'monthExpanded');
},
child: widget.yearHeaderBuilder == null
? _ifBuilderEmpty
: GetBuilder<MonthUiController>(
id: 'monthExpanded',
tag: uiStateTag,
builder: (mUiCtr) => GetBuilder<MonthBuilderController>(
id: 'commonId',
tag: matchingId,
builder: (mCtr) {
String preMonth = mCtr.mSelectedDate.year ==
mCtr.mSelectedYear.year
? '${CalendarGlobals.months[mCtr.mSelectedDate.month - 1]} - '
: '';
String year = '$preMonth${mCtr.mSelectedYear.year}';
return widget.yearHeaderBuilder!(
mUiCtr.isYearPickerExpanded,
mCtr.mSelectedDate,
mCtr.mSelectedYear,
year,
);
}),
),
),
_YearDropDown(
matchId: matchingId,
uiStateTag: uiStateTag,
height: widget.expandedYearHeight,
width: widget.expandedYearWidth ?? size.width,
yearButtonBuilder: widget.yearButtonBuilder,
yearButtonCustomizer: widget.yearButtonCustomizer,
)
],
);
}
}
class _YearDropDown extends StatefulWidget {
const _YearDropDown({
Key? key,
required this.matchId,
required this.uiStateTag,
required this.height,
required this.width,
this.yearButtonBuilder,
this.yearButtonCustomizer,
}) : super(key: key);
final String matchId;
final String uiStateTag;
final double height;
final double width;
final WidgetCbYearButton? yearButtonBuilder;
final YearButtonCustomizer? yearButtonCustomizer;
@override
__YearDropDownState createState() => __YearDropDownState();
}
class __YearDropDownState extends State<_YearDropDown>
with SingleTickerProviderStateMixin {
@override
Widget build(BuildContext context) {
return GetBuilder<MonthUiController>(
tag: widget.uiStateTag,
id: 'monthExpanded',
builder: (mUiCtr) {
///!this scrolling will not work while we are using builder
// WidgetsBinding.instance!.addPostFrameCallback((_) {
// Scrollable.ensureVisible(
// mCtr.mYearPickerGlobalKey[8].currentContext!);
// });
return AnimatedSize(
curve: Curves.fastOutSlowIn,
duration: CalendarGlobals.kMinDuration,
reverseDuration: CalendarGlobals.kMinDuration,
child: AnimatedOpacity(
duration: CalendarGlobals.kMaxDuration,
opacity: mUiCtr.isYearPickerExpanded ? 1.0 : 0,
child: SizedBox(
height: mUiCtr.isYearPickerExpanded ? widget.height : 0,
width: widget.width,
child: Visibility(
///by using [Visibility] will improve the performace
visible: mUiCtr.isYearPickerExpanded,
child: GetBuilder<MonthBuilderController>(
id: 'monthExpanded',
tag: widget.matchId,
builder: (mCtr) => _YearBtnGridBuilder(
uiStateTag: widget.uiStateTag,
matchId: widget.matchId,
height: widget.height,
width: widget.width,
mCtr: mCtr,
isExpanded: mUiCtr.isYearPickerExpanded,
yearButtonBuilder: widget.yearButtonBuilder,
yearButtonCustomizer: widget.yearButtonCustomizer,
),
),
),
),
),
);
},
);
}
}
class _YearBtnGridBuilder extends StatefulWidget {
const _YearBtnGridBuilder({
Key? key,
required this.height,
required this.width,
required this.mCtr,
required this.isExpanded,
required this.matchId,
required this.uiStateTag,
this.yearButtonBuilder,
this.yearButtonCustomizer,
}) : super(key: key);
final double height;
final double width;
final MonthBuilderController mCtr;
final bool isExpanded;
final String matchId;
final String uiStateTag;
final WidgetCbYearButton? yearButtonBuilder;
final YearButtonCustomizer? yearButtonCustomizer;
@override
__YearBtnGridBuilderState createState() => __YearBtnGridBuilderState();
}
class __YearBtnGridBuilderState extends State<_YearBtnGridBuilder>
with AutomaticKeepAliveClientMixin {
late ScrollController _controller;
late double scrollPosition;
///[scrollPosition] it finds the exact scroll position of the [cbYearDropDown]
///
///
///[.truncate] is used to remove fractional part/decimal part
///``if val = 1.89
///val.truncate()
///it returns 1 and removes fractoinal part``
void _findScrollPositon() {
scrollPosition = (((((widget.mCtr.m16DateTimeYears.isEmpty
? widget.mCtr.mAllYears.indexWhere((element) =>
element.year == widget.mCtr.mSelectedYear.year)
: widget.mCtr.m16DateTimeYears.indexWhere((element) =>
element.year == widget.mCtr.mSelectedYear.year))) /
4)
.truncate() *
(widget.height / 4)) -
(widget.height / 4));
}
@override
void initState() {
super.initState();
_findScrollPositon();
_controller = ScrollController(
initialScrollOffset: scrollPosition, keepScrollOffset: true);
}
@override
void didUpdateWidget(covariant _YearBtnGridBuilder oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.isExpanded != widget.isExpanded) {
_findScrollPositon();
_controller.jumpTo(
scrollPosition,
);
}
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
@override
Widget build(BuildContext context) {
super.build(context);
final bool isMaxSize = widget.width >= 1200;
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
///height of 1 button in grid
mainAxisExtent: isMaxSize ? widget.height / 3 : widget.height / 4,
crossAxisCount: isMaxSize ? 5 : 4,
),
//!same
// SliverGridDelegateWithMaxCrossAxisExtent(
// maxCrossAxisExtent:widget.width / 4,
// mainAxisExtent: widget.height / 4,
// ),
controller: _controller,
addAutomaticKeepAlives: true,
cacheExtent: 20,
physics: const BouncingScrollPhysics(),
itemCount: widget.mCtr.m16DateTimeYears.isEmpty
? widget.mCtr.mAllYears.length
: (widget.mCtr.m16DateTimeYears.length - (isMaxSize ? 1 : 0)),
itemBuilder: (context, i) => GetBuilder<MonthBuilderController>(
tag: widget.matchId,
id: widget.mCtr.m16DateTimeYears.isEmpty
? widget.mCtr.mAllYears[i]
: widget.mCtr.m16DateTimeYears[i],
builder: (mCtr) {
// Global.debugLogs('Year:$i');
DateTime thisLoopDate = mCtr.m16DateTimeYears.isEmpty
? mCtr.mAllYears[i]
: mCtr.m16DateTimeYears[i];
bool isYearselected = DateUtilsCB.checkYearIsSelected(
///
isDisabled: DateUtilsCB.checkDayisDisabled(
listOfDates: mCtr.mAllYears, date: thisLoopDate),
///
dateSelected: mCtr.mSelectedYear,
loopedDay: thisLoopDate,
);
bool isyearDisabled = DateUtilsCB.checkYearisDisabled(
listOfDates: mCtr.mAllYears,
date: thisLoopDate,
);
return FittedBox(
fit: BoxFit.scaleDown,
child: _YearButtons(
matchId: widget.matchId,
uiStateTag: widget.uiStateTag,
isyearDisabled: isyearDisabled,
thisLoopDate: thisLoopDate,
isYearselected: isYearselected,
height: widget.height,
width: widget.width,
builder: widget.yearButtonBuilder,
borderColorOnDisabled:
widget.yearButtonCustomizer?.borderColorOnDisabled,
borderColorOnEnabled:
widget.yearButtonCustomizer?.borderColorOnEnabled,
borderColorOnSelected:
widget.yearButtonCustomizer?.borderColorOnSelected,
shrinkOnButtonPressed: widget.yearButtonCustomizer == null
? true
: widget.yearButtonCustomizer!.shrinkOnButtonPressed,
hoverColor: widget.yearButtonCustomizer?.hoverColor,
onPressed: widget.yearButtonCustomizer?.onPressed,
splashColor: widget.yearButtonCustomizer?.splashColor,
textColorOnDisabled:
widget.yearButtonCustomizer?.textColorOnDisabled,
textColorOnEnabled:
widget.yearButtonCustomizer?.textColorOnEnabled,
textColorOnSelected:
widget.yearButtonCustomizer?.textColorOnSelected,
),
);
},
),
);
}
@override
bool get wantKeepAlive => true;
}
class _YearButtons extends StatefulWidget {
const _YearButtons({
Key? key,
required this.isyearDisabled,
required this.thisLoopDate,
required this.isYearselected,
required this.height,
required this.width,
required this.matchId,
required this.uiStateTag,
this.builder,
this.borderColorOnSelected,
this.borderColorOnDisabled,
this.borderColorOnEnabled,
this.textColorOnSelected,
this.textColorOnDisabled,
this.textColorOnEnabled,
this.splashColor,
this.hoverColor,
this.onPressed,
this.shrinkOnButtonPressed = true,
}) : super(key: key);
final bool isyearDisabled;
final DateTime thisLoopDate;
final bool isYearselected;
final double height;
final double width;
final String matchId;
final String uiStateTag;
final WidgetCbYearButton? builder;
///
final Color? borderColorOnSelected;
final Color? borderColorOnDisabled;
final Color? borderColorOnEnabled;
final Color? textColorOnSelected;
final Color? textColorOnDisabled;
final Color? textColorOnEnabled;
final Color? splashColor;
final Color? hoverColor;
final Function(bool isButtonDisabled, DateTime selectedYear)? onPressed;
final bool shrinkOnButtonPressed;
@override
__YearButtons createState() => __YearButtons();
}
class __YearButtons extends State<_YearButtons>
with AutomaticKeepAliveClientMixin {
///Callback when a year button is pressed
void _onYearPressed() {
final mCtr = Get.find<MonthBuilderController>(tag: widget.matchId);
final mUiCtr = Get.find<MonthUiController>(tag: widget.uiStateTag);
if (widget.isyearDisabled) {
if (widget.onPressed != null) {
widget.onPressed!(widget.isyearDisabled, widget.thisLoopDate);
}
CalendarGlobals.debugLogs('Calendar_builder: year button disabled');
} else {
if (widget.onPressed != null) {
widget.onPressed!(widget.isyearDisabled, widget.thisLoopDate);
}
///Changes selected date
mCtr.changeSelectedYear(
selectedYear: widget.thisLoopDate,
oldSelectedYear: DateTime(mCtr.mSelectedYear.year,
mCtr.mSelectedYear.month, mCtr.mSelectedYear.day),
updateByID: true,
updateId: 'dateChangeId',
commonUpdateId: 'commonId');
///isExpanded
if (widget.shrinkOnButtonPressed) {
Future.delayed(const Duration(milliseconds: 200)).then((value) {
mUiCtr.chageYearExpanded(
isExpanded: false,
updateId: 'monthExpanded',
commonUpdateId: 'commonId');
});
}
///changes the page of month pageView
int _mPage = mCtr.mAllYears
.indexWhere((element) => element.year == widget.thisLoopDate.year);
mUiCtr.mPageController.jumpToPage(_mPage);
///saves and removes months if length exedes 3
mCtr.addToSavedMonthDates(DateTime(mCtr.mSelectedYear.year,
mCtr.mSelectedYear.month, mCtr.mSelectedYear.day));
mCtr.savedMonthRemover(DateTime(widget.thisLoopDate.year,
widget.thisLoopDate.month, widget.thisLoopDate.day));
}
mUiCtr.onYearButtonClicked
?.call(widget.thisLoopDate, widget.isyearDisabled ? false : true);
}
@override
Widget build(BuildContext context) {
super.build(context);
final txtTheme = Theme.of(context).textTheme;
final colorTheme = Theme.of(context);
Widget ifBuilderisEmpty = SizedBox(
height: (widget.height / 5.5) >= 35 ? 35 : widget.height / 5.5,
width: (widget.width / 6) >= 150 ? 150 : (widget.width / 6),
child: InkWell(
onTap: _onYearPressed,
splashColor:
widget.isyearDisabled ? Colors.transparent : widget.splashColor,
hoverColor: widget.isyearDisabled ? null : widget.hoverColor,
customBorder: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(
(widget.height / 5.5) >= 35 ? 35 : widget.height / 5.5),
),
),
child: DecoratedBox(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(
(widget.height / 5.5) >= 35 ? 35 : widget.height / 5.5),
),
border: Border.all(
color: widget.isyearDisabled
? widget.borderColorOnDisabled ??
colorTheme.disabledColor.withOpacity(0.1)
: widget.isYearselected
? widget.borderColorOnSelected ??
(colorTheme.brightness == Brightness.dark
? colorTheme.colorScheme.secondary
: Colors.black)
: widget.borderColorOnEnabled ?? Colors.grey,
width: widget.isyearDisabled
? 1
: widget.isYearselected
? 1.5
: 1),
),
child: FittedBox(
fit: BoxFit.scaleDown,
child: Text(widget.thisLoopDate.year.toString(),
style: widget.isyearDisabled
? txtTheme.titleMedium!
.copyWith(color: widget.textColorOnDisabled)
: widget.isYearselected
? txtTheme.bodyLarge!
.copyWith(color: widget.textColorOnSelected)
: txtTheme.bodyLarge!
.copyWith(color: widget.textColorOnEnabled)),
),
),
),
);
return widget.builder == null
? ifBuilderisEmpty
: GestureDetector(
onTap: () {
///execute functions
_onYearPressed();
},
behavior: HitTestBehavior.opaque,
child: widget.builder!(
widget.thisLoopDate,
(widget.height / 5.5) >= 35 ? 35 : widget.height / 5.5,
(widget.width / 6) >= 150 ? 150 : (widget.width / 6),
widget.isyearDisabled,
widget.isYearselected,
));
}
@override
bool get wantKeepAlive => true;
}