From 17d8637156cdef107d4e8f92d45f6b92c8822853 Mon Sep 17 00:00:00 2001 From: Xananax Date: Sat, 22 Apr 2023 03:08:05 +0200 Subject: [PATCH] bugs squished --- assets/play_small.svg | 54 ++++++++++++++ assets/play_small.svg.import | 35 ++++++++++ project.godot | 1 + scripts/cmd.gd | 35 ++++++++-- scripts/config_manager.gd | 120 ++++++++++++++++++++++++-------- scripts/file_watcher.gd | 3 +- scripts/time_entry.gd | 15 ++-- scripts/time_entry_tree_item.gd | 15 +++- scripts/time_sheet.gd | 66 ++++++++++++++---- ui/settings.gd | 11 +-- ui/settings.tscn | 24 +++++-- ui/tasks_list.gd | 28 ++++---- ui/time_counter.gd | 46 ++++++------ 13 files changed, 346 insertions(+), 107 deletions(-) create mode 100644 assets/play_small.svg create mode 100644 assets/play_small.svg.import diff --git a/assets/play_small.svg b/assets/play_small.svg new file mode 100644 index 0000000..c15a14e --- /dev/null +++ b/assets/play_small.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + diff --git a/assets/play_small.svg.import b/assets/play_small.svg.import new file mode 100644 index 0000000..e08645e --- /dev/null +++ b/assets/play_small.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/play_small.svg-6ecf1cf55097c1673c0917a7e7624a3c.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/play_small.svg" +dest_files=[ "res://.import/play_small.svg-6ecf1cf55097c1673c0917a7e7624a3c.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/project.godot b/project.godot index 30a23c8..63d14c5 100644 --- a/project.godot +++ b/project.godot @@ -86,6 +86,7 @@ window/per_pixel_transparency/enabled=true window/energy_saving/keep_screen_on=false window/handheld/orientation="portrait" window/ios/hide_home_indicator=false +window/stretch/aspect="keep" [rendering] diff --git a/scripts/cmd.gd b/scripts/cmd.gd index ca5a662..9e95f76 100644 --- a/scripts/cmd.gd +++ b/scripts/cmd.gd @@ -1,8 +1,15 @@ class_name CMD -var command_line_arguments: Dictionary = {} -func unsurround(value: String, quotes := PoolStringArray(['"', "'"])) -> String: +var _parsed := false + +## @type Dictionary[String, String|bool] +var command_line_arguments: Dictionary = {} setget set_command_line_arguments, get_command_line_arguments + + +## Removes the first element find from the `quotes` array from the start and end of a string +## Also removes any whitespace resulting from removing the quoting elements +static func unsurround(value: String, quotes := PoolStringArray(['"', "'"])) -> String: for quote_str in quotes: if value.begins_with(quote_str) \ and value.ends_with(quote_str) \ @@ -10,6 +17,7 @@ func unsurround(value: String, quotes := PoolStringArray(['"', "'"])) -> String: return value.trim_prefix(quote_str).trim_suffix(quote_str).strip_edges() return value + ## Returns a dictionary of all arguments passed after `--` on the command line ## arguments take one of 2 forms: ## - `--arg` which is a boolean (using `--no-arg` for `false` is possible) @@ -17,7 +25,7 @@ func unsurround(value: String, quotes := PoolStringArray(['"', "'"])) -> String: ## unsurround the string ## This function does no evaluation and does not attempt to guess the type of ## arguments. You will receive either bools, or strings. -func _read_arguments() -> Dictionary: +static func parse_cmd_arguments() -> Dictionary: var arguments := {} for arg in OS.get_cmdline_args(): var argument: String = arg.lstrip("--").to_lower() @@ -36,12 +44,27 @@ func _read_arguments() -> Dictionary: return arguments +func set_command_line_arguments(_arguments: Dictionary) -> void: + printerr("get_command_line_arguments is a read only value") + +func get_command_line_arguments() -> Dictionary: + if not _parsed: + _parsed = true + command_line_arguments = parse_cmd_arguments() + return command_line_arguments + + +## Returns a single argument passed after `--` on the command line +## if the argument does not exist, `default` is returned instead +## _parse_cmd_arguments() has to be called first func get_argument(name: String, default = null): - if command_line_arguments.has(name): - return command_line_arguments[name] + if get_command_line_arguments().has(name): + return get_command_line_arguments()[name] return default +## Verifies an argument exists on the command line +## _parse_cmd_arguments() has to be called first func has_argument(name: String) -> bool: - return command_line_arguments.has(name) + return get_command_line_arguments().has(name) diff --git a/scripts/config_manager.gd b/scripts/config_manager.gd index 6d2dc6d..21d9b76 100644 --- a/scripts/config_manager.gd +++ b/scripts/config_manager.gd @@ -1,25 +1,41 @@ +## Reads the config, sets values. Acts a singleton because it proxies a const +## file path. class_name ConfigManager extends Resource - -signal file_changed -signal time_sheet_reloaded - const CONFIG_PATH := "user://settings.cfg" -var timesheet: TimeSheet setget ,get_timesheet var _config := ConfigFile.new() var _watcher: FileWatcher +############################################################################### +# +# SIGNAL +# + +signal time_sheet_loaded + +func emit_loaded() -> void: + emit_signal("time_sheet_loaded") + + +############################################################################### +# +# TIMESHEET FILE LOADING AND PARSING +# + +var timesheet: TimeSheet setget ,get_timesheet + + func get_timesheet() -> TimeSheet: if timesheet == null: - timesheet = _load_timesheet(get_current_file()) + timesheet = _load_timesheet(get_current_timesheet_file_path()) return timesheet func _load_timesheet(path: String) -> TimeSheet: - timesheet = TimeSheet.restore(path) - if timesheet == null: + var new_timesheet := TimeSheet.restore(path) + if new_timesheet == null: return null _watcher = FileWatcher.new() _watcher.file_name = path @@ -30,72 +46,94 @@ func _load_timesheet(path: String) -> TimeSheet: #timesheet.connect("entry_started", self, "_on_entry_started") # warning-ignore:return_value_discarded #timesheet.connect("entry_stopped", self, "_on_entry_stopped") - return timesheet + return new_timesheet func reload_timesheet() -> void: - var new_timesheet = _load_timesheet(get_current_file()) + var new_timesheet = _load_timesheet(get_current_timesheet_file_path()) if new_timesheet == null: printerr("failed to load new timesheet") return timesheet = new_timesheet - emit_signal("time_sheet_reloaded") + emit_loaded() -var current_file: String = "" setget set_current_file, get_current_file +############################################################################### +# +# TIMESHEET FILE PATH +# + +var current_timesheet_file_path: String = "" setget set_current_timesheet_file_path, get_current_timesheet_file_path -func set_current_file(value: String) -> void: +func set_current_timesheet_file_path(value: String) -> void: timesheet = _load_timesheet(value) if timesheet == null: return - current_file = value + current_timesheet_file_path = value _config.set_value("MAIN", "file", value) - emit_signal("file_changed") + emit_loaded() save() -func get_current_file() -> String: +func get_current_timesheet_file_path() -> String: var _default_path := OS.get_system_dir(OS.SYSTEM_DIR_DOCUMENTS, true).plus_file("mouse_timer.csv") return _config.get_value("MAIN", "file", _default_path) +############################################################################### +# +# THEME FILE LOADING AND PARSING +# + + var theme: Theme setget , get_theme + func get_theme() -> Theme: if theme == null: - theme = ResourceLoader.load(theme_path, "Theme") + theme = ResourceLoader.load(theme_file_path, "Theme") return theme +############################################################################### +# +# THEME FILE PATH +# + signal theme_changed -var theme_path: String = "" setget set_theme_path, get_theme_path +var theme_file_path: String = "" setget set_theme_file_path, get_theme_file_path -func set_theme_path(value: String) -> void: +func set_theme_file_path(value: String) -> void: var new_theme: Theme = ResourceLoader.load(value, "Theme") if new_theme != null: theme = new_theme - theme_path = value + theme_file_path = value _config.set_value("MAIN", "theme", value) emit_signal("theme_changed") save() -func get_theme_path() -> String: +func get_theme_file_path() -> String: return _config.get_value("MAIN", "theme", preload("res://assets/default_theme.theme").resource_path) -var last_task_name: String = "" setget set_last_task_name, get_last_task_name +#var current_task_name: String = "" setget set_current_task_name, get_current_task_name +# +#func set_current_task_name(value: String) -> void: +# current_task_name = value +# _config.set_value("MAIN", "current_task_name", value) +# save() +# +#func get_current_task_name() -> String: +# return _config.get_value("MAIN", "current_task_name", "") -func set_last_task_name(value: String) -> void: - last_task_name = value - _config.set_value("MAIN", "last_task_name", value) - save() - -func get_last_task_name() -> String: - return _config.get_value("MAIN", "last_task_name", "") +############################################################################### +# +# SOUND OPTION +# var sound_fx_on: bool = true setget set_sound_fx_on, get_sound_fx_on @@ -108,6 +146,30 @@ func get_sound_fx_on() -> bool: return _config.get_value("MAIN", "sound_fx", true) +############################################################################### +# +# SOME SETTINGS CACHE +# + +var current_task_name := "" setget set_current_task_name, get_current_task_name + + +func set_current_task_name(value: String) -> void: + current_task_name = value + _config.set_value("CACHE", "current_task_name", value) + save() + + +func get_current_task_name() -> String: + return _config.get_value("CACHE", "current_task_name", "") + + +############################################################################### +# +# BOOTSTRAP +# + + func _init() -> void: # warning-ignore:return_value_discarded _config.load(CONFIG_PATH) diff --git a/scripts/file_watcher.gd b/scripts/file_watcher.gd index cae7ab8..f5e1bb2 100644 --- a/scripts/file_watcher.gd +++ b/scripts/file_watcher.gd @@ -37,7 +37,8 @@ func check() -> void: var new_modified := _file.get_modified_time(file_name) if new_modified != _last_modified: _last_modified = new_modified - emit_signal("file_changed") + print("file changed") + emit_signal("file_changed") func start() -> void: diff --git a/scripts/time_entry.gd b/scripts/time_entry.gd index bf23f88..858fa3b 100644 --- a/scripts/time_entry.gd +++ b/scripts/time_entry.gd @@ -3,9 +3,6 @@ class_name TimeEntry -signal end_time_updated -signal closed - var name := "" var is_closed := false var start_time := TimeStamp.new() @@ -13,20 +10,21 @@ var end_time := TimeStamp.new() func start_recording() -> TimeEntry: - start_time = start_time.from_current_time() - end_time = end_time.from_current_time() + # warning-ignore:return_value_discarded + start_time.from_current_time() + # warning-ignore:return_value_discarded + end_time.from_current_time() return self func update() -> void: - end_time = end_time.from_current_time() - emit_signal("end_time_updated") + # warning-ignore:return_value_discarded + end_time.from_current_time() func close() -> void: update() is_closed = true - emit_signal("closed") func get_elapsed_seconds() -> int: @@ -88,5 +86,6 @@ func to_dict() -> Dictionary: closed = is_closed, } + func _to_string() -> String: return "%s\t%s\t%s"%[name, tr(Consts.ONGOING) if is_closed == false else end_time.to_string(), start_time] diff --git a/scripts/time_entry_tree_item.gd b/scripts/time_entry_tree_item.gd index d638772..5cd5275 100644 --- a/scripts/time_entry_tree_item.gd +++ b/scripts/time_entry_tree_item.gd @@ -6,7 +6,9 @@ var time_entry: TimeEntry var children := {} var time_entries := [] + func get_child(parts: Array, or_create := false): + # workaround for cyclic dependencies bug var TimeEntryTreeItem = load("res://scripts/time_entry_tree_item.gd") if parts.size() == 0: return self @@ -21,14 +23,23 @@ func get_child(parts: Array, or_create := false): return children[part].get_child(parts, or_create) +func find_active_time_entry() -> TimeEntry: + for _time_entry_tree_item in time_entries: + var time_entry_tree_item := _time_entry_tree_item as TimeEntryTreeItem + var current_time_entry := time_entry_tree_item.time_entry + if not current_time_entry.is_closed: + return current_time_entry + return null + + func append(new_time_entry: TimeEntry) -> void: var TimeEntryTreeItem = load("res://scripts/time_entry_tree_item.gd") var time_entry_tree_item = TimeEntryTreeItem.new() time_entry_tree_item.time_entry = new_time_entry # warning-ignore:return_value_discarded - new_time_entry.connect("end_time_updated", time_entry_tree_item, "_on_end_time_updated") + # new_time_entry.connect("end_time_updated", time_entry_tree_item, "_on_end_time_updated") # warning-ignore:return_value_discarded - time_entry_tree_item.connect("end_time_updated", self, "_on_end_time_updated") + # time_entry_tree_item.connect("end_time_updated", self, "_on_end_time_updated") time_entries.append(time_entry_tree_item) diff --git a/scripts/time_sheet.gd b/scripts/time_sheet.gd index 6d70af3..9d9e0fd 100644 --- a/scripts/time_sheet.gd +++ b/scripts/time_sheet.gd @@ -3,7 +3,8 @@ class_name TimeSheet var source_path := "" var entries := [] -var tree := TimeEntryTreeItem.new() +# warning-ignore:integer_division +var _last_update := Time.get_ticks_msec() / 1000 ## Loads the data file func load_file() -> bool: @@ -25,20 +26,10 @@ func load_file() -> bool: continue var entry := TimeEntry.new().from_csv_line(line) entries.append(entry) - # warning-ignore:return_value_discarded - entry.connect("closed", self, "save") file.close() entries.sort_custom(self, "_sort_entries") - - - for entry_index in entries.size(): - var entry: TimeEntry = entries[entry_index] - var parts: PoolStringArray = entry.name.split("/") - var repo: TimeEntryTreeItem = tree.get_child(parts, true) - repo.append(entry) - return true @@ -46,22 +37,56 @@ func _sort_entries(a: TimeEntry, b: TimeEntry) -> bool: return a.name < b.name +func get_active_entry_from_name(task_name: String) -> TimeEntry: + for _entry in entries: + var current_time_entry := _entry as TimeEntry + if current_time_entry.name == task_name and not current_time_entry.is_closed: + return current_time_entry + return null + + ## Adds a new time entry to the tree and to the data file -func start_entry(entry_name: String) -> void: +func add_entry(entry_name: String) -> TimeEntry: var current_entry := TimeEntry.new().start_recording() current_entry.name = entry_name - current_entry.closed = false + current_entry.is_closed = false var file := File.new() var success := file.open(source_path, File.READ_WRITE) if success != OK: printerr("Could not open file") - return + return null + file.seek_end() entries.append(current_entry) file.store_csv_line(current_entry.to_csv_line()) - emit_signal("entry_started") + return current_entry + + +func stop_entry(entry_name: String, do_save := true) -> bool: + prints("stopping", entry_name) + for _entry in entries: + var current_time_entry := _entry as TimeEntry + if current_time_entry.name == entry_name and not current_time_entry.is_closed: + current_time_entry.close() + if do_save: + save() + return true + return false + + +func toggle_entry(entry_name: String, do_save := true) -> void: + if stop_entry(entry_name, do_save): + return + else: + # warning-ignore:return_value_discarded + add_entry(entry_name) func update() -> void: + # warning-ignore:integer_division + var current_time := Time.get_ticks_msec() / 1000 + if current_time == _last_update: + return + _last_update = current_time for entry in entries: var time_entry := entry as TimeEntry if time_entry.is_closed == false: @@ -74,10 +99,21 @@ func save() -> void: if success != OK: printerr("Could not open file") return + prints("saving") for time_entry in entries: file.store_csv_line(time_entry.to_csv_line()) +func make_items_tree() -> TimeEntryTreeItem: + var tree := TimeEntryTreeItem.new() + for entry_index in entries.size(): + var entry := entries[entry_index] as TimeEntry + var parts := entry.name.split("/") + var repo: TimeEntryTreeItem = tree.get_child(parts, true) + repo.append(entry) + return tree + + static func restore(file_path: String) -> TimeSheet: var timesheet = load("res://scripts/time_sheet.gd").new() timesheet.source_path = file_path diff --git a/ui/settings.gd b/ui/settings.gd index faecc34..165f06c 100644 --- a/ui/settings.gd +++ b/ui/settings.gd @@ -1,4 +1,4 @@ -extends PanelContainer +extends Control var config: ConfigManager = preload("res://config_manager.tres") @@ -26,11 +26,13 @@ func _ready() -> void: # warning-ignore:return_value_discarded file_path_file_dialog.connect("file_selected", self, "_on_current_file_selected") # warning-ignore:return_value_discarded - file_path_line_edit.connect("text_submitted", self, "_on_current_file_selected") + file_path_line_edit.connect("text_entered", self, "_on_current_file_selected") - theme_path_button.connected("pressed", self, "_on_theme_path_button_pressed") + # warning-ignore:return_value_discarded + theme_path_button.connect("pressed", self, "_on_theme_path_button_pressed") - theme_path_file_dialog.connected("file_selected", self, "_on_new_theme_selected") + # warning-ignore:return_value_discarded + theme_path_file_dialog.connect("file_selected", self, "_on_new_theme_selected") theme_path_file_dialog.hide() file_path_file_dialog.hide() @@ -46,6 +48,7 @@ func _ready() -> void: # warning-ignore:return_value_discarded open_data_dir_button.connect("pressed", self, "_on_open_data_dir_button_pressed") + _on_current_file_changed() func _on_current_file_changed() -> void: diff --git a/ui/settings.tscn b/ui/settings.tscn index 420c733..b400c02 100644 --- a/ui/settings.tscn +++ b/ui/settings.tscn @@ -116,19 +116,31 @@ This game uses Godot Engine, available under the following license: THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. " -[node name="FilePathFileDialog" type="FileDialog" parent="."] +[node name="CanvasLayer" type="CanvasLayer" parent="."] + +[node name="FilePathFileDialog" type="FileDialog" parent="CanvasLayer"] unique_name_in_owner = true -margin_right = 442.0 -margin_bottom = 760.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 window_title = "Pick a file" +resizable = true +dialog_hide_on_ok = true +mode_overrides_title = false access = 2 filters = PoolStringArray( "*.csv ; Comma Separated Files" ) -[node name="ThemePathFileDialog" type="FileDialog" parent="."] +[node name="ThemePathFileDialog" type="FileDialog" parent="CanvasLayer"] unique_name_in_owner = true -margin_right = 360.0 -margin_bottom = 760.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 window_title = "Open a File" +resizable = true +dialog_hide_on_ok = true +mode_overrides_title = false mode = 0 access = 2 filters = PoolStringArray( "*.theme ; Theme Files" ) diff --git a/ui/tasks_list.gd b/ui/tasks_list.gd index f739e9b..428ca56 100644 --- a/ui/tasks_list.gd +++ b/ui/tasks_list.gd @@ -18,16 +18,14 @@ func _ready() -> void: # warning-ignore:return_value_discarded _timer.connect("timeout", self, "_on_timer_timeout") # warning-ignore:return_value_discarded - config.connect("file_changed", self, "populate_entries") - # warning-ignore:return_value_discarded - config.connect("time_sheet_reloaded", self, "populate_entries") + config.connect("time_sheet_loaded", self, "populate_entries") populate_entries() func populate_entries() -> void: clear() var tree_items_root := create_item() - var item_entries_tree := config.timesheet.tree + var item_entries_tree := config.timesheet.make_items_tree() _populate_from_entry(tree_items_root, item_entries_tree) _timer.start() #for item in entries: @@ -56,18 +54,23 @@ func _populate_from_entry(tree_item_root: TreeItem, time_entry_item_root: TimeEn for time_entry_name in children: var time_entry_item: TimeEntryTreeItem = children[time_entry_name] var item := find_or_create_item(tree_item_root, time_entry_name) - item.set_metadata(COL.TEXT, time_entry_item) + item.set_metadata(COL.TEXT, time_entry_name) item.set_text(COL.TIME, time_entry_item.get_period()) # warning-ignore:return_value_discarded time_entry_item.connect("end_time_updated", self, "_on_time_entry_changed_update_item", [time_entry_item, item]) _populate_from_entry(item, time_entry_item) + var has_at_least_one_running_entry := time_entry_item.find_active_time_entry() != null + var texture := preload("res://assets/stop_small.svg") \ + if has_at_least_one_running_entry \ + else preload("res://assets/play_small.svg") + item.add_button(COL.TIME, texture) var entries = time_entry_item_root.time_entries for entry_item in entries: var time_entry_item := entry_item as TimeEntryTreeItem var item := create_item(tree_item_root) var time_entry := time_entry_item.time_entry item.set_text(COL.TEXT, time_entry.start_time.to_string()) - item.set_metadata(COL.TEXT, time_entry_item) + item.set_metadata(COL.TEXT, time_entry_item.time_entry.name) item.set_text(COL.TIME, time_entry_item.get_period()) if time_entry.is_closed == false: var texture := preload("res://assets/stop_small.svg") @@ -81,17 +84,10 @@ func _on_time_entry_changed_update_item(time_entry_item: TimeEntryTreeItem, item func _on_button_pressed(item: TreeItem, _column: int, _id: int) -> void: - var time_entry_tree_item: TimeEntryTreeItem = item.get_metadata(COL.TEXT) - if time_entry_tree_item == null: + var task_name: String = item.get_metadata(COL.TEXT) + if task_name == "": return - var time_entry := time_entry_tree_item.time_entry - if time_entry == null: - return - if time_entry.is_closed: - return - else: - time_entry.close() - item.erase_button(COL.TIME, 0) + config.timesheet.toggle_entry(task_name) ## Unecessary in Godot 4, can bre replaced with get_children() diff --git a/ui/time_counter.gd b/ui/time_counter.gd index 05ad102..28cdc9c 100644 --- a/ui/time_counter.gd +++ b/ui/time_counter.gd @@ -10,6 +10,7 @@ onready var start_button := $"%StartButton" as Button onready var timer := $"%Timer" as Timer onready var audio_stream_player := $"%AudioStreamPlayer" as AudioStreamPlayer +var current_time_entry: TimeEntry func _ready() -> void: # warning-ignore:return_value_discarded @@ -18,13 +19,16 @@ func _ready() -> void: start_button.toggle_mode = true # warning-ignore:return_value_discarded start_button.connect("toggled", self, "_on_start_button_toggled") - task_name_line_edit.text = config.last_task_name + task_name_line_edit.text = config.current_task_name # warning-ignore:return_value_discarded task_name_line_edit.connect("text_changed", self, "_on_task_name_line_edit_text_changed") # warning-ignore:return_value_discarded - config.connect("entry_started", self, "set_button_as_started") + config.connect("time_sheet_loaded", self, "_on_time_sheet_loaded") + update_timer_state() # warning-ignore:return_value_discarded - config.connect("entry_stopped", self, "set_button_as_stopped") + #config.connect("entry_started", self, "set_button_as_started") + # warning-ignore:return_value_discarded + #config.connect("entry_stopped", self, "set_button_as_stopped") # TODO: connect this: #time_entries_items_tree.item_selected.connect( # func item_selected() -> void: @@ -34,25 +38,33 @@ func _ready() -> void: func _on_timer_timeout() -> void: config.timesheet.update() - - time_label.text = config.timesheet.get_period() - - ## TODO: change this - # var total_elapsed: int = config.timesheet.get_total_elapsed_seconds() - # time_entries_items_tree.set_time_elapsed(total_elapsed) + time_label.text = current_time_entry.get_period() -func _on_start_button_toggled(is_on: bool) -> void: +func _on_start_button_toggled(_is_on: bool) -> void: if config.sound_fx_on: audio_stream_player.play() - if is_on: - config.timesheet.start_entry(task_name_line_edit.text) + if current_time_entry != null: + config.timesheet.stop_entry(task_name_line_edit.text) else: - config.timesheet.close_entry() + config.timesheet.add_entry(task_name_line_edit.text) func _on_task_name_line_edit_text_changed(new_text: String) -> void: - config.last_task_name = new_text + config.current_task_name = new_text + update_timer_state() + + +func _on_time_sheet_loaded(): + print("loaded") + update_timer_state() + +func update_timer_state() -> void: + current_time_entry = config.timesheet.get_active_entry_from_name(config.current_task_name) + if current_time_entry: + set_button_as_started() + else: + set_button_as_stopped() func set_button_as_stopped() -> void: @@ -70,9 +82,3 @@ func set_button_as_started() -> void: start_button.hint_tooltip = tr(Consts.STOP) start_button.theme_type_variation = Consts.THEME_OVERRIDE_STOP timer.start() - - -func set_initial_state() -> void: - if config.timesheet.current_entry != null and config.timesheet.current_entry.closed == false: - start_button.set_pressed_no_signal(true) - set_button_as_started()