extends Control signal date_selected(date: Calendar.DateObj) @onready var _main: Main = get_tree().get_current_scene() @onready var _month_label: Label = $VBoxContainer/HBoxContainer/MonthLabel @onready var _days_grid: GridContainer = $VBoxContainer/DaysGrid @onready var _prev_month_button: Button = $VBoxContainer/HBoxContainer/PrevMonthButton @onready var _next_month_button: Button = $VBoxContainer/HBoxContainer/NextMonthButton @onready var _vertical_box: VBoxContainer = $VBoxContainer @onready var _horizontal_box: HBoxContainer = $VBoxContainer/HBoxContainer var cal: Calendar = Calendar.new() var current_date: Calendar.DateObj = Calendar.DateObj.today() var selected_date_label: Label var weekdays_formatted: Array[String] var months_formatted: Array[String] func _process(delta): _process_grid_size() _process_font_size(_month_label, 32) _process_font_size(_prev_month_button, 32) _process_font_size(_next_month_button, 32) func _process_grid_size(): for day_label in _days_grid.get_children(): var font_size = day_label.label_settings.font_size var new_font_size = get_viewport_rect().size.y/32 if font_size != new_font_size: day_label.label_settings.font_size = new_font_size for selection in day_label.get_children(): var selection_size = selection.size.x var new_selection_size = get_viewport_rect().size.y/32 if selection_size != new_selection_size: selection.size.x = new_selection_size selection.size.y = new_selection_size func _process_font_size(obj, k): var font_size = obj.get_theme_default_font_size() var new_font_size = get_viewport_rect().size.y/k if font_size != new_font_size: obj.add_theme_font_size_override("font_size", new_font_size) func _ready() -> void: cal.set_calendar_locale("res://addons/calendar_library/demo/calendar_locale_RU.tres") cal.set_first_weekday(Time.WEEKDAY_MONDAY) cal.week_number_system = Calendar.WeekNumberSystem.WEEK_NUMBER_FOUR_DAY weekdays_formatted = cal.get_weekdays_formatted(Calendar.WeekdayFormat.WEEKDAY_FORMAT_SHORT) months_formatted = cal.get_months_formatted(Calendar.MonthFormat.MONTH_FORMAT_FULL) _prev_month_button.pressed.connect(_on_prev_month_pressed) _next_month_button.pressed.connect(_on_next_month_pressed) update_calendar() func update_calendar() -> void: for child in _days_grid.get_children(): child.queue_free() _month_label.text = "%s %d" % [months_formatted[current_date.month - 1], current_date.year] var month_calendar = cal.get_calendar_month(current_date.year, current_date.month, true) var today = Calendar.DateObj.today() for weekday in weekdays_formatted: var label = CalendarLabel.new(weekday) _days_grid.add_child(label) for week in month_calendar: for date_obj in week: var day_label = create_day_label(date_obj, today) _days_grid.add_child(day_label) _cancel_selection() func _cancel_selection(): for day_label in _days_grid.get_children(): for selection in day_label.get_children(): selection.queue_free() func create_day_label(date_obj: Calendar.DateObj, today: Calendar.DateObj) -> CalendarLabel: var label = CalendarLabel.new(str(date_obj.day), true) if date_obj.month != current_date.month: label.label_settings.font_color = Color("#414853") else: if date_obj.is_equal(today): label.label_settings.font_color = Color("#70bafa") else: label.label_settings.font_color = Color("#cdced2") if date_obj.is_equal(current_date): set_selected_state(label) selected_date_label = label label.pressed.connect(_on_date_pressed.bind(date_obj, label)) return label func set_selected_state(label: Label) -> void: if selected_date_label and selected_date_label.get_child_count() > 0: selected_date_label.get_child(0).queue_free() var selection = ColorRect.new() selection.size = Vector2(60, 60) selection.color = Color("#414853") selection.show_behind_parent = true label.add_child(selection) selected_date_label = label func _on_date_pressed(date: Calendar.DateObj, label: Label) -> void: current_date = date set_selected_state(label) date_selected.emit(date) update_calendar() _main.go_to_previous_page(true) func _on_prev_month_pressed() -> void: current_date.add_months(-1) update_calendar() func _on_next_month_pressed() -> void: current_date.add_months(1) update_calendar() func update(): _cancel_selection() class CalendarLabel: extends Label signal pressed() var clickable: bool = false func _init(p_text: String, p_clickable: bool = false): text = p_text horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER mouse_filter = MOUSE_FILTER_PASS if p_text.is_empty() else MOUSE_FILTER_STOP var settings = LabelSettings.new() settings.font_size = 46 settings.font_color = Color.WHITE label_settings = settings if p_clickable and not p_text.is_empty(): clickable = true mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND func _gui_input(event: InputEvent) -> void: if clickable and event is InputEventMouseButton: if event.pressed and event.button_index == MOUSE_BUTTON_LEFT: pressed.emit()