mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-18 17:19:50 +00:00
Add autosave feature with backup of unsaved new projects (#221)
* Add autosave feature with backup of unsaved new projects. * Fix wrong indentation on line 205. * Store backup for every opened file in user://. Some other improvements. * Remove unnecessary variable. * Update Translations.pot Co-authored-by: Manolis Papadeas <35376950+OverloadedOrama@users.noreply.github.com>
This commit is contained in:
parent
c82c54d096
commit
82fe186b65
|
@ -1676,6 +1676,14 @@ visible = false
|
|||
|
||||
[node name="RightCursor" type="Sprite" parent="."]
|
||||
visible = false
|
||||
|
||||
[node name="BackupConfirmation" type="ConfirmationDialog" parent="."]
|
||||
margin_right = 349.0
|
||||
margin_bottom = 88.0
|
||||
rect_min_size = Vector2( 250, 87.5 )
|
||||
popup_exclusive = true
|
||||
dialog_text = "Autosaved backup for %s was found.
|
||||
Do you want to reload it?"
|
||||
[connection signal="mouse_entered" from="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer/ViewportAndRulers/HorizontalRuler" to="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer/ViewportAndRulers/HorizontalRuler" method="_on_HorizontalRuler_mouse_entered"]
|
||||
[connection signal="pressed" from="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer/ViewportAndRulers/HorizontalRuler" to="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer/ViewportAndRulers/HorizontalRuler" method="_on_HorizontalRuler_pressed"]
|
||||
[connection signal="pressed" from="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer/ViewportAndRulers/HSplitContainer/ViewportandVerticalRuler/VerticalRuler" to="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer/ViewportAndRulers/HSplitContainer/ViewportandVerticalRuler/VerticalRuler" method="_on_VerticalRuler_pressed"]
|
||||
|
@ -1762,6 +1770,7 @@ visible = false
|
|||
[connection signal="file_selected" from="PaletteImportFileDialog" to="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="on_palette_import_file_selected"]
|
||||
[connection signal="popup_hide" from="PaletteImportFileDialog" to="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="_on_NewPaletteDialog_popup_hide"]
|
||||
[connection signal="popup_hide" from="HSVDialog" to="." method="_can_draw_true"]
|
||||
[connection signal="popup_hide" from="BackupConfirmation" to="." method="_can_draw_true"]
|
||||
|
||||
[editable path="BrushesPopup/TabContainer/File/FileBrushContainer/CircleBrushButton"]
|
||||
|
||||
|
|
|
@ -49,39 +49,30 @@ size_flags_horizontal = 3
|
|||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/ScrollContainer"]
|
||||
margin_right = 308.0
|
||||
margin_bottom = 1186.0
|
||||
margin_bottom = 1230.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="General" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
||||
margin_right = 306.0
|
||||
margin_bottom = 116.0
|
||||
|
||||
[node name="OpenLastProject" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||
margin_right = 306.0
|
||||
margin_bottom = 24.0
|
||||
hint_tooltip = "Opens last opened project on startup"
|
||||
mouse_default_cursor_shape = 2
|
||||
pressed = true
|
||||
text = "Open last project on startup"
|
||||
margin_bottom = 180.0
|
||||
|
||||
[node name="SmoothZoom" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||
margin_top = 28.0
|
||||
margin_right = 306.0
|
||||
margin_bottom = 52.0
|
||||
margin_bottom = 24.0
|
||||
hint_tooltip = "Adds a smoother transition when zooming in or out"
|
||||
mouse_default_cursor_shape = 2
|
||||
pressed = true
|
||||
text = "Smooth Zoom"
|
||||
|
||||
[node name="HSeparator2" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||
margin_top = 56.0
|
||||
margin_top = 28.0
|
||||
margin_right = 306.0
|
||||
margin_bottom = 60.0
|
||||
margin_bottom = 32.0
|
||||
|
||||
[node name="GridContainer" type="GridContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||
margin_top = 64.0
|
||||
margin_top = 36.0
|
||||
margin_right = 306.0
|
||||
margin_bottom = 116.0
|
||||
margin_bottom = 88.0
|
||||
custom_constants/vseparation = 4
|
||||
custom_constants/hseparation = 4
|
||||
columns = 2
|
||||
|
@ -125,6 +116,11 @@ size_flags_horizontal = 3
|
|||
pressed = true
|
||||
text = "Show right tool icon"
|
||||
|
||||
[node name="HSeparator3" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||
margin_top = 92.0
|
||||
margin_right = 306.0
|
||||
margin_bottom = 96.0
|
||||
|
||||
[node name="PressureSentivity" type="HBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||
visible = false
|
||||
margin_top = 116.0
|
||||
|
@ -145,10 +141,56 @@ text = "Affect Brush's Alpha"
|
|||
items = [ "None", null, false, 0, null, "Affect Brush's Alpha", null, false, 1, null ]
|
||||
selected = 1
|
||||
|
||||
[node name="Languages" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
||||
margin_top = 120.0
|
||||
[node name="OpenLastProject" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||
margin_top = 100.0
|
||||
margin_right = 306.0
|
||||
margin_bottom = 512.0
|
||||
margin_bottom = 124.0
|
||||
hint_tooltip = "Opens last opened project on startup"
|
||||
mouse_default_cursor_shape = 2
|
||||
pressed = true
|
||||
text = "Open last project on startup"
|
||||
|
||||
[node name="EnableAutosave" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||
margin_top = 128.0
|
||||
margin_right = 306.0
|
||||
margin_bottom = 152.0
|
||||
text = "Enable autosave"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="AutosaveInterval" type="HBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||
margin_top = 156.0
|
||||
margin_right = 306.0
|
||||
margin_bottom = 180.0
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="AutosaveIntervalLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/General/AutosaveInterval"]
|
||||
margin_top = 5.0
|
||||
margin_right = 115.0
|
||||
margin_bottom = 19.0
|
||||
text = "Autosave interval:"
|
||||
|
||||
[node name="AutosaveInterval" type="SpinBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General/AutosaveInterval"]
|
||||
margin_left = 119.0
|
||||
margin_right = 306.0
|
||||
margin_bottom = 24.0
|
||||
size_flags_horizontal = 3
|
||||
min_value = 1.0
|
||||
max_value = 30.0
|
||||
value = 1.0
|
||||
align = 2
|
||||
suffix = "minute(s)"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="Languages" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
||||
margin_top = 184.0
|
||||
margin_right = 306.0
|
||||
margin_bottom = 576.0
|
||||
|
||||
[node name="System Language" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||
margin_right = 306.0
|
||||
|
@ -252,9 +294,9 @@ custom_fonts/font = ExtResource( 3 )
|
|||
text = "繁體中文 [zh_TW]"
|
||||
|
||||
[node name="Themes" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
||||
margin_top = 516.0
|
||||
margin_top = 580.0
|
||||
margin_right = 306.0
|
||||
margin_bottom = 652.0
|
||||
margin_bottom = 716.0
|
||||
|
||||
[node name="Dark Theme" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Themes"]
|
||||
margin_right = 306.0
|
||||
|
@ -291,9 +333,9 @@ mouse_default_cursor_shape = 2
|
|||
text = "Light"
|
||||
|
||||
[node name="Canvas" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
||||
margin_top = 656.0
|
||||
margin_top = 720.0
|
||||
margin_right = 306.0
|
||||
margin_bottom = 848.0
|
||||
margin_bottom = 912.0
|
||||
|
||||
[node name="GuideOptions" type="GridContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas"]
|
||||
margin_right = 306.0
|
||||
|
@ -465,9 +507,9 @@ mouse_default_cursor_shape = 2
|
|||
color = Color( 1, 1, 1, 1 )
|
||||
|
||||
[node name="Image" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
||||
margin_top = 852.0
|
||||
margin_top = 916.0
|
||||
margin_right = 306.0
|
||||
margin_bottom = 928.0
|
||||
margin_bottom = 992.0
|
||||
|
||||
[node name="ImageOptions" type="GridContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/Image"]
|
||||
margin_right = 306.0
|
||||
|
@ -538,9 +580,9 @@ mouse_default_cursor_shape = 2
|
|||
color = Color( 0, 0, 0, 0 )
|
||||
|
||||
[node name="Shortcuts" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
||||
margin_top = 932.0
|
||||
margin_top = 996.0
|
||||
margin_right = 306.0
|
||||
margin_bottom = 1186.0
|
||||
margin_bottom = 1230.0
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts"]
|
||||
margin_right = 306.0
|
||||
|
@ -571,7 +613,8 @@ margin_bottom = 28.0
|
|||
[node name="Shortcuts" type="GridContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts"]
|
||||
margin_top = 32.0
|
||||
margin_right = 306.0
|
||||
margin_bottom = 254.0
|
||||
margin_bottom = 234.0
|
||||
custom_constants/vseparation = 2
|
||||
custom_constants/hseparation = 5
|
||||
columns = 3
|
||||
|
||||
|
@ -598,9 +641,9 @@ text = "Right Tool:"
|
|||
align = 1
|
||||
|
||||
[node name="Empty2" type="Control" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_top = 18.0
|
||||
margin_top = 16.0
|
||||
margin_right = 137.0
|
||||
margin_bottom = 22.0
|
||||
margin_bottom = 20.0
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
visible = false
|
||||
|
@ -610,174 +653,174 @@ margin_bottom = 22.0
|
|||
|
||||
[node name="HSeparator2" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 142.0
|
||||
margin_top = 18.0
|
||||
margin_top = 16.0
|
||||
margin_right = 221.0
|
||||
margin_bottom = 22.0
|
||||
margin_bottom = 20.0
|
||||
|
||||
[node name="HSeparator3" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 226.0
|
||||
margin_top = 18.0
|
||||
margin_top = 16.0
|
||||
margin_right = 305.0
|
||||
margin_bottom = 22.0
|
||||
margin_bottom = 20.0
|
||||
|
||||
[node name="RectSelectLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_top = 29.0
|
||||
margin_top = 25.0
|
||||
margin_right = 137.0
|
||||
margin_bottom = 43.0
|
||||
margin_bottom = 39.0
|
||||
text = "Rectangular Selection"
|
||||
|
||||
[node name="left_rectangle_select_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 142.0
|
||||
margin_top = 26.0
|
||||
margin_top = 22.0
|
||||
margin_right = 221.0
|
||||
margin_bottom = 46.0
|
||||
margin_bottom = 42.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="right_rectangle_select_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 226.0
|
||||
margin_top = 26.0
|
||||
margin_top = 22.0
|
||||
margin_right = 305.0
|
||||
margin_bottom = 46.0
|
||||
margin_bottom = 42.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="ZoomLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_top = 53.0
|
||||
margin_top = 47.0
|
||||
margin_right = 137.0
|
||||
margin_bottom = 67.0
|
||||
margin_bottom = 61.0
|
||||
text = "Zoom"
|
||||
|
||||
[node name="left_zoom_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 142.0
|
||||
margin_top = 50.0
|
||||
margin_top = 44.0
|
||||
margin_right = 221.0
|
||||
margin_bottom = 70.0
|
||||
margin_bottom = 64.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="right_zoom_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 226.0
|
||||
margin_top = 50.0
|
||||
margin_top = 44.0
|
||||
margin_right = 305.0
|
||||
margin_bottom = 70.0
|
||||
margin_bottom = 64.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="ColorPickerLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_top = 77.0
|
||||
margin_top = 69.0
|
||||
margin_right = 137.0
|
||||
margin_bottom = 91.0
|
||||
margin_bottom = 83.0
|
||||
text = "Color Picker"
|
||||
|
||||
[node name="left_colorpicker_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 142.0
|
||||
margin_top = 74.0
|
||||
margin_top = 66.0
|
||||
margin_right = 221.0
|
||||
margin_bottom = 94.0
|
||||
margin_bottom = 86.0
|
||||
|
||||
[node name="right_colorpicker_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 226.0
|
||||
margin_top = 74.0
|
||||
margin_top = 66.0
|
||||
margin_right = 305.0
|
||||
margin_bottom = 94.0
|
||||
margin_bottom = 86.0
|
||||
|
||||
[node name="PencilLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_top = 101.0
|
||||
margin_top = 91.0
|
||||
margin_right = 137.0
|
||||
margin_bottom = 115.0
|
||||
margin_bottom = 105.0
|
||||
text = "Pencil"
|
||||
|
||||
[node name="left_pencil_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 142.0
|
||||
margin_top = 98.0
|
||||
margin_top = 88.0
|
||||
margin_right = 221.0
|
||||
margin_bottom = 118.0
|
||||
margin_bottom = 108.0
|
||||
|
||||
[node name="right_pencil_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 226.0
|
||||
margin_top = 98.0
|
||||
margin_top = 88.0
|
||||
margin_right = 305.0
|
||||
margin_bottom = 118.0
|
||||
margin_bottom = 108.0
|
||||
|
||||
[node name="EraserLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_top = 125.0
|
||||
margin_top = 113.0
|
||||
margin_right = 137.0
|
||||
margin_bottom = 139.0
|
||||
margin_bottom = 127.0
|
||||
text = "Eraser"
|
||||
|
||||
[node name="left_eraser_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 142.0
|
||||
margin_top = 122.0
|
||||
margin_top = 110.0
|
||||
margin_right = 221.0
|
||||
margin_bottom = 142.0
|
||||
margin_bottom = 130.0
|
||||
|
||||
[node name="right_eraser_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 226.0
|
||||
margin_top = 122.0
|
||||
margin_top = 110.0
|
||||
margin_right = 305.0
|
||||
margin_bottom = 142.0
|
||||
margin_bottom = 130.0
|
||||
|
||||
[node name="BucketLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_top = 149.0
|
||||
margin_top = 135.0
|
||||
margin_right = 137.0
|
||||
margin_bottom = 163.0
|
||||
margin_bottom = 149.0
|
||||
text = "Bucket"
|
||||
|
||||
[node name="left_fill_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 142.0
|
||||
margin_top = 146.0
|
||||
margin_top = 132.0
|
||||
margin_right = 221.0
|
||||
margin_bottom = 166.0
|
||||
margin_bottom = 152.0
|
||||
|
||||
[node name="right_fill_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 226.0
|
||||
margin_top = 146.0
|
||||
margin_top = 132.0
|
||||
margin_right = 305.0
|
||||
margin_bottom = 166.0
|
||||
margin_bottom = 152.0
|
||||
|
||||
[node name="LightenDarkenLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_top = 173.0
|
||||
margin_top = 157.0
|
||||
margin_right = 137.0
|
||||
margin_bottom = 187.0
|
||||
margin_bottom = 171.0
|
||||
text = "Lighten/Darken"
|
||||
|
||||
[node name="left_lightdark_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 142.0
|
||||
margin_top = 170.0
|
||||
margin_top = 154.0
|
||||
margin_right = 221.0
|
||||
margin_bottom = 190.0
|
||||
margin_bottom = 174.0
|
||||
|
||||
[node name="right_lightdark_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 226.0
|
||||
margin_top = 170.0
|
||||
margin_top = 154.0
|
||||
margin_right = 305.0
|
||||
margin_bottom = 190.0
|
||||
margin_bottom = 174.0
|
||||
|
||||
[node name="HSeparator4" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_top = 194.0
|
||||
margin_top = 176.0
|
||||
margin_right = 137.0
|
||||
margin_bottom = 198.0
|
||||
margin_bottom = 180.0
|
||||
|
||||
[node name="HSeparator5" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 142.0
|
||||
margin_top = 194.0
|
||||
margin_top = 176.0
|
||||
margin_right = 221.0
|
||||
margin_bottom = 198.0
|
||||
margin_bottom = 180.0
|
||||
|
||||
[node name="HSeparator6" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 226.0
|
||||
margin_top = 194.0
|
||||
margin_top = 176.0
|
||||
margin_right = 305.0
|
||||
margin_bottom = 198.0
|
||||
margin_bottom = 180.0
|
||||
|
||||
[node name="Switch Colors" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_top = 205.0
|
||||
margin_top = 185.0
|
||||
margin_right = 137.0
|
||||
margin_bottom = 219.0
|
||||
margin_bottom = 199.0
|
||||
text = "Switch Colors"
|
||||
|
||||
[node name="switch_colors" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||
margin_left = 142.0
|
||||
margin_top = 202.0
|
||||
margin_top = 182.0
|
||||
margin_right = 221.0
|
||||
margin_bottom = 222.0
|
||||
margin_bottom = 202.0
|
||||
|
||||
[node name="Popups" type="Node" parent="."]
|
||||
|
||||
|
@ -805,13 +848,15 @@ __meta__ = {
|
|||
[connection signal="about_to_show" from="." to="." method="_on_PreferencesDialog_about_to_show"]
|
||||
[connection signal="popup_hide" from="." to="." method="_on_PreferencesDialog_popup_hide"]
|
||||
[connection signal="item_selected" from="HSplitContainer/Tree" to="." method="_on_Tree_item_selected"]
|
||||
[connection signal="pressed" from="HSplitContainer/ScrollContainer/VBoxContainer/General/OpenLastProject" to="." method="_on_OpenLastProject_pressed"]
|
||||
[connection signal="pressed" from="HSplitContainer/ScrollContainer/VBoxContainer/General/SmoothZoom" to="." method="_on_SmoothZoom_pressed"]
|
||||
[connection signal="toggled" from="HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer/LeftIndicatorCheckbox" to="." method="_on_LeftIndicatorCheckbox_toggled"]
|
||||
[connection signal="toggled" from="HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer/RightIndicatorCheckbox" to="." method="_on_RightIndicatorCheckbox_toggled"]
|
||||
[connection signal="toggled" from="HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer/LeftToolIconCheckbox" to="." method="_on_LeftToolIconCheckbox_toggled"]
|
||||
[connection signal="toggled" from="HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer/RightToolIconCheckbox" to="." method="_on_RightToolIconCheckbox_toggled"]
|
||||
[connection signal="item_selected" from="HSplitContainer/ScrollContainer/VBoxContainer/General/PressureSentivity/PressureSensitivityOptionButton" to="." method="_on_PressureSensitivityOptionButton_item_selected"]
|
||||
[connection signal="pressed" from="HSplitContainer/ScrollContainer/VBoxContainer/General/OpenLastProject" to="." method="_on_OpenLastProject_pressed"]
|
||||
[connection signal="toggled" from="HSplitContainer/ScrollContainer/VBoxContainer/General/EnableAutosave" to="." method="_on_EnableAutosave_toggled"]
|
||||
[connection signal="value_changed" from="HSplitContainer/ScrollContainer/VBoxContainer/General/AutosaveInterval/AutosaveInterval" to="." method="_on_AutosaveInterval_value_changed"]
|
||||
[connection signal="color_changed" from="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GuideOptions/GuideColor" to="." method="_on_GuideColor_color_changed"]
|
||||
[connection signal="value_changed" from="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GridOptions/GridWidthValue" to="." method="_on_GridWidthValue_value_changed"]
|
||||
[connection signal="value_changed" from="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GridOptions/GridHeightValue" to="." method="_on_GridHeightValue_value_changed"]
|
||||
|
|
|
@ -41,6 +41,9 @@ func _ready() -> void:
|
|||
# Disable input until the shortcut selector is displayed
|
||||
set_process_input(false)
|
||||
|
||||
# Replace OK with Close since preference changes are being applied immediately, not after OK confirmation
|
||||
get_ok().text = tr("Close")
|
||||
|
||||
for child in languages.get_children():
|
||||
if child is Button:
|
||||
child.connect("pressed", self, "_on_Language_pressed", [child])
|
||||
|
@ -76,6 +79,16 @@ func _ready() -> void:
|
|||
Global.show_right_tool_icon = Global.config_cache.get_value("preferences", "show_right_tool_icon")
|
||||
right_tool_icon.pressed = Global.show_right_tool_icon
|
||||
|
||||
# Get autosave settings
|
||||
if Global.config_cache.has_section_key("preferences", "autosave_interval"):
|
||||
var autosave_interval = Global.config_cache.get_value("preferences", "autosave_interval")
|
||||
OpenSave.set_autosave_interval(autosave_interval)
|
||||
general.get_node("AutosaveInterval/AutosaveInterval").value = autosave_interval
|
||||
if Global.config_cache.has_section_key("preferences", "enable_autosave"):
|
||||
var enable_autosave = Global.config_cache.get_value("preferences", "enable_autosave")
|
||||
OpenSave.toggle_autosave(enable_autosave)
|
||||
general.get_node("EnableAutosave").pressed = enable_autosave
|
||||
|
||||
# Set default values for Canvas options
|
||||
if Global.config_cache.has_section_key("preferences", "grid_size"):
|
||||
var grid_size = Global.config_cache.get_value("preferences", "grid_size")
|
||||
|
@ -527,3 +540,15 @@ func _on_OpenLastProject_pressed():
|
|||
Global.open_last_project = !Global.open_last_project
|
||||
Global.config_cache.set_value("preferences", "open_last_project", Global.open_last_project)
|
||||
Global.config_cache.save("user://cache.ini")
|
||||
|
||||
|
||||
func _on_EnableAutosave_toggled(button_pressed : bool) -> void:
|
||||
OpenSave.toggle_autosave(button_pressed)
|
||||
Global.config_cache.set_value("preferences", "enable_autosave", button_pressed)
|
||||
Global.config_cache.save("user://cache.ini")
|
||||
|
||||
|
||||
func _on_AutosaveInterval_value_changed(value : float) -> void:
|
||||
OpenSave.set_autosave_interval(value)
|
||||
Global.config_cache.set_value("preferences", "autosave_interval", value)
|
||||
Global.config_cache.save("user://cache.ini")
|
||||
|
|
|
@ -193,8 +193,28 @@ func _ready() -> void:
|
|||
Global.config_cache.set_value("preferences", "open_last_project", true)
|
||||
if Global.config_cache.get_value("preferences", "open_last_project"):
|
||||
Global.open_last_project = Global.config_cache.get_value("preferences", "open_last_project")
|
||||
|
||||
# If backup file exists then Pixelorama was not closed properly (probably crashed) - reopen backup
|
||||
$BackupConfirmation.get_cancel().text = tr("Delete")
|
||||
if Global.config_cache.has_section("backups"):
|
||||
var project_paths = Global.config_cache.get_section_keys("backups")
|
||||
if project_paths.size() > 0:
|
||||
# Get backup path
|
||||
var backup_path = Global.config_cache.get_value("backups", project_paths[0])
|
||||
# Temporatily stop autosave until user confirms backup
|
||||
OpenSave.autosave_timer.stop()
|
||||
Global.can_draw = false
|
||||
# For it's only possible to reload the first found backup
|
||||
$BackupConfirmation.dialog_text = $BackupConfirmation.dialog_text % project_paths[0]
|
||||
$BackupConfirmation.connect("confirmed", self, "_on_BackupConfirmation_confirmed", [project_paths[0], backup_path])
|
||||
$BackupConfirmation.get_cancel().connect("pressed", self, "_on_BackupConfirmation_delete", [project_paths[0], backup_path])
|
||||
$BackupConfirmation.popup_centered()
|
||||
else:
|
||||
load_last_project()
|
||||
else:
|
||||
load_last_project()
|
||||
|
||||
|
||||
func _input(event : InputEvent) -> void:
|
||||
Global.left_cursor.position = get_global_mouse_position() + Vector2(-32, 32)
|
||||
Global.left_cursor.texture = Global.left_cursor_tool_texture
|
||||
|
@ -420,16 +440,17 @@ func help_menu_id_pressed(id : int) -> void:
|
|||
Global.can_draw = false
|
||||
|
||||
func load_last_project():
|
||||
# Check if any project was saved or opened last time
|
||||
if Global.config_cache.has_section_key("preferences", "last_project_path"):
|
||||
# Check if file still exists on disk
|
||||
var file_path = Global.config_cache.get_value("preferences", "last_project_path")
|
||||
var file_check := File.new()
|
||||
if file_check.file_exists(file_path): # If yes then load the file
|
||||
_on_OpenSprite_file_selected(file_path)
|
||||
else:
|
||||
# If file doesn't exist on disk then warn user about this
|
||||
$OpenLastProjectAlertDialog.popup_centered()
|
||||
if Global.open_last_project:
|
||||
# Check if any project was saved or opened last time
|
||||
if Global.config_cache.has_section_key("preferences", "last_project_path"):
|
||||
# Check if file still exists on disk
|
||||
var file_path = Global.config_cache.get_value("preferences", "last_project_path")
|
||||
var file_check := File.new()
|
||||
if file_check.file_exists(file_path): # If yes then load the file
|
||||
_on_OpenSprite_file_selected(file_path)
|
||||
else:
|
||||
# If file doesn't exist on disk then warn user about this
|
||||
$OpenLastProjectAlertDialog.popup_centered()
|
||||
|
||||
|
||||
func _on_UnsavedCanvasDialog_confirmed() -> void:
|
||||
|
@ -451,7 +472,7 @@ func _on_OpenSprite_file_selected(path : String) -> void:
|
|||
|
||||
|
||||
func _on_SaveSprite_file_selected(path : String) -> void:
|
||||
OpenSave.save_pxo_file(path)
|
||||
OpenSave.save_pxo_file(path, false)
|
||||
|
||||
# Set last opened project path and save
|
||||
Global.config_cache.set_value("preferences", "last_project_path", path)
|
||||
|
@ -782,16 +803,34 @@ func _on_QuitAndSaveDialog_custom_action(action : String) -> void:
|
|||
$SaveSprite.popup_centered()
|
||||
$QuitDialog.hide()
|
||||
Global.can_draw = false
|
||||
OpenSave.remove_backup()
|
||||
|
||||
|
||||
func _on_QuitDialog_confirmed() -> void:
|
||||
# Darken the UI to denote that the application is currently exiting
|
||||
# (it won't respond to user input in this state).
|
||||
modulate = Color(0.5, 0.5, 0.5)
|
||||
|
||||
OpenSave.remove_backup()
|
||||
get_tree().quit()
|
||||
|
||||
|
||||
func _on_BackupConfirmation_confirmed(project_path : String, backup_path : String) -> void:
|
||||
OpenSave.reload_backup_file(project_path, backup_path)
|
||||
OpenSave.autosave_timer.start()
|
||||
$ExportDialog.file_name = OpenSave.current_save_path.get_file().trim_suffix(".pxo")
|
||||
$ExportDialog.directory_path = OpenSave.current_save_path.get_base_dir()
|
||||
$ExportDialog.was_exported = false
|
||||
file_menu.set_item_text(3, tr("Save") + " %s" % OpenSave.current_save_path.get_file())
|
||||
file_menu.set_item_text(6, tr("Export"))
|
||||
|
||||
|
||||
func _on_BackupConfirmation_delete(project_path : String, backup_path : String) -> void:
|
||||
OpenSave.remove_backup_by_path(project_path, backup_path)
|
||||
OpenSave.autosave_timer.start()
|
||||
# Reopen last project
|
||||
load_last_project()
|
||||
|
||||
|
||||
func _on_LeftPixelPerfectMode_toggled(button_pressed) -> void:
|
||||
Global.left_pixel_perfect = button_pressed
|
||||
|
||||
|
|
|
@ -1,17 +1,31 @@
|
|||
extends Node
|
||||
|
||||
var current_save_path := ""
|
||||
# Stores a filename of a backup file in user:// until user saves manually
|
||||
var backup_save_path = ""
|
||||
|
||||
onready var autosave_timer : Timer
|
||||
var default_autosave_interval := 5 # Minutes
|
||||
|
||||
func _ready():
|
||||
autosave_timer = Timer.new()
|
||||
autosave_timer.one_shot = false
|
||||
autosave_timer.process_mode = Timer.TIMER_PROCESS_IDLE
|
||||
autosave_timer.connect("timeout", self, "_on_Autosave_timeout")
|
||||
add_child(autosave_timer)
|
||||
set_autosave_interval(default_autosave_interval)
|
||||
toggle_autosave(false) # Gets started from preferences dialog
|
||||
|
||||
|
||||
func open_pxo_file(path : String) -> void:
|
||||
func open_pxo_file(path : String, untitled_backup : bool = false) -> void:
|
||||
var file := File.new()
|
||||
var err := file.open_compressed(path, File.READ, File.COMPRESSION_ZSTD)
|
||||
if err == ERR_FILE_UNRECOGNIZED:
|
||||
err = file.open(path, File.READ) # If the file is not compressed open it raw (pre-v0.7)
|
||||
|
||||
if err != OK:
|
||||
Global.notification_label("File failed to open")
|
||||
file.close()
|
||||
OS.alert("Can't load file")
|
||||
return
|
||||
|
||||
var file_version := file.get_line() # Example, "v0.6"
|
||||
|
@ -133,13 +147,13 @@ func open_pxo_file(path : String) -> void:
|
|||
|
||||
file.close()
|
||||
|
||||
current_save_path = path
|
||||
Global.window_title = path.get_file() + " - Pixelorama"
|
||||
if not untitled_backup:
|
||||
# Untitled backup should not change window title and save path
|
||||
current_save_path = path
|
||||
Global.window_title = path.get_file() + " - Pixelorama"
|
||||
|
||||
|
||||
func save_pxo_file(path : String) -> void:
|
||||
current_save_path = path
|
||||
|
||||
func save_pxo_file(path : String, autosave : bool) -> void:
|
||||
var file := File.new()
|
||||
var err := file.open_compressed(path, File.WRITE, File.COMPRESSION_ZSTD)
|
||||
if err == OK:
|
||||
|
@ -209,10 +223,89 @@ func save_pxo_file(path : String) -> void:
|
|||
file.store_8(tag[3]) # Tag "to", the last frame
|
||||
file.store_line("END_FRAME_TAGS")
|
||||
|
||||
if !Global.saved:
|
||||
file.close()
|
||||
|
||||
if !Global.saved and not autosave:
|
||||
Global.saved = true
|
||||
|
||||
Global.window_title = current_save_path.get_file() + " - Pixelorama"
|
||||
Global.notification_label("File saved")
|
||||
file.close()
|
||||
if autosave:
|
||||
Global.notification_label("File autosaved")
|
||||
else:
|
||||
# First remove backup then set current save path
|
||||
remove_backup()
|
||||
current_save_path = path
|
||||
Global.notification_label("File saved")
|
||||
|
||||
if backup_save_path == "":
|
||||
Global.window_title = path.get_file() + " - Pixelorama"
|
||||
|
||||
else:
|
||||
Global.notification_label("File failed to save")
|
||||
|
||||
|
||||
func toggle_autosave(enable : bool) -> void:
|
||||
if enable:
|
||||
autosave_timer.start()
|
||||
else:
|
||||
autosave_timer.stop()
|
||||
|
||||
|
||||
func set_autosave_interval(interval : float) -> void:
|
||||
autosave_timer.wait_time = interval * 60 # Interval parameter is in minutes, wait_time is seconds
|
||||
autosave_timer.start()
|
||||
|
||||
|
||||
func _on_Autosave_timeout() -> void:
|
||||
if backup_save_path == "":
|
||||
# Create a new backup file if it doesn't exist yet
|
||||
backup_save_path = "user://backup-" + String(OS.get_unix_time())
|
||||
|
||||
store_backup_path()
|
||||
save_pxo_file(backup_save_path, true)
|
||||
|
||||
|
||||
# Backup paths are stored in two ways:
|
||||
# 1) User already manually saved and defined a save path -> {current_save_path, backup_save_path}
|
||||
# 2) User didn't manually saved, "untitled" backup is stored -> {backup_save_path, backup_save_path}
|
||||
func store_backup_path() -> void:
|
||||
if current_save_path != "":
|
||||
# Remove "untitled" backup if it existed on this project instance
|
||||
if Global.config_cache.has_section_key("backups", backup_save_path):
|
||||
Global.config_cache.erase_section_key("backups", backup_save_path)
|
||||
|
||||
Global.config_cache.set_value("backups", current_save_path, backup_save_path)
|
||||
else:
|
||||
Global.config_cache.set_value("backups", backup_save_path, backup_save_path)
|
||||
|
||||
Global.config_cache.save("user://cache.ini")
|
||||
|
||||
|
||||
func remove_backup() -> void:
|
||||
# Remove backup file
|
||||
if backup_save_path != "":
|
||||
if current_save_path != "":
|
||||
remove_backup_by_path(current_save_path, backup_save_path)
|
||||
else:
|
||||
# If manual save was not yet done - remove "untitled" backup
|
||||
remove_backup_by_path(backup_save_path, backup_save_path)
|
||||
backup_save_path = ""
|
||||
|
||||
|
||||
func remove_backup_by_path(project_path : String, backup_path : String) -> void:
|
||||
Directory.new().remove(backup_path)
|
||||
Global.config_cache.erase_section_key("backups", project_path)
|
||||
Global.config_cache.save("user://cache.ini")
|
||||
|
||||
|
||||
func reload_backup_file(project_path : String, backup_path : String) -> void:
|
||||
# If project path is the same as backup save path -> the backup was untitled
|
||||
open_pxo_file(backup_path, project_path == backup_path)
|
||||
backup_save_path = backup_path
|
||||
|
||||
if project_path != backup_path:
|
||||
current_save_path = project_path
|
||||
Global.window_title = project_path.get_file() + " - Pixelorama(*)"
|
||||
Global.saved = false
|
||||
|
||||
Global.notification_label("Backup reloaded")
|
||||
|
||||
|
|
|
@ -909,6 +909,15 @@ msgstr ""
|
|||
msgid "File saved"
|
||||
msgstr ""
|
||||
|
||||
msgid "File autosaved"
|
||||
msgstr ""
|
||||
|
||||
msgid "File failed to open"
|
||||
msgstr ""
|
||||
|
||||
msgid "File failed to save"
|
||||
msgstr ""
|
||||
|
||||
msgid "File exported"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1067,3 +1076,16 @@ msgstr ""
|
|||
|
||||
msgid "Creates multiple files but every file is stored in different directory that corresponds to its frame tag"
|
||||
msgstr ""
|
||||
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
|
||||
msgid "Autosaved backup for %s was found."
|
||||
"Do you want to reload it?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Backup reloaded"
|
||||
msgstr ""
|
||||
|
|
Loading…
Reference in a new issue