154 lines
4.9 KiB
GDScript
154 lines
4.9 KiB
GDScript
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()
|