Finalising app functions for alpha release

This commit is contained in:
Jaap Marsman 2022-11-04 21:14:09 +08:00
parent 416f9c232f
commit da1cca70e0
9 changed files with 294 additions and 94 deletions

View File

@ -14,6 +14,10 @@ The above copyright notice and this permission notice shall be included in all c
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.
## Web Export (for Results)
Uses code from the [HTML5-File-Exchange-for-Godot project](https://github.com/Pukkah/HTML5-File-Exchange-for-Godot).
## Fonts
Portions of this software are copyright © 2022 The FreeType Project (www.freetype.org). All rights reserved.

View File

@ -0,0 +1,80 @@
extends Node
signal read_completed
signal load_completed(image)
var js_callback = JavaScript.create_callback(self, "load_handler");
var js_interface;
func _ready():
if OS.get_name() == "HTML5" and OS.has_feature('JavaScript'):
_define_js()
js_interface = JavaScript.get_interface("_HTML5FileExchange");
func _define_js()->void:
#Define JS script
JavaScript.eval("""
var _HTML5FileExchange = {};
_HTML5FileExchange.upload = function(gd_callback) {
canceled = true;
var input = document.createElement('INPUT');
input.setAttribute("type", "file");
input.setAttribute("accept", "image/png, image/jpeg, image/webp");
input.click();
input.addEventListener('change', event => {
if (event.target.files.length > 0){
canceled = false;}
var file = event.target.files[0];
var reader = new FileReader();
this.fileType = file.type;
// var fileName = file.name;
reader.readAsArrayBuffer(file);
reader.onloadend = (evt) => { // Since here's it's arrow function, "this" still refers to _HTML5FileExchange
if (evt.target.readyState == FileReader.DONE) {
this.result = evt.target.result;
gd_callback(); // It's hard to retrieve value from callback argument, so it's just for notification
}
}
});
}
""", true)
func load_handler(_args):
emit_signal("read_completed")
func load_image():
if OS.get_name() != "HTML5" or !OS.has_feature('JavaScript'):
return
js_interface.upload(js_callback);
yield(self, "read_completed")
var imageType = js_interface.fileType;
var imageData = JavaScript.eval("_HTML5FileExchange.result", true) # interface doesn't work as expected for some reason
var image = Image.new()
var image_error
match imageType:
"image/png":
image_error = image.load_png_from_buffer(imageData)
"image/jpeg":
image_error = image.load_jpg_from_buffer(imageData)
"image/webp":
image_error = image.load_webp_from_buffer(imageData)
var invalidType:
print("Unsupported file format - %s." % invalidType)
return
if image_error:
print("An error occurred while trying to display the image.")
emit_signal("load_completed", image)
func save_image(image:Image, fileName:String = "export.png")->void:
if OS.get_name() != "HTML5" or !OS.has_feature('JavaScript'):
return
image.clear_mipmaps()
var buffer = image.save_png_to_buffer()
JavaScript.download_buffer(buffer, fileName)

View File

@ -0,0 +1,15 @@
[plugin]
name="HTML5 File Exchange"
description="Open/Import and Save/Export files in HTML5 environment.
Supported input - *.png, *.jpeg, *.webp
Supported output - *.png
Usage:
Get file from User -
var image:Image = yield(HTML5File.get_image(), \"completed\")
Send file to User -
HTML5File.save_image(image:Image, fileName:String = \"export\")"
author="laame"
version="0.1.1"
script="plugin.gd"

View File

@ -0,0 +1,10 @@
tool
extends EditorPlugin
func _enter_tree():
add_autoload_singleton("HTML5File", "res://addons/HTML5FileExchange/HTML5FileExchange.gd")
func _exit_tree():
remove_autoload_singleton("HTML5File")

View File

@ -7,15 +7,29 @@ onready var global_ints = $"/root/GlobalInts"
func _ready():
pass
func Download_File(_img,_filename):
var buf = _img.save_png_to_buffer()
JavaScript.download_buffer(buf,_filename+".png")
func _process(delta):
# $"%SaveReport".visible = true
# $"%BackMainMenu".visible = true
pass
func _on_SaveReport_pressed():
# Download_File(results, results)
pass
$"%SaveReport".visible = false
$"%BackMainMenu".visible = false
# WIP: Web Version
# var file = File.new()
# file.open("res://screenshot.png", File.READ)
# var base_64_data = Marshalls.raw_to_base64(file.get_buffer(file.get_len()))
# var url = "data:image/jpg;base64,"+base_64_data
# var comand = "var a = document.createElement('a'); a.href = '" + url + "'; a.setAttribute( 'download' , 'filename.jpg' ); a.click();"
# JavaScript.eval(comand, true)
# WIP: Non-Web Version
var image = get_viewport().get_texture().get_data()
image.flip_y()
image.save_png("user://results.png")
func _on_BackMainMenu_pressed():

View File

@ -1,13 +1,11 @@
extends Node
# For testing purposes - make the intervals 4 seconds instead of 20
var date
var ddmmyyyy
var total_observed_time : int
var timer_duration : int = 20
var timer_duration : int = 6
var observation_minutes : int = 1
@ -61,7 +59,7 @@ var four_behaviour_percent : int
var five_behaviour_percent : int
func reset_all_vars():
observation_minutes = 1
observation_minutes = 15
generate_results = false

View File

@ -49,6 +49,7 @@ func _ready():
refresh_descriptors()
$"StartScreen".visible = true
$"%NameChangePanel".visible = true
$"%InstructionScreen".visible = true
$"%WarningLabel".visible = false
$"ObservationWindow".visible = false
$"Results".visible = false
@ -70,29 +71,29 @@ func _process(_delta):
date_time_display.text = str(date_time.hour, ":", date_time.minute)
func _on_MinuteMinus_pressed() -> void:
func _on_MinuteMinus_pressed():
if global_ints.observation_minutes >= 2:
global_ints.observation_minutes -= 1
minute_label.text = str(global_ints.observation_minutes)
func _on_MinutePlus_pressed() -> void:
func _on_MinutePlus_pressed():
if global_ints.observation_minutes < 60:
global_ints.observation_minutes += 1
minute_label.text = str(global_ints.observation_minutes)
func _on_Manual_pressed() -> void:
func _on_Manual_pressed():
var _error = OS.shell_open("https://www.internationalsengroup.org/resources/time-sampling-form/")
func _on_PupilName_pressed() -> void:
func _on_PupilName_pressed():
$"%NameLine".text = global_ints.observed_person_name
$"%InstructionPanel".visible = false
$"%NameChangePanel".visible = true
func _on_Start_pressed() -> void:
func _on_Start_pressed():
$"StartScreen".visible = false
refresh_descriptors()
$"ObservationWindow".visible = true
@ -130,3 +131,14 @@ func _on_Start_pressed() -> void:
func _on_ChangeItems_pressed():
$"EditScreen".visible = true
func _on_InsOkButton_pressed():
$"%InstructionScreen".visible = false
func _on_MinuteMinus_button_down():
# if global_ints.observation_minutes >= 2:
# global_ints.observation_minutes -= 1
# minute_label.text = str(global_ints.observation_minutes)
pass

View File

@ -75,7 +75,6 @@ __meta__ = {
}
[node name="StartScreen" type="CanvasLayer" parent="."]
visible = false
[node name="InstructionPanel" type="Panel" parent="StartScreen"]
unique_name_in_owner = true
@ -136,10 +135,10 @@ __meta__ = {
[node name="CurrentTime" type="Label" parent="StartScreen/InstructionPanel"]
unique_name_in_owner = true
margin_left = 1200.0
margin_top = 510.0
margin_right = 1279.0
margin_bottom = 533.0
margin_left = 1196.0
margin_top = 506.0
margin_right = 1275.0
margin_bottom = 529.0
custom_colors/font_color = Color( 0, 0, 0, 1 )
custom_fonts/font = SubResource( 4 )
text = "99:99"
@ -155,7 +154,7 @@ margin_top = -197.0
margin_right = 322.5
margin_bottom = -163.0
theme = ExtResource( 1 )
text = "How long will you observe? (in minutes)"
text = "How long will you observe for? (in minutes)"
align = 1
[node name="ObservationItemsTitle" type="Label" parent="StartScreen/InstructionPanel"]
@ -473,7 +472,7 @@ unique_name_in_owner = true
margin_right = 539.0
margin_bottom = 34.0
theme = ExtResource( 1 )
text = "Observed Individual First Name:"
text = "Who are you observing? (First name)"
[node name="WarningLabel" type="Label" parent="StartScreen/NameChangePanel/NameContainer"]
unique_name_in_owner = true
@ -496,7 +495,7 @@ margin_top = 114.0
margin_right = 539.0
margin_bottom = 148.0
theme = ExtResource( 1 )
text = "Your Full Name:"
text = "What is your name?"
[node name="ObserverLine" type="LineEdit" parent="StartScreen/NameChangePanel/NameContainer"]
unique_name_in_owner = true
@ -511,7 +510,7 @@ margin_top = 190.0
margin_right = 539.0
margin_bottom = 224.0
theme = ExtResource( 1 )
text = "Observed during which Activity/Lesson:"
text = "What Activity/Lesson are you observing?"
[node name="ObservedActivity" type="LineEdit" parent="StartScreen/NameChangePanel/NameContainer"]
unique_name_in_owner = true
@ -527,6 +526,50 @@ margin_bottom = 300.0
theme = ExtResource( 1 )
text = "OK"
[node name="InstructionScreen" type="Panel" parent="StartScreen"]
unique_name_in_owner = true
visible = false
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -640.0
margin_top = -254.0
margin_right = 640.0
margin_bottom = 359.0
custom_styles/panel = SubResource( 1 )
script = ExtResource( 4 )
[node name="InstructionContainer" type="VBoxContainer" parent="StartScreen/InstructionScreen"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -385.0
margin_top = -258.0
margin_right = 385.0
margin_bottom = 258.0
[node name="Instructions" type="Label" parent="StartScreen/InstructionScreen/InstructionContainer"]
margin_right = 770.0
margin_bottom = 478.0
theme = ExtResource( 1 )
text = "The Time Sampling Form is a guided observation tool. You set the length of your observation in minutes.
Every 20 seconds you will click the button that corresponds with the behaviour you see at that time. The buttons to select the observed behaviour will be visible in the final 5 seconds of each 20 second interval.
Use the \"Manual\" button on the main screen to read more about this tool and possible use cases.
For first time users: It is recommended to do a one minute trial to gain an understanding of the system. I hope you find this tool useful!"
autowrap = true
[node name="InsOkButton" type="Button" parent="StartScreen/InstructionScreen/InstructionContainer"]
margin_top = 482.0
margin_right = 770.0
margin_bottom = 516.0
theme = ExtResource( 1 )
text = "OK"
[node name="EditScreen" type="CanvasLayer" parent="."]
unique_name_in_owner = true
visible = false
@ -779,6 +822,7 @@ margin_bottom = 649.0
text = "Clear All"
[node name="ObservationWindow" type="CanvasLayer" parent="."]
visible = false
script = ExtResource( 7 )
[node name="Panel" type="Panel" parent="ObservationWindow"]
@ -788,6 +832,9 @@ margin_top = 188.0
margin_bottom = 1.0
theme = ExtResource( 1 )
custom_styles/panel = SubResource( 7 )
__meta__ = {
"_edit_lock_": true
}
[node name="BehaviourButtons" type="HBoxContainer" parent="ObservationWindow/Panel"]
anchor_left = 0.5
@ -910,10 +957,14 @@ theme = ExtResource( 1 )
text = "Seconds remaining"
[node name="Button" type="Button" parent="ObservationWindow/Panel"]
margin_left = 582.0
margin_top = 13.0
margin_right = 700.0
margin_bottom = 47.0
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -74.5
margin_top = -231.5
margin_right = 74.5
margin_bottom = -191.5
text = "Stop Early"
[node name="TimerBar" type="ProgressBar" parent="ObservationWindow/Panel"]
@ -998,6 +1049,7 @@ unique_name_in_owner = true
wait_time = 20.0
[node name="Results" type="CanvasLayer" parent="."]
visible = false
script = ExtResource( 9 )
[node name="Panel" type="Panel" parent="Results"]
@ -1006,19 +1058,24 @@ anchor_bottom = 1.0
margin_top = -3.0
theme = ExtResource( 1 )
custom_styles/panel = SubResource( 8 )
__meta__ = {
"_edit_lock_": true
}
[node name="SaveReport" type="Button" parent="Results/Panel"]
margin_left = 1042.0
margin_top = 683.0
margin_right = 1271.0
margin_bottom = 717.0
unique_name_in_owner = true
margin_left = 1011.0
margin_top = 675.0
margin_right = 1270.0
margin_bottom = 715.0
text = "Save Report as PNG"
[node name="BackMainMenu" type="Button" parent="Results/Panel"]
unique_name_in_owner = true
margin_left = 11.0
margin_top = 676.0
margin_top = 675.0
margin_right = 155.0
margin_bottom = 710.0
margin_bottom = 715.0
text = "Restart"
[node name="FullResult" type="Label" parent="Results/Panel"]
@ -1032,106 +1089,110 @@ text = "Can this be multi-line?
Or does text-wrap work?
Can I get integers in? Must be able to, concatenate."
autowrap = true
__meta__ = {
"_edit_lock_": true
}
[node name="ObsBar1" type="ProgressBar" parent="Results/Panel"]
unique_name_in_owner = true
margin_left = 271.0
margin_left = 348.0
margin_top = 422.0
margin_right = 1063.0
margin_right = 1140.0
margin_bottom = 447.0
size_flags_horizontal = 3
step = 1.0
percent_visible = false
[node name="ObsBar2" type="ProgressBar" parent="Results/Panel"]
unique_name_in_owner = true
margin_left = 348.0
margin_top = 452.0
margin_right = 1140.0
margin_bottom = 477.0
size_flags_horizontal = 3
step = 1.0
percent_visible = false
[node name="ObsBar3" type="ProgressBar" parent="Results/Panel"]
unique_name_in_owner = true
margin_left = 348.0
margin_top = 482.0
margin_right = 1140.0
margin_bottom = 507.0
size_flags_horizontal = 3
step = 1.0
percent_visible = false
[node name="ObsBar4" type="ProgressBar" parent="Results/Panel"]
unique_name_in_owner = true
margin_left = 348.0
margin_top = 512.0
margin_right = 1140.0
margin_bottom = 537.0
size_flags_horizontal = 3
step = 1.0
percent_visible = false
[node name="ObsBar5" type="ProgressBar" parent="Results/Panel"]
unique_name_in_owner = true
margin_left = 348.0
margin_top = 542.0
margin_right = 1140.0
margin_bottom = 567.0
size_flags_horizontal = 3
step = 1.0
percent_visible = false
[node name="GridContainer" type="GridContainer" parent="Results/Panel"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -423.0
margin_left = -517.0
margin_top = 60.5
margin_right = 423.0
margin_bottom = 181.5
columns = 2
margin_right = -302.0
margin_bottom = 206.5
[node name="ObsTitle1" type="Label" parent="Results/Panel/GridContainer"]
unique_name_in_owner = true
margin_right = 792.0
margin_right = 50.0
margin_bottom = 26.0
custom_fonts/font = SubResource( 12 )
text = "Item1"
[node name="ObsTitle2" type="Label" parent="Results/Panel/GridContainer"]
unique_name_in_owner = true
margin_left = 796.0
margin_right = 846.0
margin_bottom = 26.0
margin_top = 30.0
margin_right = 50.0
margin_bottom = 56.0
custom_fonts/font = SubResource( 12 )
text = "Item2"
[node name="ObsBar2" type="ProgressBar" parent="Results/Panel/GridContainer"]
unique_name_in_owner = true
margin_top = 30.0
margin_right = 792.0
margin_bottom = 31.0
size_flags_horizontal = 3
step = 1.0
percent_visible = false
[node name="ObsTitle3" type="Label" parent="Results/Panel/GridContainer"]
unique_name_in_owner = true
margin_left = 796.0
margin_top = 30.0
margin_right = 846.0
margin_bottom = 56.0
margin_top = 60.0
margin_right = 50.0
margin_bottom = 86.0
custom_fonts/font = SubResource( 12 )
text = "Item3"
[node name="ObsBar3" type="ProgressBar" parent="Results/Panel/GridContainer"]
unique_name_in_owner = true
margin_top = 60.0
margin_right = 792.0
margin_bottom = 61.0
size_flags_horizontal = 3
step = 1.0
percent_visible = false
[node name="ObsTitle4" type="Label" parent="Results/Panel/GridContainer"]
unique_name_in_owner = true
margin_left = 796.0
margin_top = 60.0
margin_right = 846.0
margin_bottom = 86.0
margin_top = 90.0
margin_right = 50.0
margin_bottom = 116.0
custom_fonts/font = SubResource( 12 )
text = "Item4"
[node name="ObsBar4" type="ProgressBar" parent="Results/Panel/GridContainer"]
unique_name_in_owner = true
margin_top = 90.0
margin_right = 792.0
margin_bottom = 91.0
size_flags_horizontal = 3
step = 1.0
percent_visible = false
[node name="ObsTitle5" type="Label" parent="Results/Panel/GridContainer"]
unique_name_in_owner = true
margin_left = 796.0
margin_top = 90.0
margin_right = 846.0
margin_bottom = 116.0
margin_top = 120.0
margin_right = 50.0
margin_bottom = 146.0
custom_fonts/font = SubResource( 12 )
text = "Item5"
[node name="ObsBar5" type="ProgressBar" parent="Results/Panel/GridContainer"]
unique_name_in_owner = true
margin_top = 120.0
margin_right = 792.0
margin_bottom = 121.0
size_flags_horizontal = 3
step = 1.0
percent_visible = false
[connection signal="button_down" from="StartScreen/InstructionPanel/MinuteBox/MinuteMinus" to="." method="_on_MinuteMinus_button_down"]
[connection signal="pressed" from="StartScreen/InstructionPanel/MinuteBox/MinuteMinus" to="." method="_on_MinuteMinus_pressed"]
[connection signal="pressed" from="StartScreen/InstructionPanel/MinuteBox/MinutePlus" to="." method="_on_MinutePlus_pressed"]
[connection signal="pressed" from="StartScreen/InstructionPanel/BottomButtons/Manual" to="." method="_on_Manual_pressed"]
@ -1139,6 +1200,7 @@ percent_visible = false
[connection signal="pressed" from="StartScreen/InstructionPanel/BottomButtons/PupilName" to="." method="_on_PupilName_pressed"]
[connection signal="pressed" from="StartScreen/InstructionPanel/BottomButtons/Start" to="." method="_on_Start_pressed"]
[connection signal="pressed" from="StartScreen/NameChangePanel/NameContainer/OkButton" to="StartScreen/NameChangePanel" method="_on_OkButton_pressed"]
[connection signal="pressed" from="StartScreen/InstructionScreen/InstructionContainer/InsOkButton" to="." method="_on_InsOkButton_pressed"]
[connection signal="pressed" from="EditScreen/Panel/CancelButton" to="EditScreen" method="_on_CancelButton_pressed"]
[connection signal="pressed" from="EditScreen/Panel/OKButton" to="EditScreen" method="_on_OKButton_pressed"]
[connection signal="pressed" from="EditScreen/Panel/ClearAll" to="EditScreen" method="_on_ClearAll_pressed"]

View File

@ -19,6 +19,7 @@ config/macos_native_icon="res://Assets/icons/main_icon.icns"
[autoload]
GlobalInts="*res://global_ints.gd"
HTML5File="*res://addons/HTML5FileExchange/HTML5FileExchange.gd"
[display]
@ -27,6 +28,10 @@ window/size/height=720
window/stretch/mode="2d"
window/stretch/aspect="keep"
[editor_plugins]
enabled=PoolStringArray( "res://addons/HTML5FileExchange/plugin.cfg" )
[gui]
common/drop_mouse_on_gui_input_disabled=true