Add base project

This commit is contained in:
Mathilde Grapin 2024-05-25 18:50:50 +02:00
parent 0cec0c70d5
commit 5abf7b3d81
19 changed files with 501 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

15
.gitignore vendored Normal file
View file

@ -0,0 +1,15 @@
# Godot 4+ specific ignores
.godot/
# Godot-specific ignores
.import/
export.cfg
export_presets.cfg
# Imported translations (automatically generated from CSV files)
*.translation
# Mono-specific ignores
.mono/
data_*/
mono_crash.*.json

View file

@ -5,3 +5,8 @@
A simple period tracker. A simple period tracker.
Base idea is to track period but it can be used to track any other repetitive events. Base idea is to track period but it can be used to track any other repetitive events.
## Credit
### Sniglet
[Sniglet](https://www.design-research.be/by-womxn/) by [Haley Fiege](https://fonts.google.com/?query=Haley+Fiege).

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 fill="#478cbf" 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 813 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H447l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c3 34 55 34 58 0v-86c-3-34-55-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: 950 B

37
icon.svg.import Normal file
View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cn3dbt5jkbtfe"
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

28
project.godot Normal file
View file

@ -0,0 +1,28 @@
; 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="gpml"
run/main_scene="res://scene/calendar.tscn"
config/features=PackedStringArray("4.2", "Forward Plus")
config/icon="res://icon.svg"
[input]
shift_click={
"deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":true,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(669, 17),"global_position":Vector2(673, 58),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
]
}
[rendering]
environment/defaults/default_clear_color=Color(0.162066, 0.162066, 0.162066, 1)

43
scene/calendar.tscn Normal file
View file

@ -0,0 +1,43 @@
[gd_scene load_steps=5 format=3 uid="uid://bkwvaljh0oj22"]
[ext_resource type="Theme" uid="uid://bu07nib41exqy" path="res://ui/theme.tres" id="1_jufjt"]
[ext_resource type="Script" path="res://script/calendar.gd" id="1_nbpow"]
[ext_resource type="PackedScene" uid="uid://x8u7mduga68y" path="res://scene/month.tscn" id="2_g4ut4"]
[ext_resource type="Script" path="res://scene/periodmanager.gd" id="3_3jsi6"]
[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
theme = ExtResource("1_jufjt")
script = ExtResource("1_nbpow")
month_scene = ExtResource("2_g4ut4")
[node name="CenterContainer" type="CenterContainer" parent="."]
layout_mode = 1
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -576.0
offset_right = 576.0
offset_bottom = 27.0
grow_horizontal = 2
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"]
layout_mode = 2
[node name="YearLabel" type="Label" parent="CenterContainer/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 0
theme_override_font_sizes/font_size = 96
[node name="Year" type="GridContainer" parent="CenterContainer/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 4
columns = 4
[node name="PeriodManager" type="Node" parent="."]
script = ExtResource("3_3jsi6")

9
scene/day.tscn Normal file
View file

@ -0,0 +1,9 @@
[gd_scene load_steps=2 format=3 uid="uid://dt5l2bunc1iru"]
[ext_resource type="Script" path="res://script/day.gd" id="1_jhrhj"]
[node name="Day" type="Button"]
offset_right = 46.0
offset_bottom = 40.0
text = "12"
script = ExtResource("1_jhrhj")

63
scene/month.tscn Normal file
View file

@ -0,0 +1,63 @@
[gd_scene load_steps=3 format=3 uid="uid://x8u7mduga68y"]
[ext_resource type="Script" path="res://script/month.gd" id="1_tiy7h"]
[ext_resource type="PackedScene" uid="uid://dt5l2bunc1iru" path="res://scene/day.tscn" id="2_5kdiw"]
[node name="Month" type="Control"]
custom_minimum_size = Vector2(250, 250)
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_tiy7h")
day_scene = ExtResource("2_5kdiw")
[node name="HBoxContainer" type="HBoxContainer" parent="."]
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="MonthLabel" type="Label" parent="HBoxContainer"]
layout_mode = 2
theme_override_font_sizes/font_size = 20
[node name="DaysGridContainer" type="GridContainer" parent="HBoxContainer"]
layout_mode = 2
columns = 7
[node name="Dimanche" type="Label" parent="HBoxContainer/DaysGridContainer"]
layout_mode = 2
size_flags_horizontal = 4
text = "D"
[node name="Lundi" type="Label" parent="HBoxContainer/DaysGridContainer"]
layout_mode = 2
size_flags_horizontal = 4
text = "L"
[node name="Mardi" type="Label" parent="HBoxContainer/DaysGridContainer"]
layout_mode = 2
size_flags_horizontal = 4
text = "M"
[node name="Mercredi" type="Label" parent="HBoxContainer/DaysGridContainer"]
layout_mode = 2
size_flags_horizontal = 4
text = "M"
[node name="Jeudi" type="Label" parent="HBoxContainer/DaysGridContainer"]
layout_mode = 2
size_flags_horizontal = 4
text = "J"
[node name="Vendredi" type="Label" parent="HBoxContainer/DaysGridContainer"]
layout_mode = 2
size_flags_horizontal = 4
text = "V"
[node name="Samedi" type="Label" parent="HBoxContainer/DaysGridContainer"]
layout_mode = 2
size_flags_horizontal = 4
text = "S"

25
scene/periodmanager.gd Normal file
View file

@ -0,0 +1,25 @@
extends Node
var periods = []
var last_period = null
func add(date):
if last_period != null:
last_period.end = date
last_period = null
dump()
return
# If no new period has begun
var period = Period.new()
period.begin = date
periods.append(period)
last_period = period
dump()
func dump():
for period in periods:
print("%s - %s" % [period.begin, period.end])

64
script/calendar.gd Normal file
View file

@ -0,0 +1,64 @@
class_name Calendar
extends Control
@export var month_scene: PackedScene
@onready var year_label = $CenterContainer/VBoxContainer/YearLabel
@onready var year = $CenterContainer/VBoxContainer/Year
@onready var period_manager = $PeriodManager
var last_focused_day = null
var new_focused_day = null
var all_days = []
# Called when the node enters the scene tree for the first time.
func _ready():
var current_year = Time.get_date_dict_from_system().year
year_label.text = "%s" % current_year
for i in range (1, 13):
var month = month_scene.instantiate()
month.year = current_year
month.month = i
month.day_toggled.connect(_on_day_toggled)
month.fill_days.connect(_on_fill_days)
year.add_child(month)
for element in month.days.get_children():
if element is Day:
all_days.append(element)
func _on_day_toggled(date):
# period_manager.add(date)
# Update last focused day.
var focused_node = get_viewport().gui_get_focus_owner()
if focused_node is Day:
last_focused_day = focused_node
func _on_fill_days(shift_clicked_day):
# Toogle day from last focused day to current day.
# Assert that last focused day is different from date.
if last_focused_day == null:
return
if shift_clicked_day == last_focused_day:
return
# Determine if date is before or after the last focused day.
var first_day = last_focused_day if last_focused_day.is_before(shift_clicked_day) else shift_clicked_day
var last_day = shift_clicked_day if first_day == last_focused_day else last_focused_day
# Toggle days between the two days.
var toggle = false
for day in all_days:
if first_day == day:
toggle = true
if toggle:
day.set_pressed_no_signal(true)
if last_day == day:
return

39
script/day.gd Normal file
View file

@ -0,0 +1,39 @@
class_name Day
extends Button
signal day_toggled(date)
signal fill_days(date)
var date = {}
func _ready():
set_toggle_mode(true);
toggled.connect(self._on_day_toggled)
func _gui_input(event):
if event.is_action_pressed("shift_click"):
fill_days.emit(self)
accept_event()
func _on_day_toggled(_toggled_on):
day_toggled.emit(date)
func set_date(year, month, day):
date = {"year": year, "month": month, "day": day}
func is_before(other_day):
var day_unix_time = Time.get_unix_time_from_datetime_dict(date)
var other_day_unix_time = Time.get_unix_time_from_datetime_dict(other_day.date)
if day_unix_time < other_day_unix_time:
return true
return false
func dump():
print("%s - %s - %s" % [date.year, date.month, date.day])

55
script/month.gd Normal file
View file

@ -0,0 +1,55 @@
class_name Month
extends Control
signal day_toggled(date)
signal fill_days(date)
const DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
@export var day_scene: PackedScene
var year: int
var month: int
@onready var month_label = $HBoxContainer/MonthLabel
@onready var days = $HBoxContainer/DaysGridContainer
# Called when the node enters the scene tree for the first time.
func _ready():
month_label.text = "%s" % month
var days_in_month = find_days_in_month(year, month)
var date_string = "%s-%s-%s" % [year, month, 1]
var first_day = Time.get_datetime_dict_from_datetime_string(date_string, true)
# Fill the container with number corresponding to days
for i in range(first_day.weekday):
var empty_label = Label.new()
days.add_child(empty_label)
for i in range(1, days_in_month + 1):
var day = day_scene.instantiate()
day.set_date(year, month, i)
day.text = "%s" % [i]
day.day_toggled.connect(_on_day_toggled)
day.fill_days.connect(_on_fill_days)
days.add_child(day)
func _on_day_toggled(date):
day_toggled.emit(date)
func _on_fill_days(day):
fill_days.emit(day)
func find_days_in_month(year: int, month: int):
assert(month >= 1 and month <= 12)
if (month == 2 and is_leap_year(year)):
return 29
return DAYS_IN_MONTH[month - 1]
func is_leap_year(year: int):
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)

5
script/period.gd Normal file
View file

@ -0,0 +1,5 @@
class_name Period
extends Node
var begin = {}
var end = {}

BIN
ui/Sniglet-ExtraBold.ttf Normal file

Binary file not shown.

View file

@ -0,0 +1,33 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://dkdwwfrrrxsv6"
path="res://.godot/imported/Sniglet-ExtraBold.ttf-e7d97d8b5ada3d87451c1bbbfe8eb998.fontdata"
[deps]
source_file="res://ui/Sniglet-ExtraBold.ttf"
dest_files=["res://.godot/imported/Sniglet-ExtraBold.ttf-e7d97d8b5ada3d87451c1bbbfe8eb998.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
hinting=1
subpixel_positioning=1
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}

BIN
ui/Sniglet-Regular.ttf Normal file

Binary file not shown.

View file

@ -0,0 +1,33 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://bqpsg4cosm86c"
path="res://.godot/imported/Sniglet-Regular.ttf-a388ba5acd2b2b968e010f49c0098b80.fontdata"
[deps]
source_file="res://ui/Sniglet-Regular.ttf"
dest_files=["res://.godot/imported/Sniglet-Regular.ttf-a388ba5acd2b2b968e010f49c0098b80.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
hinting=1
subpixel_positioning=1
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}

44
ui/theme.tres Normal file
View file

@ -0,0 +1,44 @@
[gd_resource type="Theme" load_steps=4 format=3 uid="uid://bu07nib41exqy"]
[ext_resource type="FontFile" uid="uid://bqpsg4cosm86c" path="res://ui/Sniglet-Regular.ttf" id="1_8evya"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_jjd3u"]
content_margin_left = 4.0
content_margin_top = 4.0
content_margin_right = 4.0
content_margin_bottom = 4.0
bg_color = Color(0.1, 0.1, 0.1, 0.6)
border_width_left = 3
border_width_top = 3
border_width_right = 3
border_width_bottom = 3
border_color = Color(0.677521, 0.850448, 0.731593, 1)
corner_radius_top_left = 3
corner_radius_top_right = 3
corner_radius_bottom_right = 3
corner_radius_bottom_left = 3
corner_detail = 5
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_fxaw6"]
content_margin_left = 4.0
content_margin_top = 4.0
content_margin_right = 4.0
content_margin_bottom = 4.0
bg_color = Color(0.826838, 0.64006, 0.825632, 0.6)
border_width_left = 3
border_width_top = 3
border_width_right = 3
border_width_bottom = 3
border_color = Color(0.678431, 0.85098, 0.733333, 1)
corner_radius_top_left = 3
corner_radius_top_right = 3
corner_radius_bottom_right = 3
corner_radius_bottom_left = 3
corner_detail = 5
[resource]
default_font = ExtResource("1_8evya")
default_font_size = 16
Button/styles/normal = SubResource("StyleBoxFlat_jjd3u")
Button/styles/pressed = SubResource("StyleBoxFlat_fxaw6")
Label/colors/font_color = Color(0.800791, 0.644553, 0.798944, 1)