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.
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)