├── .gitignore ├── LICENSE ├── OFL.txt ├── README.md ├── demos └── Demo.tscn ├── main.gd ├── plugin.cfg ├── scripts └── time-input.gd └── tools ├── assets ├── Signika-VariableFont_wght.ttf ├── Signika-VariableFont_wght.ttf.import ├── pencil-create.png ├── pencil-create.png.import ├── time-icon.png ├── time-icon.png.import ├── time.png └── time.png.import ├── scenes ├── clock.tscn ├── manual_clock.tscn └── scripts │ ├── HoursPanel.gd │ ├── ManualTimePanel.gd │ ├── MinutesPanel.gd │ └── TimePanel.gd └── styles ├── BigTime.tres ├── default_theme.tres ├── highlight_hour_minute.tres ├── hover_tick_highlight.tres ├── no_radio_image.tres ├── tick_unhighlight.tres └── unhighlight_hour_minute.tres /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Godot-specific ignores 3 | .import/ 4 | export.cfg 5 | export_presets.cfg 6 | 7 | # Mono-specific ignores 8 | .mono/ 9 | data_*/ 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Aendryr 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /OFL.txt: -------------------------------------------------------------------------------- 1 | Copyright 2018 The Signika Project Authors (https://github.com/googlefonts/Signika). 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | This license is copied below, and is also available with a FAQ at: 5 | http://scripts.sil.org/OFL 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Godot-Date-Time-Input 2 | 3 | This plugin will add a TimeEdit node that allows you to easily select Time. It should work with mobile too. 4 | 5 | ### Note: 6 | 7 | Tested only with godot 4.1 (let me know if you tested it with other versions) 8 | 9 | # Assets 10 | 11 | The font used is under OFL license. 12 | The icons used belong to https://dribbble.com/AlekseyPopov and have been downloaded from here: https://themeui.net/evericons-free-icon-pack/ 13 | 14 | # How to use 15 | 16 | After installing the plugin add the node TimeEdit to your scene. 17 | In order to change styles and customize the node/s you have to change the Theme file wich can be found in tools/styles/default_theme.tres 18 | 19 | # WIP 20 | 21 | Date select (calendar) 22 | DateTime select (calendar+time) 23 | Interval select (calendar with groups? mby) 24 | 25 | -------------------------------------------------------------------------------- /demos/Demo.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://dug5b0gv1cxbh"] 2 | 3 | [ext_resource type="Script" path="res://addons/date-time-elements/scripts/time-input.gd" id="7_2kjc1"] 4 | 5 | [node name="Demo" type="Node2D"] 6 | 7 | [node name="TimeEdit" type="LineEdit" parent="."] 8 | anchors_preset = 8 9 | anchor_left = 0.5 10 | anchor_top = 0.5 11 | anchor_right = 0.5 12 | anchor_bottom = 0.5 13 | offset_left = 3.0 14 | offset_top = 1.0 15 | offset_right = 146.0 16 | offset_bottom = 32.0 17 | grow_horizontal = 2 18 | grow_vertical = 2 19 | placeholder_text = "hh:mm (a/p)m" 20 | script = ExtResource("7_2kjc1") 21 | 22 | [connection signal="mouse_entered" from="TimeEdit/Clock" to="TimeEdit/Clock" method="_on_mouse_entered"] 23 | [connection signal="mouse_exited" from="TimeEdit/Clock" to="TimeEdit/Clock" method="_on_mouse_exited"] 24 | [connection signal="visibility_changed" from="TimeEdit/Clock" to="TimeEdit/Clock" method="_on_visibility_changed"] 25 | [connection signal="draw" from="TimeEdit/ManualClock" to="TimeEdit/ManualClock" method="_on_draw"] 26 | -------------------------------------------------------------------------------- /main.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends EditorPlugin 3 | 4 | func _enter_tree(): 5 | add_custom_type("TimeEdit", "LineEdit", preload("scripts/time-input.gd"), preload("tools/assets/time-icon.png")) 6 | 7 | func _exit_tree(): 8 | remove_custom_type("Time") 9 | -------------------------------------------------------------------------------- /plugin.cfg: -------------------------------------------------------------------------------- 1 | [plugin] 2 | 3 | name="Date Time Elements" 4 | description="This plugin will add a TimeEdit node that allows you easily select Time. It should work on mobile too." 5 | author="Aendryr" 6 | version="1.0.2" 7 | script="main.gd" 8 | -------------------------------------------------------------------------------- /scripts/time-input.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends LineEdit 3 | ## An InputField for Time 4 | 5 | ## Singal for changing time 6 | signal time_changed; 7 | 8 | ## If active will get current time as implicit value. 9 | ## The value is set on the _ready function. 10 | @export var current_time:bool = false 11 | 12 | ## Which popup should be displayed by default when first click happens 13 | @export_enum("Clock","ManualClock") var popup:String = "Clock" 14 | 15 | ## The color of the clock hand 16 | @export_color_no_alpha var hand_color = Color8(72,148,60) 17 | 18 | ## Implicit placeholder text 19 | var format:String="hh:mm (a/p)m"; 20 | 21 | # Force placeholder to be "hh:mm (a/p)m" // WIP 22 | func _init() -> void: 23 | self.placeholder_text=format 24 | 25 | # Add nodes from tools/scenes for selecting time 26 | # Change hand color for Time.tscn 27 | # Connect signal time_changed to self and children 28 | func _ready() -> void: 29 | var time_clock = preload("res://addons/date-time-elements/tools/scenes/clock.tscn").instantiate() 30 | var manual_time_clock = preload("res://addons/date-time-elements/tools/scenes/manual_clock.tscn").instantiate() 31 | 32 | time_clock.get_node("Hours/Hand/Center").modulate = hand_color; 33 | time_clock.get_node("Hours/Hand/Circle").modulate = hand_color; 34 | time_clock.get_node("Hours/Hand/Panel").modulate = hand_color; 35 | time_clock.get_node("Minutes/Hand/Center").modulate = hand_color; 36 | time_clock.get_node("Minutes/Hand/Circle").modulate = hand_color; 37 | time_clock.get_node("Minutes/Hand/Panel").modulate = hand_color; 38 | time_clock.global_position = Vector2(get_viewport_rect().size.x/2 - time_clock.size.x/2 - global_position.x,0) 39 | manual_time_clock.global_position = Vector2(get_viewport_rect().size.x/2 - manual_time_clock.size.x/2 - global_position.x,0) 40 | 41 | self.add_child(time_clock) 42 | self.add_child(manual_time_clock) 43 | 44 | self.time_changed.connect(_on_time_changed); 45 | 46 | if(current_time): 47 | self.time_changed.emit(get_current_time()[0],get_current_time()[1]) 48 | self.focus_entered.connect(_on_click) 49 | 50 | ## Releases focus and mouse button from LineEdit 51 | func _on_click() -> void: 52 | var a = InputEventMouseButton.new() 53 | a.set_button_index(1) 54 | a.set_pressed(false) 55 | Input.parse_input_event(a) 56 | self.release_focus() 57 | get_node(popup).show() 58 | 59 | ## Changes the text of the LineEdit 60 | func _on_time_changed(time,ampm)->void: 61 | self.text=time+" "+ampm 62 | 63 | ## return [ 0 => "hour:min":String, 1 => "am/pm":string ]:Array 64 | func get_current_time()->Array: 65 | var time:Dictionary = Time.get_datetime_dict_from_system() 66 | var hour = time["hour"] 67 | var minute = time["minute"] 68 | if(minute < 10): 69 | minute="0"+str(minute) 70 | var ampm="" 71 | if hour - 12 < 0: 72 | ampm = "am" 73 | else: 74 | ampm = "pm" 75 | hour = abs(hour-12); 76 | if(hour < 10): 77 | hour = "0"+str(hour) 78 | return [str(hour)+":"+str(minute),ampm] 79 | -------------------------------------------------------------------------------- /tools/assets/Signika-VariableFont_wght.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aendryr/Godot-Date-Time-Input/36a7faaace9e956bcdb5e97e3e1e602e81e74790/tools/assets/Signika-VariableFont_wght.ttf -------------------------------------------------------------------------------- /tools/assets/Signika-VariableFont_wght.ttf.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="font_data_dynamic" 4 | type="FontFile" 5 | uid="uid://du2k7gp5t4sgx" 6 | path="res://.godot/imported/Signika-VariableFont_wght.ttf-0607bc35fd3b528fb65686ea3d637ed3.fontdata" 7 | 8 | [deps] 9 | 10 | source_file="res://addons/date-time-elements/tools/assets/Signika-VariableFont_wght.ttf" 11 | dest_files=["res://.godot/imported/Signika-VariableFont_wght.ttf-0607bc35fd3b528fb65686ea3d637ed3.fontdata"] 12 | 13 | [params] 14 | 15 | Rendering=null 16 | antialiasing=1 17 | generate_mipmaps=false 18 | multichannel_signed_distance_field=false 19 | msdf_pixel_range=8 20 | msdf_size=48 21 | allow_system_fallback=true 22 | force_autohinter=false 23 | hinting=1 24 | subpixel_positioning=1 25 | oversampling=0.0 26 | Fallbacks=null 27 | fallbacks=[] 28 | Compress=null 29 | compress=true 30 | preload=[] 31 | language_support={} 32 | script_support={} 33 | opentype_features={} 34 | -------------------------------------------------------------------------------- /tools/assets/pencil-create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aendryr/Godot-Date-Time-Input/36a7faaace9e956bcdb5e97e3e1e602e81e74790/tools/assets/pencil-create.png -------------------------------------------------------------------------------- /tools/assets/pencil-create.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://ctequww0j0g3s" 6 | path="res://.godot/imported/pencil-create.png-5506304e9045307947782ecbc686aa21.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://addons/date-time-elements/tools/assets/pencil-create.png" 14 | dest_files=["res://.godot/imported/pencil-create.png-5506304e9045307947782ecbc686aa21.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /tools/assets/time-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aendryr/Godot-Date-Time-Input/36a7faaace9e956bcdb5e97e3e1e602e81e74790/tools/assets/time-icon.png -------------------------------------------------------------------------------- /tools/assets/time-icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dxea78gkcsbca" 6 | path="res://.godot/imported/time-icon.png-39a555d1409fe5c1698bc3452c82e226.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://addons/date-time-elements/tools/assets/time-icon.png" 14 | dest_files=["res://.godot/imported/time-icon.png-39a555d1409fe5c1698bc3452c82e226.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /tools/assets/time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aendryr/Godot-Date-Time-Input/36a7faaace9e956bcdb5e97e3e1e602e81e74790/tools/assets/time.png -------------------------------------------------------------------------------- /tools/assets/time.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bimkc5conx88y" 6 | path="res://.godot/imported/time.png-08ef3da7e12f95297ecec66fc7158ebd.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://addons/date-time-elements/tools/assets/time.png" 14 | dest_files=["res://.godot/imported/time.png-08ef3da7e12f95297ecec66fc7158ebd.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /tools/scenes/clock.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=10 format=3 uid="uid://dd62kph24qxqm"] 2 | 3 | [ext_resource type="Script" path="res://addons/date-time-elements/tools/scenes/scripts/TimePanel.gd" id="1_uh78g"] 4 | [ext_resource type="Texture2D" uid="uid://ctequww0j0g3s" path="res://addons/date-time-elements/tools/assets/pencil-create.png" id="2_ta41s"] 5 | [ext_resource type="Script" path="res://addons/date-time-elements/tools/scenes/scripts/MinutesPanel.gd" id="3_vmjrw"] 6 | [ext_resource type="Script" path="res://addons/date-time-elements/tools/scenes/scripts/HoursPanel.gd" id="4_tepjp"] 7 | 8 | [sub_resource type="FontFile" id="FontFile_nggve"] 9 | subpixel_positioning = 0 10 | msdf_pixel_range = 14 11 | msdf_size = 128 12 | cache/0/16/0/ascent = 0.0 13 | cache/0/16/0/descent = 0.0 14 | cache/0/16/0/underline_position = 0.0 15 | cache/0/16/0/underline_thickness = 0.0 16 | cache/0/16/0/scale = 1.0 17 | cache/0/16/0/kerning_overrides/16/0 = Vector2(0, 0) 18 | cache/0/16/0/kerning_overrides/40/0 = Vector2(0, 0) 19 | cache/0/16/0/kerning_overrides/48/0 = Vector2(0, 0) 20 | cache/0/40/0/ascent = 0.0 21 | cache/0/40/0/descent = 0.0 22 | cache/0/40/0/underline_position = 0.0 23 | cache/0/40/0/underline_thickness = 0.0 24 | cache/0/40/0/scale = 1.0 25 | cache/0/40/0/kerning_overrides/16/0 = Vector2(0, 0) 26 | cache/0/40/0/kerning_overrides/40/0 = Vector2(0, 0) 27 | cache/0/40/0/kerning_overrides/48/0 = Vector2(0, 0) 28 | cache/0/48/0/ascent = 0.0 29 | cache/0/48/0/descent = 0.0 30 | cache/0/48/0/underline_position = 0.0 31 | cache/0/48/0/underline_thickness = 0.0 32 | cache/0/48/0/scale = 1.0 33 | cache/0/48/0/kerning_overrides/16/0 = Vector2(0, 0) 34 | cache/0/48/0/kerning_overrides/40/0 = Vector2(0, 0) 35 | cache/0/48/0/kerning_overrides/48/0 = Vector2(0, 0) 36 | 37 | [sub_resource type="ButtonGroup" id="ButtonGroup_skeia"] 38 | 39 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_5mkke"] 40 | bg_color = Color(0.117647, 0.101961, 0.101961, 1) 41 | corner_radius_top_left = 200 42 | corner_radius_top_right = 200 43 | corner_radius_bottom_right = 200 44 | corner_radius_bottom_left = 200 45 | 46 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_wuhcs"] 47 | bg_color = Color(1, 1, 1, 1) 48 | corner_radius_top_left = 250 49 | corner_radius_top_right = 250 50 | corner_radius_bottom_right = 250 51 | corner_radius_bottom_left = 250 52 | anti_aliasing_size = 0.01 53 | 54 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_pttem"] 55 | bg_color = Color(1, 1, 1, 1) 56 | 57 | [node name="Clock" type="Panel"] 58 | visible = false 59 | offset_right = 337.0 60 | offset_bottom = 457.0 61 | script = ExtResource("1_uh78g") 62 | 63 | [node name="LayoutTop" type="FlowContainer" parent="."] 64 | layout_mode = 1 65 | anchors_preset = 5 66 | anchor_left = 0.5 67 | anchor_right = 0.5 68 | offset_left = -122.0 69 | offset_top = 32.0 70 | offset_right = 122.0 71 | offset_bottom = 100.0 72 | grow_horizontal = 2 73 | theme_override_constants/h_separation = 20 74 | alignment = 1 75 | vertical = true 76 | 77 | [node name="Value" type="Label" parent="LayoutTop"] 78 | layout_mode = 2 79 | theme_override_fonts/font = SubResource("FontFile_nggve") 80 | theme_override_font_sizes/font_size = 48 81 | text = "12:00" 82 | 83 | [node name="Label" type="Label" parent="LayoutTop/Value"] 84 | layout_mode = 0 85 | offset_top = -13.0 86 | offset_right = 40.0 87 | offset_bottom = 13.0 88 | text = "TIME" 89 | 90 | [node name="AMPMContainer" type="VBoxContainer" parent="LayoutTop"] 91 | layout_mode = 2 92 | theme_override_constants/separation = 0 93 | 94 | [node name="AM" type="CheckBox" parent="LayoutTop/AMPMContainer"] 95 | layout_mode = 2 96 | button_pressed = true 97 | button_group = SubResource("ButtonGroup_skeia") 98 | text = "AM" 99 | 100 | [node name="PM" type="CheckBox" parent="LayoutTop/AMPMContainer"] 101 | layout_mode = 2 102 | button_group = SubResource("ButtonGroup_skeia") 103 | text = "PM" 104 | 105 | [node name="ChangeMode" type="Button" parent="LayoutTop"] 106 | layout_mode = 2 107 | icon = ExtResource("2_ta41s") 108 | 109 | [node name="Minutes" type="Panel" parent="."] 110 | visible = false 111 | layout_mode = 1 112 | anchors_preset = 8 113 | anchor_left = 0.5 114 | anchor_top = 0.5 115 | anchor_right = 0.5 116 | anchor_bottom = 0.5 117 | offset_left = -123.2 118 | offset_top = -93.2 119 | offset_right = 123.2 120 | offset_bottom = 153.2 121 | grow_horizontal = 2 122 | grow_vertical = 2 123 | theme_override_styles/panel = SubResource("StyleBoxFlat_5mkke") 124 | script = ExtResource("3_vmjrw") 125 | 126 | [node name="Hand" type="Marker2D" parent="Minutes"] 127 | position = Vector2(123.2, 123.2) 128 | 129 | [node name="Center" type="Panel" parent="Minutes/Hand"] 130 | modulate = Color(0.282353, 0.580392, 0.235294, 1) 131 | offset_left = -4.0 132 | offset_top = -4.0 133 | offset_right = 4.0 134 | offset_bottom = 4.0 135 | theme_override_styles/panel = SubResource("StyleBoxFlat_wuhcs") 136 | 137 | [node name="Circle" type="Panel" parent="Minutes/Hand"] 138 | modulate = Color(0.282353, 0.580392, 0.235294, 1) 139 | offset_left = -18.0 140 | offset_top = -110.2 141 | offset_right = 18.0 142 | offset_bottom = -74.2 143 | theme_override_styles/panel = SubResource("StyleBoxFlat_wuhcs") 144 | 145 | [node name="Panel" type="Panel" parent="Minutes/Hand"] 146 | modulate = Color(0.282353, 0.580392, 0.235294, 1) 147 | offset_left = 2.0 148 | offset_top = 2.0 149 | offset_right = 6.0 150 | offset_bottom = 98.0 151 | rotation = 3.14159 152 | theme_override_styles/panel = SubResource("StyleBoxFlat_pttem") 153 | 154 | [node name="05" type="Label" parent="Minutes" groups=["date-time-minutes-popup"]] 155 | layout_mode = 0 156 | offset_left = 151.7 157 | offset_top = 24.7 158 | offset_right = 187.7 159 | offset_bottom = 60.7 160 | text = "05" 161 | horizontal_alignment = 1 162 | vertical_alignment = 1 163 | 164 | [node name="10" type="Label" parent="Minutes" groups=["date-time-minutes-popup"]] 165 | layout_mode = 0 166 | offset_left = 184.7 167 | offset_top = 58.7 168 | offset_right = 220.7 169 | offset_bottom = 94.7 170 | text = "10" 171 | horizontal_alignment = 1 172 | vertical_alignment = 1 173 | 174 | [node name="15" type="Label" parent="Minutes" groups=["date-time-minutes-popup"]] 175 | layout_mode = 0 176 | offset_left = 197.7 177 | offset_top = 104.7 178 | offset_right = 233.7 179 | offset_bottom = 140.7 180 | text = "15" 181 | horizontal_alignment = 1 182 | vertical_alignment = 1 183 | 184 | [node name="20" type="Label" parent="Minutes" groups=["date-time-minutes-popup"]] 185 | layout_mode = 0 186 | offset_left = 184.7 187 | offset_top = 150.7 188 | offset_right = 220.7 189 | offset_bottom = 186.7 190 | text = "20" 191 | horizontal_alignment = 1 192 | vertical_alignment = 1 193 | 194 | [node name="25" type="Label" parent="Minutes" groups=["date-time-minutes-popup"]] 195 | layout_mode = 0 196 | offset_left = 151.7 197 | offset_top = 184.7 198 | offset_right = 187.7 199 | offset_bottom = 220.7 200 | text = "25" 201 | horizontal_alignment = 1 202 | vertical_alignment = 1 203 | 204 | [node name="30" type="Label" parent="Minutes" groups=["date-time-minutes-popup"]] 205 | layout_mode = 0 206 | offset_left = 105.7 207 | offset_top = 196.7 208 | offset_right = 141.7 209 | offset_bottom = 232.7 210 | text = "30" 211 | horizontal_alignment = 1 212 | vertical_alignment = 1 213 | 214 | [node name="35" type="Label" parent="Minutes" groups=["date-time-minutes-popup"]] 215 | layout_mode = 0 216 | offset_left = 58.7 217 | offset_top = 184.7 218 | offset_right = 94.7 219 | offset_bottom = 220.7 220 | text = "35" 221 | horizontal_alignment = 1 222 | vertical_alignment = 1 223 | 224 | [node name="40" type="Label" parent="Minutes" groups=["date-time-minutes-popup"]] 225 | layout_mode = 0 226 | offset_left = 25.7 227 | offset_top = 150.7 228 | offset_right = 61.7 229 | offset_bottom = 186.7 230 | text = "40" 231 | horizontal_alignment = 1 232 | vertical_alignment = 1 233 | 234 | [node name="45" type="Label" parent="Minutes" groups=["date-time-minutes-popup"]] 235 | layout_mode = 0 236 | offset_left = 13.7 237 | offset_top = 104.7 238 | offset_right = 49.7 239 | offset_bottom = 140.7 240 | text = "45" 241 | horizontal_alignment = 1 242 | vertical_alignment = 1 243 | 244 | [node name="50" type="Label" parent="Minutes" groups=["date-time-minutes-popup"]] 245 | layout_mode = 0 246 | offset_left = 24.7 247 | offset_top = 58.7 248 | offset_right = 60.7 249 | offset_bottom = 94.7 250 | text = "50" 251 | horizontal_alignment = 1 252 | vertical_alignment = 1 253 | 254 | [node name="55" type="Label" parent="Minutes" groups=["date-time-minutes-popup"]] 255 | layout_mode = 0 256 | offset_left = 59.7 257 | offset_top = 24.7 258 | offset_right = 95.7 259 | offset_bottom = 60.7 260 | text = "55" 261 | horizontal_alignment = 1 262 | vertical_alignment = 1 263 | 264 | [node name="00" type="Label" parent="Minutes" groups=["date-time-minutes-popup"]] 265 | layout_mode = 0 266 | offset_left = 105.7 267 | offset_top = 12.7 268 | offset_right = 141.7 269 | offset_bottom = 48.7 270 | text = "00" 271 | horizontal_alignment = 1 272 | vertical_alignment = 1 273 | 274 | [node name="Hours" type="Panel" parent="."] 275 | visible = false 276 | layout_mode = 1 277 | anchors_preset = 8 278 | anchor_left = 0.5 279 | anchor_top = 0.5 280 | anchor_right = 0.5 281 | anchor_bottom = 0.5 282 | offset_left = -123.2 283 | offset_top = -93.2 284 | offset_right = 123.2 285 | offset_bottom = 153.2 286 | grow_horizontal = 2 287 | grow_vertical = 2 288 | theme_override_styles/panel = SubResource("StyleBoxFlat_5mkke") 289 | script = ExtResource("4_tepjp") 290 | 291 | [node name="Hand" type="Marker2D" parent="Hours"] 292 | position = Vector2(123.2, 123.2) 293 | 294 | [node name="Center" type="Panel" parent="Hours/Hand"] 295 | modulate = Color(0.282353, 0.580392, 0.235294, 1) 296 | offset_left = -4.0 297 | offset_top = -4.0 298 | offset_right = 4.0 299 | offset_bottom = 4.0 300 | theme_override_styles/panel = SubResource("StyleBoxFlat_wuhcs") 301 | 302 | [node name="Circle" type="Panel" parent="Hours/Hand"] 303 | modulate = Color(0.282353, 0.580392, 0.235294, 1) 304 | offset_left = -18.0 305 | offset_top = -110.2 306 | offset_right = 18.0 307 | offset_bottom = -74.2 308 | theme_override_styles/panel = SubResource("StyleBoxFlat_wuhcs") 309 | 310 | [node name="Panel" type="Panel" parent="Hours/Hand"] 311 | modulate = Color(0.282353, 0.580392, 0.235294, 1) 312 | offset_left = 2.0 313 | offset_top = 2.0 314 | offset_right = 6.0 315 | offset_bottom = 98.0 316 | rotation = 3.14159 317 | theme_override_styles/panel = SubResource("StyleBoxFlat_pttem") 318 | 319 | [node name="01" type="Label" parent="Hours" groups=["date-time-hours-popup"]] 320 | layout_mode = 0 321 | offset_left = 151.7 322 | offset_top = 24.7 323 | offset_right = 187.7 324 | offset_bottom = 60.7 325 | text = "01" 326 | horizontal_alignment = 1 327 | vertical_alignment = 1 328 | 329 | [node name="02" type="Label" parent="Hours" groups=["date-time-hours-popup"]] 330 | layout_mode = 0 331 | offset_left = 184.7 332 | offset_top = 58.7 333 | offset_right = 220.7 334 | offset_bottom = 94.7 335 | text = "02" 336 | horizontal_alignment = 1 337 | vertical_alignment = 1 338 | 339 | [node name="03" type="Label" parent="Hours" groups=["date-time-hours-popup"]] 340 | layout_mode = 0 341 | offset_left = 197.7 342 | offset_top = 104.7 343 | offset_right = 233.7 344 | offset_bottom = 140.7 345 | text = "03" 346 | horizontal_alignment = 1 347 | vertical_alignment = 1 348 | 349 | [node name="04" type="Label" parent="Hours" groups=["date-time-hours-popup"]] 350 | layout_mode = 0 351 | offset_left = 184.7 352 | offset_top = 150.7 353 | offset_right = 220.7 354 | offset_bottom = 186.7 355 | text = "04" 356 | horizontal_alignment = 1 357 | vertical_alignment = 1 358 | 359 | [node name="05" type="Label" parent="Hours" groups=["date-time-hours-popup"]] 360 | layout_mode = 0 361 | offset_left = 151.7 362 | offset_top = 184.7 363 | offset_right = 187.7 364 | offset_bottom = 220.7 365 | text = "05" 366 | horizontal_alignment = 1 367 | vertical_alignment = 1 368 | 369 | [node name="06" type="Label" parent="Hours" groups=["date-time-hours-popup"]] 370 | layout_mode = 0 371 | offset_left = 105.7 372 | offset_top = 196.7 373 | offset_right = 141.7 374 | offset_bottom = 232.7 375 | text = "06" 376 | horizontal_alignment = 1 377 | vertical_alignment = 1 378 | 379 | [node name="07" type="Label" parent="Hours" groups=["date-time-hours-popup"]] 380 | layout_mode = 0 381 | offset_left = 58.7 382 | offset_top = 184.7 383 | offset_right = 94.7 384 | offset_bottom = 220.7 385 | text = "07" 386 | horizontal_alignment = 1 387 | vertical_alignment = 1 388 | 389 | [node name="08" type="Label" parent="Hours" groups=["date-time-hours-popup"]] 390 | layout_mode = 0 391 | offset_left = 25.7 392 | offset_top = 150.7 393 | offset_right = 61.7 394 | offset_bottom = 186.7 395 | text = "08" 396 | horizontal_alignment = 1 397 | vertical_alignment = 1 398 | 399 | [node name="09" type="Label" parent="Hours" groups=["date-time-hours-popup"]] 400 | layout_mode = 0 401 | offset_left = 13.7 402 | offset_top = 104.7 403 | offset_right = 49.7 404 | offset_bottom = 140.7 405 | text = "09" 406 | horizontal_alignment = 1 407 | vertical_alignment = 1 408 | 409 | [node name="10" type="Label" parent="Hours" groups=["date-time-hours-popup"]] 410 | layout_mode = 0 411 | offset_left = 24.7 412 | offset_top = 58.7 413 | offset_right = 60.7 414 | offset_bottom = 94.7 415 | text = "10" 416 | horizontal_alignment = 1 417 | vertical_alignment = 1 418 | 419 | [node name="11" type="Label" parent="Hours" groups=["date-time-hours-popup"]] 420 | layout_mode = 0 421 | offset_left = 59.7 422 | offset_top = 24.7 423 | offset_right = 95.7 424 | offset_bottom = 60.7 425 | text = "11" 426 | horizontal_alignment = 1 427 | vertical_alignment = 1 428 | 429 | [node name="12" type="Label" parent="Hours" groups=["date-time-hours-popup"]] 430 | layout_mode = 0 431 | offset_left = 105.0 432 | offset_top = 13.0 433 | offset_right = 141.0 434 | offset_bottom = 49.0 435 | text = "12" 436 | horizontal_alignment = 1 437 | vertical_alignment = 1 438 | 439 | [node name="LayoutBottom" type="FlowContainer" parent="."] 440 | layout_mode = 1 441 | anchors_preset = 7 442 | anchor_left = 0.5 443 | anchor_top = 1.0 444 | anchor_right = 0.5 445 | anchor_bottom = 1.0 446 | offset_left = -121.5 447 | offset_top = -52.0 448 | offset_right = 122.5 449 | offset_bottom = -21.0 450 | grow_horizontal = 2 451 | grow_vertical = 0 452 | alignment = 2 453 | 454 | [node name="Cancel" type="Button" parent="LayoutBottom"] 455 | layout_mode = 2 456 | text = "Cancel" 457 | 458 | [connection signal="mouse_entered" from="." to="." method="_on_mouse_entered"] 459 | [connection signal="mouse_exited" from="." to="." method="_on_mouse_exited"] 460 | [connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"] 461 | [connection signal="pressed" from="LayoutTop/AMPMContainer/AM" to="." method="_on_AMPM_pressed" binds= ["am"]] 462 | [connection signal="pressed" from="LayoutTop/AMPMContainer/PM" to="." method="_on_AMPM_pressed" binds= ["pm"]] 463 | [connection signal="pressed" from="LayoutTop/ChangeMode" to="." method="_on_SwitchToManual_pressed"] 464 | [connection signal="mouse_entered" from="Minutes" to="Minutes" method="_on_mouse_entered"] 465 | [connection signal="mouse_exited" from="Minutes" to="Minutes" method="_on_mouse_exited"] 466 | [connection signal="visibility_changed" from="Minutes" to="Minutes" method="_on_visibility_changed"] 467 | [connection signal="mouse_entered" from="Hours" to="Hours" method="_on_mouse_entered"] 468 | [connection signal="mouse_exited" from="Hours" to="Hours" method="_on_mouse_exited"] 469 | [connection signal="visibility_changed" from="Hours" to="Hours" method="_on_visibility_changed"] 470 | [connection signal="pressed" from="LayoutBottom/Cancel" to="." method="_on_cancel_pressed"] 471 | -------------------------------------------------------------------------------- /tools/scenes/manual_clock.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=3 uid="uid://cgnmf5j3rno6r"] 2 | 3 | [ext_resource type="Script" path="res://addons/date-time-elements/tools/scenes/scripts/ManualTimePanel.gd" id="1_lswku"] 4 | [ext_resource type="Texture2D" uid="uid://bimkc5conx88y" path="res://addons/date-time-elements/tools/assets/time.png" id="2_0k6l0"] 5 | 6 | [sub_resource type="FontFile" id="FontFile_nggve"] 7 | subpixel_positioning = 0 8 | msdf_pixel_range = 14 9 | msdf_size = 128 10 | cache/0/16/0/ascent = 0.0 11 | cache/0/16/0/descent = 0.0 12 | cache/0/16/0/underline_position = 0.0 13 | cache/0/16/0/underline_thickness = 0.0 14 | cache/0/16/0/scale = 1.0 15 | cache/0/16/0/kerning_overrides/16/0 = Vector2(0, 0) 16 | cache/0/16/0/kerning_overrides/40/0 = Vector2(0, 0) 17 | cache/0/16/0/kerning_overrides/48/0 = Vector2(0, 0) 18 | cache/0/40/0/ascent = 0.0 19 | cache/0/40/0/descent = 0.0 20 | cache/0/40/0/underline_position = 0.0 21 | cache/0/40/0/underline_thickness = 0.0 22 | cache/0/40/0/scale = 1.0 23 | cache/0/40/0/kerning_overrides/16/0 = Vector2(0, 0) 24 | cache/0/40/0/kerning_overrides/40/0 = Vector2(0, 0) 25 | cache/0/40/0/kerning_overrides/48/0 = Vector2(0, 0) 26 | cache/0/48/0/ascent = 0.0 27 | cache/0/48/0/descent = 0.0 28 | cache/0/48/0/underline_position = 0.0 29 | cache/0/48/0/underline_thickness = 0.0 30 | cache/0/48/0/scale = 1.0 31 | cache/0/48/0/kerning_overrides/16/0 = Vector2(0, 0) 32 | cache/0/48/0/kerning_overrides/40/0 = Vector2(0, 0) 33 | cache/0/48/0/kerning_overrides/48/0 = Vector2(0, 0) 34 | 35 | [sub_resource type="ButtonGroup" id="ButtonGroup_skeia"] 36 | 37 | [node name="ManualClock" type="Panel"] 38 | visible = false 39 | offset_right = 269.0 40 | offset_bottom = 244.0 41 | script = ExtResource("1_lswku") 42 | 43 | [node name="LayoutTop" type="FlowContainer" parent="."] 44 | layout_mode = 1 45 | anchors_preset = 5 46 | anchor_left = 0.5 47 | anchor_right = 0.5 48 | offset_left = -106.0 49 | offset_top = 32.0 50 | offset_right = 106.0 51 | offset_bottom = 100.0 52 | grow_horizontal = 2 53 | alignment = 1 54 | vertical = true 55 | 56 | [node name="Value" type="Label" parent="LayoutTop"] 57 | layout_mode = 2 58 | theme_override_fonts/font = SubResource("FontFile_nggve") 59 | theme_override_font_sizes/font_size = 48 60 | text = "12:00" 61 | 62 | [node name="Label" type="Label" parent="LayoutTop/Value"] 63 | layout_mode = 0 64 | offset_top = -13.0 65 | offset_right = 40.0 66 | offset_bottom = 13.0 67 | text = "TIME" 68 | 69 | [node name="AMPMContainer" type="VBoxContainer" parent="LayoutTop"] 70 | layout_mode = 2 71 | theme_override_constants/separation = 0 72 | 73 | [node name="AM" type="CheckBox" parent="LayoutTop/AMPMContainer"] 74 | layout_mode = 2 75 | button_pressed = true 76 | button_group = SubResource("ButtonGroup_skeia") 77 | text = "AM" 78 | 79 | [node name="PM" type="CheckBox" parent="LayoutTop/AMPMContainer"] 80 | layout_mode = 2 81 | button_group = SubResource("ButtonGroup_skeia") 82 | text = "PM" 83 | 84 | [node name="ChangeMode" type="Button" parent="LayoutTop"] 85 | layout_mode = 2 86 | icon = ExtResource("2_0k6l0") 87 | 88 | [node name="TimeEdit" type="LineEdit" parent="."] 89 | layout_mode = 1 90 | anchors_preset = 7 91 | anchor_left = 0.5 92 | anchor_top = 1.0 93 | anchor_right = 0.5 94 | anchor_bottom = 1.0 95 | offset_left = -106.0 96 | offset_top = -119.0 97 | offset_right = 106.0 98 | offset_bottom = -70.0 99 | grow_horizontal = 2 100 | grow_vertical = 0 101 | 102 | [node name="Label" type="Label" parent="TimeEdit"] 103 | layout_mode = 0 104 | offset_left = 15.5 105 | offset_top = -13.0 106 | offset_right = 55.5 107 | offset_bottom = 13.0 108 | text = "Time" 109 | 110 | [node name="LayoutBottom" type="FlowContainer" parent="."] 111 | layout_mode = 1 112 | anchors_preset = 7 113 | anchor_left = 0.5 114 | anchor_top = 1.0 115 | anchor_right = 0.5 116 | anchor_bottom = 1.0 117 | offset_left = -106.0 118 | offset_top = -49.0 119 | offset_right = 106.0 120 | grow_horizontal = 2 121 | grow_vertical = 0 122 | alignment = 2 123 | 124 | [node name="Close" type="Button" parent="LayoutBottom"] 125 | layout_mode = 2 126 | text = "Cancel" 127 | 128 | [connection signal="draw" from="." to="." method="_on_draw"] 129 | [connection signal="pressed" from="LayoutTop/AMPMContainer/AM" to="." method="_on_AMPM_pressed" binds= ["am"]] 130 | [connection signal="pressed" from="LayoutTop/AMPMContainer/PM" to="." method="_on_AMPM_pressed" binds= ["pm"]] 131 | [connection signal="pressed" from="LayoutTop/ChangeMode" to="." method="_on_ChangeToClock_pressed"] 132 | [connection signal="focus_entered" from="TimeEdit" to="." method="_on_time_edit_focus_entered"] 133 | [connection signal="text_changed" from="TimeEdit" to="." method="_on_time_edit_text_changed"] 134 | [connection signal="pressed" from="LayoutBottom/Close" to="." method="_on_close_pressed"] 135 | -------------------------------------------------------------------------------- /tools/scenes/scripts/HoursPanel.gd: -------------------------------------------------------------------------------- 1 | extends Panel 2 | 3 | ## Used when dragging the hand of the clock 4 | var dragging = false 5 | 6 | ## Only change hand when mouse is in clock. 7 | ## drag can still change it after has left the clock but it has to start in clock. 8 | ## releasing the mouse outside parent will hide the selection. 9 | var mouse_in_clock=false; 10 | ## Default time when empty 11 | var hour="12"; 12 | ## Used to disable input 13 | var disabled=true 14 | 15 | ## Used for selecting minute (either by click or drag) 16 | ## If mouse clicks outside parent hide 17 | func _input(event): 18 | if(!disabled): 19 | if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT: 20 | if not dragging and event.pressed and (mouse_in_clock and !get_parent().mouse_in): 21 | dragging = true 22 | hour=get_parent().get_closest_label(get_tree().get_nodes_in_group("date-time-hours-popup"),get_global_mouse_position()).text 23 | $Hand.rotation_degrees=30*(int(hour)) 24 | if dragging and not event.pressed: 25 | dragging = false 26 | hide() 27 | get_parent().change_time(hour,"") 28 | if event is InputEventMouseMotion and dragging: 29 | hour=get_parent().get_closest_label(get_tree().get_nodes_in_group("date-time-hours-popup"),get_global_mouse_position()).text 30 | $Hand.rotation_degrees=30*(int(hour)) 31 | 32 | func _on_mouse_entered(): 33 | mouse_in_clock=true 34 | func _on_mouse_exited(): 35 | mouse_in_clock=false 36 | 37 | # enable input when shown and disable input when hidden 38 | func _on_visibility_changed(): 39 | # change hand to selected hour 40 | if(self.visible): 41 | disabled=false 42 | $Hand.rotation_degrees=30*(int(hour)) 43 | # reset mouse 44 | else: 45 | disabled=true 46 | mouse_in_clock=false 47 | -------------------------------------------------------------------------------- /tools/scenes/scripts/ManualTimePanel.gd: -------------------------------------------------------------------------------- 1 | extends Panel 2 | ##Script that handles Manual Clouk functionality 3 | var previous_text = "" 4 | 5 | func _ready(): 6 | get_parent().time_changed.connect(_on_time_changed); 7 | 8 | func _input(event): 9 | if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT: 10 | if not Rect2(Vector2(), size).has_point(get_local_mouse_position()): 11 | if(event.pressed): 12 | hide() 13 | 14 | # Check if format is valid using regex 15 | func _on_time_edit_text_changed(new_text): 16 | var regex = RegEx.new() 17 | regex.compile("^(0?[0-9]|1[0-2])?(:([0-5]?[0-9])?)? ?([AaPp]?[Mm]?)?$"); 18 | var result=regex.search(new_text) 19 | if(result): 20 | var temp_carret = $TimeEdit.caret_column 21 | $TimeEdit.text=result.get_string(); 22 | $TimeEdit.caret_column=temp_carret 23 | 24 | regex.compile('^(\\d{2})$'); 25 | var result2=regex.search(new_text) 26 | if(result2): 27 | if(!previous_text.contains(':')): 28 | $TimeEdit.text=result2.get_string()+":"; 29 | $TimeEdit.set_caret_column($TimeEdit.text.length()) 30 | else: 31 | regex.compile("((1[0-2]|0?[1-9]):([0-5]?[0-9]) ?([AaPp]))") 32 | var result3=regex.search(new_text) 33 | 34 | if(result3): 35 | result = result3.get_string().split(" "); 36 | var ampm=result[1]; 37 | result = result[0].split(":"); 38 | var hour=result[0]; 39 | var minute=result[1]; 40 | if(len(hour)==1): 41 | hour="0"+hour 42 | if(len(minute)==1): 43 | minute="0"+minute; 44 | if(ampm.to_lower() == "a"): 45 | ampm="am"; 46 | if(ampm.to_lower() == "p"): 47 | ampm="pm" 48 | if(hour+":"+minute+" "+ampm != $LayoutTop/Value.text+" "+$LayoutTop/AMPMContainer/AM.button_group.get_pressed_button().name.to_lower()): 49 | get_parent().time_changed.emit(hour+":"+minute,ampm); 50 | else: 51 | $TimeEdit.delete_char_at_caret() 52 | if($TimeEdit.text.length()==0): 53 | $TimeEdit.clear() 54 | previous_text = new_text; 55 | 56 | 57 | # Set cursor at the end of the line //blinking is enabled 58 | func _on_time_edit_focus_entered(): 59 | $TimeEdit.set_caret_column(len($TimeEdit.text)) 60 | 61 | # Change meridian 62 | func _on_AMPM_pressed(a_p): 63 | get_parent().time_changed.emit($LayoutTop/Value.text,a_p) 64 | $TimeEdit.text = $LayoutTop/Value.text+" "+$LayoutTop/AMPMContainer/AM.button_group.get_pressed_button().name.to_lower() 65 | 66 | # Switch popup to clock popup 67 | func _on_ChangeToClock_pressed(): 68 | self.hide() 69 | get_parent().get_node("Clock").show() 70 | get_parent().popup="Clock" 71 | 72 | # Hide when pressing the close button 73 | func _on_close_pressed(): 74 | self.hide() 75 | 76 | # When visible update TimeEdit 77 | func _on_draw(): 78 | $TimeEdit.text = $LayoutTop/Value.text+" "+$LayoutTop/AMPMContainer/AM.button_group.get_pressed_button().name.to_lower() 79 | 80 | # Change time 81 | func _on_time_changed(time,ampm): 82 | $LayoutTop/Value.text = time 83 | get_node("LayoutTop/AMPMContainer/"+ampm.to_upper()).button_pressed=true 84 | -------------------------------------------------------------------------------- /tools/scenes/scripts/MinutesPanel.gd: -------------------------------------------------------------------------------- 1 | extends Panel 2 | 3 | ## Used when dragging the hand of the clock. 4 | var dragging = false 5 | 6 | ## Only change hand when mouse is in clock. 7 | ## drag can still change it after has left the clock but it has to start in clock. 8 | ## releasing the mouse outside parent will hide the selection. 9 | var mouse_in_clock=false; 10 | ## Default time when empty 11 | var minute="00"; 12 | ## Used to disable input 13 | var disabled=true; 14 | 15 | ## Used for selecting minute (either by click or drag) 16 | ## If mouse clicks outside parent hide 17 | func _input(event): 18 | if(!disabled): 19 | if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT: 20 | if not dragging and event.pressed and (mouse_in_clock and !get_parent().mouse_in): 21 | dragging = true 22 | minute=get_parent().get_closest_label(get_tree().get_nodes_in_group("date-time-minutes-popup"),get_global_mouse_position()).text 23 | $Hand.rotation_degrees=6*(int(minute)) 24 | if dragging and not event.pressed: 25 | dragging = false 26 | hide() 27 | get_parent().change_time("",minute) 28 | if event is InputEventMouseMotion and dragging: 29 | minute=get_parent().get_closest_label(get_tree().get_nodes_in_group("date-time-minutes-popup"),get_global_mouse_position()).text 30 | $Hand.rotation_degrees=6*(int(minute)) 31 | 32 | # enable input when shown 33 | func _on_mouse_entered(): 34 | mouse_in_clock=true 35 | 36 | # disable input when hidden 37 | func _on_mouse_exited(): 38 | mouse_in_clock=false 39 | 40 | # enable input when shown and disable input when hidden 41 | func _on_visibility_changed(): 42 | # change hand to selected minute 43 | if(self.visible): 44 | disabled=false 45 | $Hand.rotation_degrees=30*(int(minute)) 46 | # reset mouse 47 | else: 48 | disabled=true 49 | mouse_in_clock=false 50 | -------------------------------------------------------------------------------- /tools/scenes/scripts/TimePanel.gd: -------------------------------------------------------------------------------- 1 | extends Panel 2 | ##Script that handles Clock functionality 3 | 4 | ## Mouse Entered 5 | var mouse_in:bool=false; 6 | 7 | func _ready(): 8 | get_parent().time_changed.connect(_on_time_changed); 9 | 10 | func _input(event): 11 | if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT: 12 | if not Rect2(Vector2(), size).has_point(get_local_mouse_position()): 13 | if(event.pressed): 14 | hide() 15 | 16 | func _on_mouse_entered()->void: 17 | mouse_in=true 18 | func _on_mouse_exited()->void: 19 | mouse_in=false 20 | 21 | # If clock scene resets. Reset children visibility. 22 | func _on_visibility_changed(): 23 | if(self.visible): 24 | $Minutes.hide() 25 | $Hours.show() 26 | # Hide when pressing the close button 27 | func _on_cancel_pressed(): 28 | self.hide(); 29 | mouse_in=false; 30 | 31 | # Change meridian 32 | func _on_AMPM_pressed(a_p:String): 33 | get_parent().time_changed.emit($LayoutTop/Value.text,a_p) 34 | 35 | # Switch popup to manual clock popup 36 | func _on_SwitchToManual_pressed()->void: 37 | hide() 38 | get_parent().get_node("ManualClock").show() 39 | get_parent().popup="ManualClock" 40 | 41 | # Change time 42 | func _on_time_changed(time,ampm)->void: 43 | $LayoutTop/Value.text=time; 44 | time=time.split(":") 45 | $Hours.hour=time[0] 46 | $Minutes.minute=time[1] 47 | 48 | ## Returns the closest label to a Vector2 position 49 | func get_closest_label(group:Array,mouse:Vector2)->Label: 50 | var min_distance=INF; 51 | var label=null; 52 | for l in group: 53 | var distance= (l.global_position+Vector2(17,17)).distance_to(mouse) 54 | if (distance < min_distance): 55 | min_distance=distance 56 | label=l 57 | return label; 58 | 59 | ## Used by children to emit time_changed signal. 60 | func change_time(hour,minute)->void: 61 | if(hour!="" and minute==""): 62 | $Minutes.show() 63 | get_parent().time_changed.emit(hour+":"+$Minutes.minute, $LayoutTop/AMPMContainer/AM.button_group.get_pressed_button().name.to_lower()) 64 | if(hour=="" and minute!=""): 65 | get_parent().time_changed.emit($Hours.hour+":"+minute, $LayoutTop/AMPMContainer/AM.button_group.get_pressed_button().name.to_lower()) 66 | self.hide() 67 | -------------------------------------------------------------------------------- /tools/styles/BigTime.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="DynamicFont" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://addons/date-time-elements/tools/assets/Signika-VariableFont_wght.ttf" type="DynamicFontData" id=1] 4 | 5 | [resource] 6 | size = 48 7 | use_mipmaps = true 8 | use_filter = true 9 | font_data = ExtResource( 1 ) 10 | -------------------------------------------------------------------------------- /tools/styles/default_theme.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Theme" load_steps=7 format=3 uid="uid://bu8lih0b3e64f"] 2 | 3 | [ext_resource type="Texture2D" path="res://addons/date-time-elements/tools/styles/no_radio_image.tres" id="1"] 4 | [ext_resource type="FontFile" uid="uid://du2k7gp5t4sgx" path="res://addons/date-time-elements/tools/assets/Signika-VariableFont_wght.ttf" id="2"] 5 | 6 | [sub_resource type="StyleBoxFlat" id="4"] 7 | bg_color = Color(0.6, 0.6, 0.6, 0) 8 | corner_radius_top_left = 25 9 | corner_radius_top_right = 25 10 | corner_radius_bottom_right = 25 11 | corner_radius_bottom_left = 25 12 | 13 | [sub_resource type="FontFile" id="3"] 14 | fallbacks = Array[Font]([ExtResource("2")]) 15 | cache/0/16/0/ascent = 0.0 16 | cache/0/16/0/descent = 0.0 17 | cache/0/16/0/underline_position = 0.0 18 | cache/0/16/0/underline_thickness = 0.0 19 | cache/0/16/0/scale = 1.0 20 | cache/0/16/0/kerning_overrides/16/0 = Vector2(0, 0) 21 | 22 | [sub_resource type="StyleBoxFlat" id="1"] 23 | bg_color = Color(0.117647, 0.101961, 0.101961, 1) 24 | corner_radius_top_left = 200 25 | corner_radius_top_right = 200 26 | corner_radius_bottom_right = 200 27 | corner_radius_bottom_left = 200 28 | 29 | [sub_resource type="FontFile" id="2"] 30 | fallbacks = Array[Font]([ExtResource("2")]) 31 | cache/0/16/0/ascent = 0.0 32 | cache/0/16/0/descent = 0.0 33 | cache/0/16/0/underline_position = 0.0 34 | cache/0/16/0/underline_thickness = 0.0 35 | cache/0/16/0/scale = 1.0 36 | cache/0/16/0/kerning_overrides/16/0 = Vector2(0, 0) 37 | 38 | [resource] 39 | default_font = SubResource("2") 40 | Button/colors/font_color = Color(0.282353, 0.580392, 0.235294, 1) 41 | Button/colors/font_color_disabled = Color(0.282353, 0.580392, 0.235294, 1) 42 | Button/colors/font_color_focus = Color(0.282353, 0.580392, 0.235294, 1) 43 | Button/colors/font_color_hover = Color(0.282353, 0.580392, 0.235294, 1) 44 | Button/colors/font_color_pressed = Color(0.282353, 0.580392, 0.235294, 1) 45 | Button/styles/disabled = SubResource("4") 46 | Button/styles/focus = SubResource("4") 47 | Button/styles/hover = SubResource("4") 48 | Button/styles/normal = SubResource("4") 49 | Button/styles/pressed = SubResource("4") 50 | CheckBox/colors/font_color = Color(1, 1, 1, 1) 51 | CheckBox/colors/font_color_pressed = Color(0.282353, 0.580392, 0.235294, 1) 52 | CheckBox/icons/checked = ExtResource("1") 53 | CheckBox/icons/checked_disabled = ExtResource("1") 54 | CheckBox/icons/radio_checked = ExtResource("1") 55 | CheckBox/icons/radio_checked_disabled = ExtResource("1") 56 | CheckBox/icons/radio_unchecked = ExtResource("1") 57 | CheckBox/icons/radio_unchecked_disabled = ExtResource("1") 58 | CheckBox/icons/unchecked = ExtResource("1") 59 | CheckBox/icons/unchecked_disabled = ExtResource("1") 60 | Label/colors/font_color = Color(1, 1, 1, 1) 61 | LineEdit/fonts/font = SubResource("3") 62 | Panel/styles/panel = SubResource("1") 63 | PopupDialog/styles/panel = null 64 | VBoxContainer/constants/separation = 10 65 | -------------------------------------------------------------------------------- /tools/styles/highlight_hour_minute.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="StyleBoxFlat" format=2] 2 | 3 | [resource] 4 | bg_color = Color( 0.282353, 0.580392, 0.235294, 1 ) 5 | corner_radius_top_left = 25 6 | corner_radius_top_right = 25 7 | corner_radius_bottom_right = 25 8 | corner_radius_bottom_left = 25 9 | anti_aliasing = false 10 | -------------------------------------------------------------------------------- /tools/styles/hover_tick_highlight.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="StyleBoxFlat" format=2] 2 | 3 | [resource] 4 | bg_color = Color( 0.117647, 0.101961, 0.101961, 1 ) 5 | corner_radius_top_left = 50 6 | corner_radius_top_right = 50 7 | corner_radius_bottom_right = 50 8 | corner_radius_bottom_left = 50 9 | -------------------------------------------------------------------------------- /tools/styles/no_radio_image.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="ImageTexture" format=2] 2 | 3 | [resource] 4 | -------------------------------------------------------------------------------- /tools/styles/tick_unhighlight.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="StyleBoxFlat" format=2] 2 | 3 | [resource] 4 | bg_color = Color( 0.6, 0.6, 0.6, 0 ) 5 | -------------------------------------------------------------------------------- /tools/styles/unhighlight_hour_minute.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="StyleBoxFlat" format=2] 2 | 3 | [resource] 4 | bg_color = Color( 0.6, 0.6, 0.6, 0 ) 5 | corner_radius_top_left = 25 6 | corner_radius_top_right = 25 7 | corner_radius_bottom_right = 25 8 | corner_radius_bottom_left = 25 9 | --------------------------------------------------------------------------------