Initial commit

This commit is contained in:
Sviatoslav Tsariov Yurievich 2025-01-29 00:45:44 +03:00
commit e11999eef5
46 changed files with 1901 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Godot 4+ specific ignores
.godot/
addons/

36
ATTRIBUTION.md Normal file
View File

@ -0,0 +1,36 @@
# Attribution
## Collaborators
### Role
Person 1
Person 2
[Person w/ Link]()
## Sourced / Unaffiliated
### Asset Type
#### Use Case
Author: [Name]()
Source: [Domain : webpage.html]()
License: [License]()
#### Godot Engine Logo
Author: Andrea Calabró
Source: [godotengine.org : press](https://godotengine.org/press/)
License: [CC BY 4.0 International](https://github.com/godotengine/godot/blob/master/LOGO_LICENSE.txt)
## Tools
#### Godot
Author: [Juan Linietsky, Ariel Manzur, and contributors](https://godotengine.org/contact)
Source: [godotengine.org](https://godotengine.org/)
License: [MIT License](https://github.com/godotengine/godot/blob/master/LICENSE.txt)
#### Git
Author: [Linus Torvalds](https://github.com/torvalds)
Source: [git-scm.com](https://git-scm.com/downloads)
License: [GNU General Public License version 2](https://opensource.org/licenses/GPL-2.0)
#### Godot Menus Template
Author: [Marek Belski](https://github.com/Maaack/Godot-Menus-Template/graphs/contributors)
Source: [github: Godot-Menus-Template](https://github.com/Maaack/Godot-Menus-Template)
License: [MIT License](LICENSE.txt)

4
README.md Normal file
View File

@ -0,0 +1,4 @@
# Talkpal - Frontend
This is the **frontend** for the **Meeting Room Booking System**, built using **Godot 4.3**.
It provides a UI for managing meetings, rooms, and schedules.

BIN
Talkpal.apk Normal file

Binary file not shown.

BIN
Talkpal.apk.idsig Normal file

Binary file not shown.

BIN
assets/comfortel_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b7jnjarkiduib"
path="res://.godot/imported/comfortel_logo.png-f15e1acabec7ae2a6f363848bac9dc4c.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/comfortel_logo.png"
dest_files=["res://.godot/imported/comfortel_logo.png-f15e1acabec7ae2a6f363848bac9dc4c.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

View File

@ -0,0 +1,12 @@
[gd_resource type="GradientTexture2D" load_steps=2 format=3 uid="uid://d0llucl6yfmwj"]
[sub_resource type="Gradient" id="Gradient_4ltd2"]
offsets = PackedFloat32Array(0, 0.545455, 0.551948, 1)
colors = PackedColorArray(0.117647, 0.101961, 0.101961, 1, 0.117647, 0.101961, 0.101961, 1, 1, 1, 1, 0, 1, 1, 1, 0)
[resource]
gradient = SubResource("Gradient_4ltd2")
width = 1024
height = 1024
fill = 1
fill_from = Vector2(0.5, 0.5)

4
assets/themes/big.tres Normal file
View File

@ -0,0 +1,4 @@
[gd_resource type="Theme" format=3 uid="uid://cmhwbyqu6nh38"]
[resource]
default_font_size = 46

View File

@ -0,0 +1,4 @@
[gd_resource type="Theme" format=3 uid="uid://7lcget51crj1"]
[resource]
default_font_size = 42

View File

@ -0,0 +1,12 @@
[gd_resource type="StyleBoxFlat" format=3 uid="uid://crantichmjy77"]
[resource]
bg_color = Color(0, 0.694118, 0.631373, 0.839216)
border_width_left = 3
border_width_top = 3
border_width_bottom = 3
border_blend = true
corner_radius_top_left = 5
corner_radius_top_right = 5
corner_radius_bottom_right = 5
corner_radius_bottom_left = 5

View File

@ -0,0 +1,4 @@
[gd_resource type="Theme" format=3 uid="uid://c5nehi7j4wsjd"]
[resource]
default_font_size = 145

205
export_presets.cfg Normal file
View File

@ -0,0 +1,205 @@
[preset.0]
name="Android"
platform="Android"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="./Talkpal.apk"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
[preset.0.options]
custom_template/debug=""
custom_template/release=""
gradle_build/use_gradle_build=false
gradle_build/export_format=0
gradle_build/min_sdk=""
gradle_build/target_sdk=""
architectures/armeabi-v7a=false
architectures/arm64-v8a=true
architectures/x86=false
architectures/x86_64=false
version/code=1
version/name=""
package/unique_name="com.example.$genname"
package/name=""
package/signed=true
package/app_category=6
package/retain_data_on_uninstall=false
package/exclude_from_recents=false
package/show_in_android_tv=false
package/show_in_app_library=true
package/show_as_launcher_app=false
launcher_icons/main_192x192=""
launcher_icons/adaptive_foreground_432x432=""
launcher_icons/adaptive_background_432x432=""
graphics/opengl_debug=false
xr_features/xr_mode=0
screen/immersive_mode=true
screen/support_small=true
screen/support_normal=true
screen/support_large=true
screen/support_xlarge=true
user_data_backup/allow=false
command_line/extra_args=""
apk_expansion/enable=false
apk_expansion/SALT=""
apk_expansion/public_key=""
permissions/custom_permissions=PackedStringArray()
permissions/access_checkin_properties=false
permissions/access_coarse_location=false
permissions/access_fine_location=false
permissions/access_location_extra_commands=false
permissions/access_mock_location=false
permissions/access_network_state=false
permissions/access_surface_flinger=false
permissions/access_wifi_state=false
permissions/account_manager=false
permissions/add_voicemail=false
permissions/authenticate_accounts=false
permissions/battery_stats=false
permissions/bind_accessibility_service=false
permissions/bind_appwidget=false
permissions/bind_device_admin=false
permissions/bind_input_method=false
permissions/bind_nfc_service=false
permissions/bind_notification_listener_service=false
permissions/bind_print_service=false
permissions/bind_remoteviews=false
permissions/bind_text_service=false
permissions/bind_vpn_service=false
permissions/bind_wallpaper=false
permissions/bluetooth=false
permissions/bluetooth_admin=false
permissions/bluetooth_privileged=false
permissions/brick=false
permissions/broadcast_package_removed=false
permissions/broadcast_sms=false
permissions/broadcast_sticky=false
permissions/broadcast_wap_push=false
permissions/call_phone=false
permissions/call_privileged=false
permissions/camera=false
permissions/capture_audio_output=false
permissions/capture_secure_video_output=false
permissions/capture_video_output=false
permissions/change_component_enabled_state=false
permissions/change_configuration=false
permissions/change_network_state=false
permissions/change_wifi_multicast_state=false
permissions/change_wifi_state=false
permissions/clear_app_cache=false
permissions/clear_app_user_data=false
permissions/control_location_updates=false
permissions/delete_cache_files=false
permissions/delete_packages=false
permissions/device_power=false
permissions/diagnostic=false
permissions/disable_keyguard=false
permissions/dump=false
permissions/expand_status_bar=false
permissions/factory_test=false
permissions/flashlight=false
permissions/force_back=false
permissions/get_accounts=false
permissions/get_package_size=false
permissions/get_tasks=false
permissions/get_top_activity_info=false
permissions/global_search=false
permissions/hardware_test=false
permissions/inject_events=false
permissions/install_location_provider=false
permissions/install_packages=false
permissions/install_shortcut=false
permissions/internal_system_window=false
permissions/internet=false
permissions/kill_background_processes=false
permissions/location_hardware=false
permissions/manage_accounts=false
permissions/manage_app_tokens=false
permissions/manage_documents=false
permissions/manage_external_storage=false
permissions/master_clear=false
permissions/media_content_control=false
permissions/modify_audio_settings=false
permissions/modify_phone_state=false
permissions/mount_format_filesystems=false
permissions/mount_unmount_filesystems=false
permissions/nfc=false
permissions/persistent_activity=false
permissions/post_notifications=false
permissions/process_outgoing_calls=false
permissions/read_calendar=false
permissions/read_call_log=false
permissions/read_contacts=false
permissions/read_external_storage=false
permissions/read_frame_buffer=false
permissions/read_history_bookmarks=false
permissions/read_input_state=false
permissions/read_logs=false
permissions/read_phone_state=false
permissions/read_profile=false
permissions/read_sms=false
permissions/read_social_stream=false
permissions/read_sync_settings=false
permissions/read_sync_stats=false
permissions/read_user_dictionary=false
permissions/reboot=false
permissions/receive_boot_completed=false
permissions/receive_mms=false
permissions/receive_sms=false
permissions/receive_wap_push=false
permissions/record_audio=false
permissions/reorder_tasks=false
permissions/restart_packages=false
permissions/send_respond_via_message=false
permissions/send_sms=false
permissions/set_activity_watcher=false
permissions/set_alarm=false
permissions/set_always_finish=false
permissions/set_animation_scale=false
permissions/set_debug_app=false
permissions/set_orientation=false
permissions/set_pointer_speed=false
permissions/set_preferred_applications=false
permissions/set_process_limit=false
permissions/set_time=false
permissions/set_time_zone=false
permissions/set_wallpaper=false
permissions/set_wallpaper_hints=false
permissions/signal_persistent_processes=false
permissions/status_bar=false
permissions/subscribed_feeds_read=false
permissions/subscribed_feeds_write=false
permissions/system_alert_window=false
permissions/transmit_ir=false
permissions/uninstall_shortcut=false
permissions/update_device_stats=false
permissions/use_credentials=false
permissions/use_sip=false
permissions/vibrate=false
permissions/wake_lock=false
permissions/write_apn_settings=false
permissions/write_calendar=false
permissions/write_call_log=false
permissions/write_contacts=false
permissions/write_external_storage=false
permissions/write_gservices=false
permissions/write_history_bookmarks=false
permissions/write_profile=false
permissions/write_secure_settings=false
permissions/write_settings=false
permissions/write_sms=false
permissions/write_social_stream=false
permissions/write_sync_settings=false
permissions/write_user_dictionary=false
dotnet/include_scripts_content=false
dotnet/include_debug_symbols=false
dotnet/embed_build_outputs=false

1
icon.svg Normal file
View File

@ -0,0 +1 @@
<svg height="128" width="128" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" width="124" height="124" rx="14" fill="#363d52" stroke="#212532" stroke-width="4"/><g transform="scale(.101) translate(122 122)"><g fill="#fff"><path d="M105 673v33q407 354 814 0v-33z"/><path d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z" fill="#478cbf"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></g></svg>

After

Width:  |  Height:  |  Size: 949 B

37
icon.svg.import Normal file
View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d4gjit28wdndu"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

36
override.cfg Normal file
View File

@ -0,0 +1,36 @@
; Project settings override file.
; Adds gamepad inputs to built-in actions.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
[input]
ui_accept={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194309,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194310,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":32,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":true,"script":null)
]
}
ui_cancel={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194305,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":6,"pressure":0.0,"pressed":true,"script":null)
]
}
ui_page_up={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194323,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":9,"pressure":0.0,"pressed":true,"script":null)
]
}
ui_page_down={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194324,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":10,"pressure":0.0,"pressed":true,"script":null)
]
}

56
project.godot Normal file
View File

@ -0,0 +1,56 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="Talkpal"
run/main_scene="res://scenes/main/main_mobile.tscn"
config/features=PackedStringArray("4.2", "GL Compatibility")
boot_splash/bg_color=Color(0.800491, 0.800491, 0.800491, 1)
boot_splash/image="res://assets/comfortel_logo.png"
config/icon="res://assets/comfortel_logo.png"
[autoload]
AppConfig="*res://addons/maaacks_menus_template/base/scenes/autoloads/app_config.tscn"
SceneLoader="*res://addons/maaacks_menus_template/base/scenes/autoloads/scene_loader.tscn"
ProjectMusicController="*res://addons/maaacks_menus_template/base/scenes/autoloads/project_music_controller.tscn"
ProjectUISoundController="*res://addons/maaacks_menus_template/base/scenes/autoloads/project_ui_sound_controller.tscn"
uuid="*res://addons/uuid/uuid.gd"
[display]
window/size/viewport_width=1080
window/size/viewport_height=2340
window/stretch/aspect="keep_width"
window/handheld/orientation=1
[dotnet]
project/assembly_name="Talkpal Frontend"
[editor_plugins]
enabled=PackedStringArray("res://addons/maaacks_menus_template/plugin.cfg", "res://addons/uuid/plugin.cfg")
[internationalization]
locale/translations=PackedStringArray("res://addons/maaacks_menus_template/base/translations/menus_translations.en.translation", "res://addons/maaacks_menus_template/base/translations/menus_translations.fr.translation")
[maaacks_menus_template]
disable_plugin_dialogues=true
copy_path="res://"
[rendering]
renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"
textures/vram_compression/import_etc2_astc=true

121
scenes/board/board.gd Normal file
View File

@ -0,0 +1,121 @@
extends VBoxContainer
const TimeSlot = preload("res://scenes/board/time_slot.tscn")
const ReservationScene = preload("res://scenes/board/reservation.tscn")
const ReservationIndent = preload("res://scenes/board/reservation_indent.tscn")
const WorkingDayStart = 8
const WorkingDayEnd = 21
const MinimalMinutesToShowTitle = 30
const MockedSchedule = [
{
"title": "Психолог",
"start_time": 120,
"end_time": 180,
"color": 1
},
{
"title": "Дипал",
"start_time": 180,
"end_time": 210,
"color": 2
},
{
"title": "Маркетинг",
"start_time": 280,
"end_time": 325,
"color": 3
}
]
@onready var _main: Main = get_tree().get_current_scene()
@onready var _timeline = $Panel/Timeline
@onready var _reservations = $Panel/Reservations
func _ready():
_remove_time_slots()
_remove_reservations()
_fill_with_slots()
_update_schedule()
func _remove_time_slots():
for time_slot in _timeline.get_children():
time_slot.queue_free()
func _fill_with_slots():
for hour in range(WorkingDayStart, WorkingDayEnd):
var slot = TimeSlot.instantiate()
_timeline.add_child(slot)
slot.set_time(hour)
func _remove_reservations():
for reservation in _reservations.get_children():
reservation.queue_free()
func _update_schedule():
if not _main.is_node_ready():
await _main.ready
var repo = _main.get_reservation_repo()
var previous_finish_time = 0
for reservation in repo.list_reservations():
var start_time_hours = reservation.start_time['hours']
var start_time_minutes = reservation.start_time['minutes']
var start_time = (start_time_hours - WorkingDayStart)*60 + start_time_minutes
var finish_time_hours = reservation.finish_time['hours']
var finish_time_minutes = reservation.finish_time['minutes']
var finish_time = (finish_time_hours - WorkingDayStart)*60 + finish_time_minutes
var reservation_time = finish_time - start_time
_compose_indent(start_time - previous_finish_time)
_compose_reservation(reservation_time, reservation.title, reservation.color)
previous_finish_time = finish_time
func _compose_indent(minutes):
var indent = ReservationIndent.instantiate()
_reservations.add_child(indent)
indent.set_minutes(minutes)
func _compose_reservation(minutes, title, color):
if minutes <= MinimalMinutesToShowTitle:
title = ""
var reservation = ReservationScene.instantiate()
_reservations.add_child(reservation)
reservation.set_minutes(minutes)
reservation.set_title(title)
reservation.set_color(color)
func _input(event):
if event is InputEventScreenTouch or (event is InputEventMouseButton and event.pressed):
if _clicked_on_timeline(event.position):
await get_tree().create_timer(0.01, false).timeout
if _main.get_current_page() == Main.Pages.Board:
_main.load_page(Main.Pages.ReservationCreation)
func _clicked_on_timeline(pos: Vector2):
var timeline_position = _timeline.global_position
return (
pos.x > timeline_position.x and
pos.x < _timeline.size.x + timeline_position.x
) and (
pos.y > timeline_position.y and
pos.y < _timeline.size.y + timeline_position.y
)
func _on_room_button_pressed():
print("emit change room signal")
func _on_date_button_pressed():
print("emit change date signal")
func update():
_ready()

57
scenes/board/board.tscn Normal file
View File

@ -0,0 +1,57 @@
[gd_scene load_steps=6 format=3 uid="uid://c431r28ef5edp"]
[ext_resource type="Script" path="res://scenes/board/board.gd" id="1_2wgc4"]
[ext_resource type="Theme" uid="uid://cmhwbyqu6nh38" path="res://assets/themes/big.tres" id="1_na0ey"]
[ext_resource type="PackedScene" uid="uid://cnr23ry08ntv4" path="res://scenes/board/time_slot.tscn" id="2_kklmx"]
[ext_resource type="PackedScene" uid="uid://blv30rxduydmw" path="res://scenes/board/reservation_indent.tscn" id="3_mltgm"]
[ext_resource type="PackedScene" uid="uid://dpi5ft4r8sfwb" path="res://scenes/board/reservation.tscn" id="4_o5rhy"]
[node name="Board" type="VBoxContainer"]
anchors_preset = 10
anchor_right = 1.0
offset_bottom = 75.0
grow_horizontal = 2
theme_override_constants/separation = 50
script = ExtResource("1_2wgc4")
[node name="TopBar" type="HBoxContainer" parent="."]
layout_mode = 2
[node name="RoomButton" type="Button" parent="TopBar"]
layout_mode = 2
theme = ExtResource("1_na0ey")
text = "Переговорка 1"
[node name="DateButton" type="Button" parent="TopBar"]
layout_mode = 2
size_flags_horizontal = 10
theme = ExtResource("1_na0ey")
text = "Вт, 14 июн. 2022"
[node name="Panel" type="Control" parent="."]
layout_mode = 2
[node name="Timeline" type="VBoxContainer" parent="Panel"]
layout_mode = 2
offset_top = 50.0
offset_right = 1036.0
offset_bottom = 354.0
[node name="TimeSlot" parent="Panel/Timeline" instance=ExtResource("2_kklmx")]
layout_mode = 2
[node name="TimeSlot2" parent="Panel/Timeline" instance=ExtResource("2_kklmx")]
layout_mode = 2
[node name="Reservations" type="VBoxContainer" parent="Panel"]
layout_mode = 2
offset_top = 50.0
offset_right = 1036.0
offset_bottom = 117.0
grow_horizontal = 2
[node name="Indent" parent="Panel/Reservations" instance=ExtResource("3_mltgm")]
layout_mode = 2
[node name="Reservation" parent="Panel/Reservations" instance=ExtResource("4_o5rhy")]
layout_mode = 2

View File

@ -0,0 +1,36 @@
extends HBoxContainer
class_name Reservation
const HourSize = 150
const Colors = {
1: Color("00b1a1d6"),
2: Color("f431e0d6"),
3: Color("eb7130d6")
}
@onready var _main: Main = get_tree().get_current_scene()
@onready var _title = $Section/SectionLabel
@onready var _panel = $Section/SectionPanel
func _ready():
initialize_signals()
func initialize_signals():
_panel.gui_input.connect(_on_section_panel_gui_input)
func set_title(title):
_title.text = title
func set_minutes(minutes):
_panel.size.y = minutes * HourSize / 60
custom_minimum_size.y = _panel.size.y
func set_color(color):
var new_style_box: StyleBoxFlat = _panel.get("theme_override_styles/panel").duplicate()
new_style_box.bg_color = Colors[color]
_panel.set("theme_override_styles/panel", new_style_box)
func _on_section_panel_gui_input(event):
if event is InputEventScreenTouch or (event is InputEventMouseButton and event.pressed):
print("emit open reservation info signal")

View File

@ -0,0 +1,40 @@
[gd_scene load_steps=4 format=3 uid="uid://dpi5ft4r8sfwb"]
[ext_resource type="Script" path="res://scenes/board/reservation.gd" id="1_drhpx"]
[ext_resource type="Theme" uid="uid://cmhwbyqu6nh38" path="res://assets/themes/big.tres" id="2_vfg04"]
[ext_resource type="StyleBox" uid="uid://crantichmjy77" path="res://assets/themes/panel_cyan.tres" id="3_xwx35"]
[node name="Reservation" type="HBoxContainer"]
custom_minimum_size = Vector2(0, 200)
offset_right = 157.0
offset_bottom = 200.0
script = ExtResource("1_drhpx")
[node name="Indent" type="Label" parent="."]
layout_mode = 2
theme = ExtResource("2_vfg04")
theme_override_colors/font_color = Color(0, 0, 0, 0)
text = "11:00 "
[node name="Section" type="Control" parent="."]
layout_mode = 2
[node name="SectionPanel" type="Panel" parent="Section"]
layout_mode = 1
offset_right = 883.0
offset_bottom = 200.0
size_flags_horizontal = 3
theme_override_styles/panel = ExtResource("3_xwx35")
[node name="SectionLabel" type="Label" parent="Section"]
layout_mode = 1
anchors_preset = 4
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = 50.0
offset_top = -33.5
offset_right = 396.0
offset_bottom = 33.5
grow_vertical = 2
theme = ExtResource("2_vfg04")
text = "Интервью C++"

View File

@ -0,0 +1,6 @@
extends Control
const HourSize = 150
func set_minutes(minutes):
custom_minimum_size.y = minutes * HourSize / 60

View File

@ -0,0 +1,9 @@
[gd_scene load_steps=2 format=3 uid="uid://blv30rxduydmw"]
[ext_resource type="Script" path="res://scenes/board/reservation_indent.gd" id="1_pq834"]
[node name="Indent" type="Control"]
custom_minimum_size = Vector2(0, 50)
layout_mode = 3
anchors_preset = 0
script = ExtResource("1_pq834")

View File

@ -0,0 +1,6 @@
extends HBoxContainer
@onready var _time_label = $TimeLabelControl/TimeLabel
func set_time(hour):
_time_label.text = str(hour) + ":00"

View File

@ -0,0 +1,62 @@
[gd_scene load_steps=4 format=3 uid="uid://cnr23ry08ntv4"]
[ext_resource type="Script" path="res://scenes/board/time_slot.gd" id="1_hwvwy"]
[ext_resource type="Theme" uid="uid://cmhwbyqu6nh38" path="res://assets/themes/big.tres" id="2_ty4oc"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_pfkqv"]
bg_color = Color(0.6, 0.6, 0.6, 0)
border_width_left = 3
border_width_top = 3
border_width_bottom = 3
border_blend = true
corner_radius_top_left = 5
corner_radius_top_right = 5
corner_radius_bottom_right = 5
corner_radius_bottom_left = 5
[node name="TimeSlot" type="HBoxContainer"]
custom_minimum_size = Vector2(0, 150)
theme_override_constants/separation = 25
script = ExtResource("1_hwvwy")
[node name="Indent" type="Label" parent="."]
layout_mode = 2
theme = ExtResource("2_ty4oc")
text = " "
[node name="TimeLabelControl" type="Control" parent="."]
layout_mode = 2
[node name="TimeLabel" type="Label" parent="TimeLabelControl"]
layout_mode = 1
anchors_preset = 6
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_left = -121.0
offset_top = -33.5
offset_bottom = 33.5
grow_horizontal = 0
grow_vertical = 2
theme = ExtResource("2_ty4oc")
text = "11:00"
[node name="Section" type="Panel" parent="."]
layout_mode = 2
size_flags_horizontal = 3
theme_override_styles/panel = SubResource("StyleBoxFlat_pfkqv")
[node name="EventsContainer" type="GridContainer" parent="."]
visible = false
layout_mode = 2
[node name="Event" type="Button" parent="EventsContainer"]
layout_mode = 2
theme = ExtResource("2_ty4oc")
text = "Переговоры с Клиентами"
[node name="Event2" type="Button" parent="EventsContainer"]
layout_mode = 2
theme = ExtResource("2_ty4oc")
text = "Интервью C#"

View File

@ -0,0 +1 @@
extends Control

View File

@ -0,0 +1,20 @@
[gd_scene load_steps=3 format=3 uid="uid://drdv8adk1wi8f"]
[ext_resource type="Script" path="res://scenes/common/calendar/calendar_edit.gd" id="1_jxhnl"]
[ext_resource type="Theme" uid="uid://cmhwbyqu6nh38" path="res://assets/themes/big.tres" id="2_e6eik"]
[node name="Calendar" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_jxhnl")
[node name="Button" type="Button" parent="."]
layout_mode = 0
offset_right = 24.0
offset_bottom = 31.0
theme = ExtResource("2_e6eik")
text = "Открыть календарь"

View File

@ -0,0 +1,86 @@
@tool
extends HBoxContainer
enum Type {
Line,
Text,
Calendar,
Time
}
@export var title : String:
set(value):
title = value
set_title(title)
@export var type := Type.Line:
set(value):
type = value
set_type(type)
@onready var _label = $FieldLabelControl/FieldLabel
@onready var _line = $Line
@onready var _calendar = $Calendar
@onready var _time = $Time
@onready var _text = $Text
var _type
func _ready():
set_title(title)
set_type(type)
func set_title(new_title):
if _label == null:
await ready
_label.text = new_title
func get_value():
match _type:
Type.Line:
return _line.text
Type.Text:
return _text.text
Type.Calendar:
return ""
Type.Time:
return {
"hours": _time.get_hours(),
"minutes": _time.get_minutes()
}
func set_value(value):
_line.text = value
func set_type(type):
if _line == null:
await ready
_line.visible = false
_text.visible = false
_calendar.visible = false
_time.visible = false
_type = type
match type:
Type.Line:
_line.visible = true
Type.Text:
_text.visible = true
Type.Calendar:
_calendar.visible = true
Type.Time:
_time.visible = true
func clean():
match _type:
Type.Line:
_line.text = ""
Type.Text:
_text.text = ""
Type.Calendar:
pass
Type.Time:
_time.clean()

View File

@ -0,0 +1,53 @@
[gd_scene load_steps=6 format=3 uid="uid://d0fdiesiaajlq"]
[ext_resource type="Script" path="res://scenes/common/edit_field.gd" id="1_sdy7t"]
[ext_resource type="Theme" uid="uid://7lcget51crj1" path="res://assets/themes/medium.tres" id="1_v1b42"]
[ext_resource type="Theme" uid="uid://cmhwbyqu6nh38" path="res://assets/themes/big.tres" id="2_iq8f3"]
[ext_resource type="PackedScene" uid="uid://drdv8adk1wi8f" path="res://scenes/common/calendar/calendar_edit.tscn" id="4_hlx5p"]
[ext_resource type="PackedScene" uid="uid://bhd0xvnvoqslr" path="res://scenes/common/time/time_edit.tscn" id="5_d0drs"]
[node name="EditField" type="HBoxContainer"]
anchors_preset = 10
anchor_right = 1.0
offset_bottom = 67.0
grow_horizontal = 2
theme_override_constants/separation = 25
script = ExtResource("1_sdy7t")
[node name="FieldLabelControl" type="Control" parent="."]
layout_mode = 2
[node name="FieldLabel" type="Label" parent="FieldLabelControl"]
layout_mode = 2
offset_left = 25.0
offset_top = 4.0
offset_right = 231.0
offset_bottom = 62.0
theme = ExtResource("1_v1b42")
[node name="Indent" type="Label" parent="."]
layout_mode = 2
theme = ExtResource("2_iq8f3")
text = " "
[node name="Line" type="LineEdit" parent="."]
layout_mode = 2
size_flags_horizontal = 3
theme = ExtResource("2_iq8f3")
[node name="Text" type="TextEdit" parent="."]
visible = false
layout_mode = 2
size_flags_horizontal = 3
theme = ExtResource("2_iq8f3")
wrap_mode = 1
scroll_fit_content_height = true
[node name="Calendar" parent="." instance=ExtResource("4_hlx5p")]
visible = false
layout_mode = 2
[node name="Time" parent="." instance=ExtResource("5_d0drs")]
visible = false
layout_mode = 2
size_flags_horizontal = 3

View File

@ -0,0 +1,41 @@
extends Control
@onready var _main: Main = get_tree().get_current_scene()
@onready var _edit := $Edit
var _hours := 0
var _minutes := 0
var _time_setting_page
func _ready():
initialize_signals()
func initialize_signals():
_edit.focus_entered.connect(_on_click)
func _on_click():
if _main.get_current_page() == Main.Pages.TimeSetting:
return
_time_setting_page = _main.load_page(Main.Pages.TimeSetting)
_time_setting_page.time_is_set.connect(self._on_time_is_set)
func _on_time_is_set(hours: int, minutes: int):
_time_setting_page.time_is_set.disconnect(_on_time_is_set)
_edit.text = str(hours) + ":" + _correct_minutes(str(minutes))
_hours = hours
_minutes = minutes
func _correct_minutes(value):
return "0" + value if len(value) == 1 else value
func get_hours():
return _hours
func get_minutes():
return _minutes
func clean():
_hours = 0
_minutes = 0
_edit.text = ""

View File

@ -0,0 +1,31 @@
[gd_scene load_steps=4 format=3 uid="uid://bhd0xvnvoqslr"]
[ext_resource type="Script" path="res://scenes/common/time/time_edit.gd" id="1_2wxyg"]
[ext_resource type="Script" path="res://addons/date-time-elements/scripts/time-input.gd" id="2_7d4ae"]
[ext_resource type="Theme" uid="uid://cmhwbyqu6nh38" path="res://assets/themes/big.tres" id="3_bpvuo"]
[node name="Time" type="BoxContainer"]
anchors_preset = 10
anchor_right = 1.0
offset_bottom = 75.0
grow_horizontal = 2
script = ExtResource("1_2wxyg")
[node name="TimeEdit" type="LineEdit" parent="."]
visible = false
layout_mode = 2
text = "21:15 "
placeholder_text = "hh:mm (a/p)m"
script = ExtResource("2_7d4ae")
current_time = true
[node name="Edit" type="LineEdit" parent="."]
layout_mode = 2
size_flags_horizontal = 3
theme = ExtResource("3_bpvuo")
virtual_keyboard_enabled = false
[connection signal="mouse_entered" from="TimeEdit/Clock" to="TimeEdit/Clock" method="_on_mouse_entered"]
[connection signal="mouse_exited" from="TimeEdit/Clock" to="TimeEdit/Clock" method="_on_mouse_exited"]
[connection signal="visibility_changed" from="TimeEdit/Clock" to="TimeEdit/Clock" method="_on_visibility_changed"]
[connection signal="draw" from="TimeEdit/ManualClock" to="TimeEdit/ManualClock" method="_on_draw"]

View File

@ -0,0 +1,40 @@
@tool
extends Marker2D
@onready var number = $Number
@onready var number_label = $Number/Label
@export_range(0, 12, 1, "o'clock") var part : float:
set(value):
part = value
set_part(part)
@export var value : int:
set(new_value):
value = new_value
await ready
set_value(value)
var _part: float
var _value: int
func _process(delta):
number.rotation = -rotation
func set_part(value):
_part = value
var new_rotation = 2*PI * value / 12
rotation = new_rotation
func get_part():
return _part
func set_value(new_value):
_value = new_value
number_label.text = str(new_value)
func get_value():
return _value
func get_number_position():
return number.global_position

View File

@ -0,0 +1,54 @@
[gd_scene load_steps=4 format=3 uid="uid://3omkos3a4po7"]
[ext_resource type="Theme" uid="uid://cmhwbyqu6nh38" path="res://assets/themes/big.tres" id="1_ne7tv"]
[ext_resource type="Script" path="res://scenes/common/time/time_hand.gd" id="1_tiohc"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_5bs5k"]
bg_color = Color(1, 1, 1, 0)
corner_radius_top_left = 250
corner_radius_top_right = 250
corner_radius_bottom_right = 250
corner_radius_bottom_left = 250
anti_aliasing_size = 0.01
[node name="Hand" type="Marker2D"]
script = ExtResource("1_tiohc")
[node name="TapArea" type="Panel" parent="."]
modulate = Color(0.282353, 0.580392, 0.235294, 1)
offset_left = -44.0
offset_top = -345.0
offset_right = 45.0
offset_bottom = -256.0
theme_override_styles/panel = SubResource("StyleBoxFlat_5bs5k")
[node name="Number" type="Control" parent="."]
layout_mode = 3
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_top = -301.0
offset_right = 1.0
offset_bottom = -301.0
grow_horizontal = 2
grow_vertical = 2
[node name="Label" type="Label" parent="Number"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -27.0
offset_top = -34.0
offset_right = 27.0
offset_bottom = 33.0
grow_horizontal = 2
grow_vertical = 2
theme = ExtResource("1_ne7tv")
text = "20"
horizontal_alignment = 1
vertical_alignment = 1

View File

@ -0,0 +1,175 @@
extends Control
const TimeHand = preload("res://scenes/common/time/time_hand.tscn")
const WorkingDayStart = 8
const WorkingDayEnd = 21
const DigitsNumber = 12
enum State {
SettingHours,
SettingMinutes
}
@export var number_flash_time := 0.5
@onready var _main: Main = get_tree().get_current_scene()
@onready var _hours_label = $VerticalBar/Time/Hours
@onready var _minutes_label = $VerticalBar/Time/Minutes
@onready var _time = $VerticalBar/Time
@onready var _face = $VerticalBar/Circle/Face
@onready var _arrow = $VerticalBar/Circle/Clock/Arrow
@onready var _numbers = $VerticalBar/Circle/Clock/Numbers
var _hours : int
var _minutes : int
var _state := State.SettingHours
var _time_after_last_flash := 0.0
signal time_is_set(hours: int, minutes: int)
func _ready():
_set_initial_values()
_start_hours_setting()
func _set_initial_values():
_hours = WorkingDayStart
_minutes = 0
func _process(delta):
if _time_after_last_flash >= number_flash_time:
_flash_number()
_time_after_last_flash = 0.0
_time_after_last_flash += delta
func _flash_number():
match _state:
State.SettingHours:
_hours_label.text = str(_hours) \
if _hours_label.text == '_' else '_'
State.SettingMinutes:
_minutes_label.text = _correct_minutes(str(_minutes)) \
if _minutes_label.text == '_' else '_'
func _fill_with_hours():
_remove_numbers()
for part in range(0, DigitsNumber):
var number = TimeHand.instantiate()
_numbers.add_child(number)
number.set_part(part)
number.set_value(WorkingDayStart + part)
func _fill_with_minutes():
_remove_numbers()
for part in range(0, DigitsNumber):
var number = TimeHand.instantiate()
_numbers.add_child(number)
number.set_part(part)
number.set_value(5*part)
func _remove_numbers():
for number in _numbers.get_children():
number.queue_free()
func _clicked_on_face(pos: Vector2):
var face_position = _face.global_position
return (pos.x > face_position.x and pos.x < _face.size.x + face_position.x) and \
(pos.y > face_position.y and pos.y < _face.size.y + face_position.y)
func _clicked_on_time(pos: Vector2):
var time_position = _time.global_position
return (pos.x > time_position.x and pos.x < _time.size.x + time_position.x) and \
(pos.y > time_position.y and pos.y < _time.size.y + time_position.y)
func _input(event):
if not _main.get_current_page() == Main.Pages.TimeSetting:
return
if (event is InputEventScreenTouch and event.pressed) or \
(event is InputEventMouseButton and event.pressed): # TODO: call on click or release, do not do anything if it was clicked
if _clicked_on_face(event.position):
var number = _get_closest_number(event.position)
_arrow.rotation = number.rotation
match _state:
State.SettingHours:
set_hours(number.get_value())
await get_tree().create_timer(0.01, false).timeout
_start_minutes_setting()
State.SettingMinutes:
set_minutes(number.get_value())
time_is_set.emit(_hours, _minutes)
await get_tree().create_timer(0.01, false).timeout
_main.go_to_previous_page()
_ready()
elif _clicked_on_time(event.position):
match _get_closest_unit(event.position):
_hours_label:
_start_hours_setting()
_minutes_label:
_start_minutes_setting()
await event.is_released() == true
func _get_closest_number(pos: Vector2):
var min_distance = INF
var sought = null
for number in _numbers.get_children():
var distance = number.get_number_position().distance_to(pos)
if (distance < min_distance):
min_distance = distance
sought = number
return sought
func _get_closest_unit(pos: Vector2):
var min_distance = INF
var sought = null
for unit in _time.get_children():
var distance = unit.global_position.distance_to(pos)
if (distance < min_distance):
min_distance = distance
sought = unit
return sought
func set_hours(value):
_hours = value
_update_time()
func get_hours():
return _hours
func set_minutes(value):
_minutes = value
_update_time()
func get_minutes():
return _minutes
func _update_time():
_arrow.rotation = 0.0
_hours_label.text = str(_hours)
_minutes_label.text = _correct_minutes(str(_minutes))
func _correct_minutes(value):
return "0" + value if len(value) == 1 else value
func _start_hours_setting():
_state = State.SettingHours
_fill_with_hours()
_update_time()
func _start_minutes_setting():
_state = State.SettingMinutes
_fill_with_minutes()
_update_time()
func update():
_ready()

View File

@ -0,0 +1,131 @@
[gd_scene load_steps=7 format=3 uid="uid://cxs8xe5w32jo4"]
[ext_resource type="Script" path="res://scenes/common/time/time_setting.gd" id="1_2uqfu"]
[ext_resource type="Texture2D" uid="uid://d0llucl6yfmwj" path="res://assets/textures/time_setting.tres" id="2_6xoc0"]
[ext_resource type="Theme" uid="uid://c5nehi7j4wsjd" path="res://assets/themes/time_font.tres" id="3_gngar"]
[ext_resource type="PackedScene" uid="uid://3omkos3a4po7" path="res://scenes/common/time/time_hand.tscn" id="4_g84y5"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_23ktd"]
bg_color = Color(1, 1, 1, 1)
corner_radius_top_left = 250
corner_radius_top_right = 250
corner_radius_bottom_right = 250
corner_radius_bottom_left = 250
anti_aliasing_size = 0.01
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_5mbj6"]
bg_color = Color(1, 1, 1, 1)
[node name="TimeSetting" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_2uqfu")
[node name="VerticalBar" type="VBoxContainer" parent="."]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -20.0
offset_top = -20.0
offset_right = 20.0
offset_bottom = 20.0
grow_horizontal = 2
grow_vertical = 2
[node name="Time" type="HBoxContainer" parent="VerticalBar"]
layout_mode = 2
theme = ExtResource("3_gngar")
alignment = 1
[node name="Hours" type="Label" parent="VerticalBar/Time"]
layout_mode = 2
text = "_"
[node name="_" type="Label" parent="VerticalBar/Time"]
layout_mode = 2
text = ":"
[node name="Minutes" type="Label" parent="VerticalBar/Time"]
layout_mode = 2
text = "00"
[node name="Circle" type="TextureRect" parent="VerticalBar"]
layout_mode = 2
texture = ExtResource("2_6xoc0")
[node name="Face" type="Control" parent="VerticalBar/Circle"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -350.0
offset_top = -350.0
offset_right = 350.0
offset_bottom = 350.0
grow_horizontal = 2
grow_vertical = 2
[node name="Clock" type="Control" parent="VerticalBar/Circle"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
grow_horizontal = 2
grow_vertical = 2
[node name="Arrow" type="Marker2D" parent="VerticalBar/Circle/Clock"]
[node name="Center" type="Panel" parent="VerticalBar/Circle/Clock/Arrow"]
modulate = Color(0.282353, 0.580392, 0.235294, 1)
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -7.5
offset_top = -7.5
offset_right = 7.5
offset_bottom = 7.5
grow_horizontal = 2
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_23ktd")
metadata/_edit_use_anchors_ = true
[node name="Circle" type="Panel" parent="VerticalBar/Circle/Clock/Arrow"]
modulate = Color(0.282353, 0.580392, 0.235294, 1)
offset_left = -44.0
offset_top = -345.0
offset_right = 45.0
offset_bottom = -256.0
theme_override_styles/panel = SubResource("StyleBoxFlat_23ktd")
[node name="Panel" type="Panel" parent="VerticalBar/Circle/Clock/Arrow"]
modulate = Color(0.282353, 0.580392, 0.235294, 1)
offset_left = 2.0
offset_top = 2.0
offset_right = 6.0
offset_bottom = 274.0
rotation = 3.14159
theme_override_styles/panel = SubResource("StyleBoxFlat_5mbj6")
[node name="Numbers" type="Control" parent="VerticalBar/Circle/Clock"]
anchors_preset = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="Hand" parent="VerticalBar/Circle/Clock/Numbers" instance=ExtResource("4_g84y5")]
[node name="Hand2" parent="VerticalBar/Circle/Clock/Numbers" instance=ExtResource("4_g84y5")]
[node name="Hand3" parent="VerticalBar/Circle/Clock/Numbers" instance=ExtResource("4_g84y5")]

View File

@ -0,0 +1,48 @@
@tool
extends Control
class_name Main
enum Pages {
Board,
ReservationCreation,
TimeSetting
}
@onready var _reservation_repo : AbstractReservationRepo = $Repos/Reservation
@export var current_page : Pages:
set(value):
current_page = value
load_page(value, false)
@onready var _pages := {
Pages.Board: $Pages/Board,
Pages.ReservationCreation: $Pages/ReservationCreation,
Pages.TimeSetting: $Pages/TimeSetting
}
var _current_page := Pages.Board
var _previous_page : Pages
func get_current_page():
return _current_page
func load_page(value, with_update=true):
_pages[_current_page].visible = false
if _previous_page != _current_page:
_previous_page = _current_page
_current_page = value
if with_update:
_pages[_current_page].update()
_pages[_current_page].visible = true
return _pages[_current_page]
func go_to_previous_page():
if _previous_page != null:
load_page(_previous_page)
func get_reservation_repo() -> AbstractReservationRepo:
return _reservation_repo

View File

@ -0,0 +1,58 @@
[gd_scene load_steps=6 format=3 uid="uid://drqy50fps66oy"]
[ext_resource type="Script" path="res://scenes/main/main_mobile.gd" id="1_vo4ao"]
[ext_resource type="PackedScene" uid="uid://c431r28ef5edp" path="res://scenes/board/board.tscn" id="2_brvql"]
[ext_resource type="PackedScene" uid="uid://csfn8q6b5hj4y" path="res://scenes/reservation/reservation_creation.tscn" id="3_qr4p2"]
[ext_resource type="PackedScene" uid="uid://cxs8xe5w32jo4" path="res://scenes/common/time/time_setting.tscn" id="4_popa2"]
[ext_resource type="Script" path="res://src/infra/repos/local/reservation.gd" id="5_50dbn"]
[node name="Main" type="Control"]
layout_mode = 3
anchor_left = 0.02
anchor_top = 0.01
anchor_right = 0.98
anchor_bottom = 0.99
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_vo4ao")
[node name="BackgroundColor" type="ColorRect" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0.133333, 0.14902, 0.176471, 1)
[node name="Pages" type="Control" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="Board" parent="Pages" instance=ExtResource("2_brvql")]
layout_mode = 1
anchors_preset = 15
anchor_bottom = 1.0
offset_bottom = 0.0
grow_vertical = 2
[node name="ReservationCreation" parent="Pages" instance=ExtResource("3_qr4p2")]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_bottom = 1.0
offset_bottom = 0.0
grow_vertical = 2
[node name="TimeSetting" parent="Pages" instance=ExtResource("4_popa2")]
visible = false
layout_mode = 1
[node name="Repos" type="Node" parent="."]
[node name="Reservation" type="Node" parent="Repos"]
script = ExtResource("5_50dbn")

View File

@ -0,0 +1,115 @@
extends VBoxContainer
@onready var _main: Main = get_tree().get_current_scene()
@onready var _back_button := $TopBar/BackButton
@onready var _apply_button := $TopBar/ApplyButton
@onready var _title_field := $TitleField
@onready var _date_field := $DateField
@onready var _start_time_field := $StartTimeField
@onready var _finish_time_field := $FinishTimeField
@onready var _creator_field := $CreatorField
@onready var _room_field := $RoomField
@onready var _description_field := $DescriptionField
func _ready():
initialize_signals()
func initialize_signals():
_back_button.pressed.connect(_on_back_button_pressed)
_apply_button.pressed.connect(_on_apply_button_pressed)
func _on_back_button_pressed():
_main.load_page(Main.Pages.Board)
func _on_apply_button_pressed():
_create_reservation()
func _create_reservation():
if not _fields_are_correct():
return
var dto = CreateReservationDTO.new()
dto.title = _title_field.get_value()
dto.date = _date_field.get_value()
dto.start_time = _start_time_field.get_value()
dto.finish_time = _finish_time_field.get_value()
dto.creator = _creator_field.get_value()
dto.room_id = _room_field.get_value() # TODO: make it listbox
dto.description = _description_field.get_value()
dto.color = randi_range(1, 3)
var repo = _main.get_reservation_repo()
repo.create_reservation(dto)
dto.queue_free()
_main.load_page(Main.Pages.Board)
clean()
func _fields_are_correct():
var successful := true
if len(_title_field.get_value()) < 1:
print("The title is not entered.")
successful = false
if not _time_is_correct():
successful = false
return successful
func _time_is_correct():
var start_time = _start_time_field.get_value()
var finish_time = _finish_time_field.get_value()
var start_time_is_after_finish_time = \
start_time["hours"] > finish_time["hours"] or \
(start_time["hours"] == finish_time["hours"] and \
start_time["minutes"] >= finish_time["minutes"])
if start_time_is_after_finish_time:
print("Start time should not be more than or equal to finish time.")
return false
var repo = _main.get_reservation_repo()
var reservations = repo.list_reservations()
var new_start_time_minutes = start_time["hours"]*60 + start_time["minutes"]
var new_finish_time_minutes = finish_time["hours"]*60 + finish_time["minutes"]
for reservation in reservations:
var other_start_time = reservation.start_time
var other_finish_time = reservation.finish_time
var other_start_time_minutes = other_start_time["hours"]*60 + other_start_time["minutes"]
var other_finish_time_minutes = other_finish_time["hours"]*60 + other_finish_time["minutes"]
var is_busy = (
(
new_start_time_minutes >= other_start_time_minutes and
new_start_time_minutes < other_finish_time_minutes
) or (
new_finish_time_minutes > other_start_time_minutes and
new_finish_time_minutes <= other_finish_time_minutes
) or (
new_start_time_minutes >= other_start_time_minutes and
new_finish_time_minutes <= other_finish_time_minutes
) or (
new_start_time_minutes <= other_start_time_minutes and
new_finish_time_minutes >= other_finish_time_minutes
)
)
if is_busy:
print("The selected time slot is busy.")
return false
return true
func update():
_ready()
func clean():
_title_field.clean()
_start_time_field.clean()
_finish_time_field.clean()

View File

@ -0,0 +1,99 @@
[gd_scene load_steps=6 format=3 uid="uid://csfn8q6b5hj4y"]
[ext_resource type="Theme" uid="uid://cmhwbyqu6nh38" path="res://assets/themes/big.tres" id="1_j1bkw"]
[ext_resource type="Script" path="res://scenes/reservation/reservation_creation.gd" id="1_whumk"]
[ext_resource type="PackedScene" uid="uid://d0fdiesiaajlq" path="res://scenes/common/edit_field.tscn" id="2_qfs8j"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dlqbv"]
bg_color = Color(0.6, 0.6, 0.6, 0)
border_width_top = 5
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_yafv8"]
bg_color = Color(0.6, 0.6, 0.6, 0)
border_width_top = 3
border_color = Color(0.8, 0.8, 0.8, 0.392157)
[node name="ReservationCreation" type="VBoxContainer"]
anchors_preset = 10
anchor_right = 1.0
offset_bottom = 23.0
grow_horizontal = 2
theme_override_constants/separation = 35
script = ExtResource("1_whumk")
[node name="TopBar" type="HBoxContainer" parent="."]
layout_mode = 2
[node name="BackButton" type="Button" parent="TopBar"]
custom_minimum_size = Vector2(0, 100)
layout_mode = 2
theme = ExtResource("1_j1bkw")
text = "Назад"
[node name="Label" type="Label" parent="TopBar"]
layout_mode = 2
size_flags_horizontal = 6
theme = ExtResource("1_j1bkw")
theme_override_colors/font_shadow_color = Color(0, 0, 0, 1)
theme_override_constants/shadow_offset_x = 3
theme_override_constants/shadow_offset_y = 3
text = "Бронирование комнаты"
horizontal_alignment = 1
[node name="ApplyButton" type="Button" parent="TopBar"]
custom_minimum_size = Vector2(0, 100)
layout_mode = 2
theme = ExtResource("1_j1bkw")
text = "Создать"
[node name="Splitter" type="Panel" parent="."]
custom_minimum_size = Vector2(0, 15)
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_dlqbv")
[node name="TitleField" parent="." instance=ExtResource("2_qfs8j")]
layout_mode = 2
title = "Название"
[node name="Splitter2" type="Panel" parent="."]
custom_minimum_size = Vector2(0, 5)
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_yafv8")
[node name="DateField" parent="." instance=ExtResource("2_qfs8j")]
layout_mode = 2
title = "Дата"
type = 2
[node name="StartTimeField" parent="." instance=ExtResource("2_qfs8j")]
layout_mode = 2
title = "Начало"
type = 3
[node name="FinishTimeField" parent="." instance=ExtResource("2_qfs8j")]
layout_mode = 2
title = "Конец"
type = 3
[node name="Splitter3" type="Panel" parent="."]
custom_minimum_size = Vector2(0, 5)
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_yafv8")
[node name="CreatorField" parent="." instance=ExtResource("2_qfs8j")]
layout_mode = 2
title = "Создатель"
[node name="RoomField" parent="." instance=ExtResource("2_qfs8j")]
layout_mode = 2
title = "Комната"
[node name="Splitter4" type="Panel" parent="."]
custom_minimum_size = Vector2(0, 5)
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_yafv8")
[node name="DescriptionField" parent="." instance=ExtResource("2_qfs8j")]
layout_mode = 2
title = "Описание"
type = 1

View File

@ -0,0 +1,27 @@
[gd_scene load_steps=2 format=3 uid="uid://dcwvxdme8mjsq"]
[ext_resource type="PackedScene" uid="uid://csfn8q6b5hj4y" path="res://scenes/reservation/reservation_creation.tscn" id="1_yk1ll"]
[node name="ReservationCreation" type="Control"]
layout_mode = 3
anchor_left = 0.02
anchor_top = 0.01
anchor_right = 0.98
anchor_bottom = 0.99
grow_horizontal = 2
grow_vertical = 2
[node name="BackgroundColor" type="ColorRect" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0.133333, 0.14902, 0.176471, 1)
[node name="VerticalBar" parent="." instance=ExtResource("1_yk1ll")]
layout_mode = 0
anchors_preset = 0
anchor_right = 0.0
grow_horizontal = 1

View File

@ -0,0 +1,20 @@
extends Node
class_name ReservationEntity
var id: String
@export var title: String
@export var description: String
@export var room_id: String
@export var creator: String
@export var date: String
@export var start_time: Dictionary # TODO: get rid of dictionaries if can
@export var finish_time: Dictionary
@export var color: int

View File

@ -0,0 +1,18 @@
extends Node
class_name CreateReservationDTO
var title: String
var description: String
var room_id: String
var creator: String
var date: String
var start_time: Dictionary # TODO: get rid of dictionaries if can
var finish_time: Dictionary
var color: int

View File

@ -0,0 +1,18 @@
extends Node
class_name UpdateReservationDTO
@export var title: String
@export var description: String
@export var room_id: String
@export var creator: String
@export var date: String
@export var start_time: Dictionary # TODO: get rid of dictionaries if can
@export var finish_time: Dictionary
@export var color: int

View File

@ -0,0 +1,25 @@
extends Node
class_name AbstractReservationRepo
var _current_reservation = null
func create_reservation(dto: CreateReservationDTO):
pass
func cancel_reservation(reservation_id):
pass
func change_reservation(reservation_id, dto: UpdateReservationDTO):
pass
func get_reservation(reservation_id):
pass
func list_reservations():
pass
func set_current_reservation(value):
_current_reservation = value
func get_current_reservation(value):
return _current_reservation

View File

@ -0,0 +1,54 @@
extends AbstractReservationRepo
class_name LocalReservationRepo
const uuid_util = preload('res://addons/uuid/uuid.gd')
var _reservations = {}
func create_reservation(dto: CreateReservationDTO):
var entity = ReservationEntity.new()
entity.id = uuid_util.v4()
entity.title = dto.title
entity.description = dto.description
entity.room_id = dto.room_id
entity.creator = dto.creator
entity.date = dto.date
entity.start_time = dto.start_time.duplicate(true)
entity.finish_time = dto.finish_time.duplicate(true)
entity.color = dto.color
_reservations[entity.id] = entity
func cancel_reservation(reservation_id):
_reservations[reservation_id].queue_free()
_reservations.erase(reservation_id)
func change_reservation(reservation_id, dto: UpdateReservationDTO):
var entity = _reservations[reservation_id]
entity.title = dto.title
entity.description = dto.description
entity.room_id = dto.room_id
entity.creator = dto.creator
entity.start_date = dto.start_date.duplicate(true)
entity.finish_date = dto.finish_date.duplicate(true)
func get_reservation(reservation_id):
return _reservations[reservation_id]
func list_reservations():
var reservations = []
for key in _reservations:
reservations.append(_reservations[key])
reservations.sort_custom(self._compare_reservations_by_start_time)
return reservations
func _compare_reservations_by_start_time(a: ReservationEntity, b: ReservationEntity) -> int:
var time_a = a.start_time["hours"] * 60 + a.start_time["minutes"]
var time_b = b.start_time["hours"] * 60 + b.start_time["minutes"]
return time_a < time_b