moved to Gitea
@ -1,49 +0,0 @@
|
||||
# Copyrights
|
||||
|
||||
This document attributes the different components used to build the Time Sampling Form application (c) 2022 Jaap Marsman.
|
||||
|
||||
## The engine: Godot
|
||||
|
||||
This app uses Godot Engine, available under the following license:
|
||||
|
||||
Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. Copyright (c) 2014-2022 Godot Engine contributors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
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.
|
||||
|
||||
The app uses the Noto Sans font family, for which <a href="https://github.com/notofonts/noto-fonts/blob/main/LICENSE" target="_blank">the full Open Font License is available here</a>.
|
||||
|
||||
## Internet module Mbed TLS (as part of Godot)
|
||||
|
||||
Copyright The Mbed TLS Contributors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
## Multiplayer module ENET (as part of Godot)
|
||||
|
||||
Copyright (c) 2002-2020 Lee Salzman
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
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.
|
||||
|
||||
## Attributions for art
|
||||
|
||||
The classroom photograph used in the app is a no-attribution-required photograph from Pixabay, under the Pixabay License. The original link to the photograph is [here](https://pixabay.com/photos/classroom-chairs-tables-school-824120/).
|
@ -1 +0,0 @@
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank"><img alt="Creative Commons Licence" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank">Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License</a>.
|
16
README.md
@ -1,17 +1,3 @@
|
||||
<p align="center">
|
||||
<img src="./design_files/main_icon_small.png" width="200" height="200">
|
||||
</p>
|
||||
|
||||
# Time Sampling Form
|
||||
|
||||
A freeware and open source SEN-related observation tool. The <a href="https://www.internationalsengroup.org/tsf_web/" target="_blank">web version is available here</a> (now works on iPads too).
|
||||
|
||||
## Manual
|
||||
|
||||
For a detailed manual on how to use the Time Sampling Form, please go to <a href="https://www.internationalsengroup.org/resources/time-sampling-form/" target="_blank">this page on the ISENG website</a>.
|
||||
|
||||
## License & Attributions
|
||||
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank"><img alt="Creative Commons Licence" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank">Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License</a>.
|
||||
|
||||
For an overview of all underlying licences, copyrights and attributions, please see the [Copyrights document](COPYRIGHTS.md).
|
||||
I have moved all code and future development to my self-hosted Gitea: [click here to view this repo there](https://gitea.defiantjc.synology.me/jaap/time-sampling-form).
|
Before Width: | Height: | Size: 505 B |
Before Width: | Height: | Size: 256 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 306 KiB |
Before Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 256 KiB |
Before Width: | Height: | Size: 306 KiB |
Before Width: | Height: | Size: 314 KiB |
@ -1,6 +0,0 @@
|
||||
Date: xx-xx-xxxx
|
||||
Time: X to X
|
||||
|
||||
This Time Sampling Form (TSF) observation was completed by %T. %S was observed for %time minutes during %AL.
|
||||
|
||||
During the observation, OBS1 was observed x out of x times, resulting in xx%. OBS2 was observed x out of x times, resulting in xx%. OBS3 was observed x out of x times, resulting in xx%. OBS4 was observed x out of x times, resulting in xx%. OBS5 was observed x out of x times, resulting in xx%.
|
@ -1,60 +0,0 @@
|
||||
extends CanvasLayer
|
||||
|
||||
onready var gi = $"/root/GlobalInts"
|
||||
onready var global_ints = gi
|
||||
onready var main_window = $"../../AppWindow"
|
||||
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
func _on_CancelButton_pressed():
|
||||
main_window.refresh_descriptors()
|
||||
$"%EditScreen".visible = false
|
||||
|
||||
|
||||
func _on_OKButton_pressed():
|
||||
|
||||
global_ints.one_acronym = $"%1AcronymE".text
|
||||
global_ints.two_acronym = $"%2AcronymE".text
|
||||
global_ints.three_acronym = $"%3AcronymE".text
|
||||
global_ints.four_acronym = $"%4AcronymE".text
|
||||
global_ints.five_acronym = $"%5AcronymE".text
|
||||
|
||||
global_ints.one_behaviour = $"%1ItemE".text
|
||||
global_ints.two_behaviour = $"%2ItemE".text
|
||||
global_ints.three_behaviour = $"%3ItemE".text
|
||||
global_ints.four_behaviour = $"%4ItemE".text
|
||||
global_ints.five_behaviour = $"%5ItemE".text
|
||||
|
||||
global_ints.one_explanation = $"%1ExplanationE".text
|
||||
global_ints.two_explanation = $"%2ExplanationE".text
|
||||
global_ints.three_explanation = $"%3ExplanationE".text
|
||||
global_ints.four_explanation = $"%4ExplanationE".text
|
||||
global_ints.five_explanation = $"%5ExplanationE".text
|
||||
|
||||
$"%EditScreen".visible = false
|
||||
|
||||
main_window.refresh_descriptors()
|
||||
|
||||
|
||||
func _on_ClearAll_pressed():
|
||||
$"%1AcronymE".text = ""
|
||||
$"%1ItemE".text = ""
|
||||
$"%1ExplanationE".text = ""
|
||||
|
||||
$"%2AcronymE".text = ""
|
||||
$"%2ItemE".text = ""
|
||||
$"%2ExplanationE".text = ""
|
||||
|
||||
$"%3AcronymE".text = ""
|
||||
$"%3ItemE".text = ""
|
||||
$"%3ExplanationE".text = ""
|
||||
|
||||
$"%4AcronymE".text = ""
|
||||
$"%4ItemE".text = ""
|
||||
$"%4ExplanationE".text = ""
|
||||
|
||||
$"%5AcronymE".text = ""
|
||||
$"%5ItemE".text = ""
|
||||
$"%5ExplanationE".text = ""
|
@ -1,16 +0,0 @@
|
||||
extends Panel
|
||||
|
||||
|
||||
onready var global_ints = $"/root/GlobalInts"
|
||||
|
||||
|
||||
func _on_OkButton_pressed():
|
||||
if $"%NameLine".text and $"NameContainer/ObserverLine".text and $"NameContainer/ObservedActivity".text != "":
|
||||
$"%InstructionPanel".visible = true
|
||||
$"%NameChangePanel".visible = false
|
||||
global_ints.observed_person_name = $"%NameLine".text
|
||||
global_ints.observer_person_name = $"NameContainer/ObserverLine".text
|
||||
global_ints.observed_activity = $"NameContainer/ObservedActivity".text
|
||||
else:
|
||||
$"%ObservedNameLabel".visible = false
|
||||
$"%WarningLabel".visible = true
|
@ -1,133 +0,0 @@
|
||||
extends CanvasLayer
|
||||
|
||||
|
||||
onready var global_ints = $"/root/GlobalInts"
|
||||
|
||||
|
||||
var time_lefts : int
|
||||
var toggle_observation : bool = false
|
||||
var observation_button_pressed : bool = false
|
||||
|
||||
|
||||
func _ready():
|
||||
$"Panel/BehaviourButtons".visible = false
|
||||
pass
|
||||
|
||||
|
||||
func _process(_delta):
|
||||
time_lefts = $"TwentySecondTimer".time_left
|
||||
$"Panel/TimeRemaining".text = str(time_lefts)
|
||||
if time_lefts == 5 && toggle_observation == false:
|
||||
print("We're at the five second mark!")
|
||||
toggle_observation = true
|
||||
$"Panel/BehaviourButtons".visible = true
|
||||
|
||||
|
||||
func calculate_percentages():
|
||||
global_ints.total_observed_time = global_ints.total_behaviours / 3
|
||||
|
||||
global_ints.one_behaviour_percent = int((float(global_ints.one_behaviour_score) / global_ints.total_behaviours) * 100)
|
||||
|
||||
global_ints.two_behaviour_percent = int((float(global_ints.two_behaviour_score) / global_ints.total_behaviours) * 100)
|
||||
|
||||
global_ints.three_behaviour_percent = int((float(global_ints.three_behaviour_score) / global_ints.total_behaviours) * 100)
|
||||
|
||||
global_ints.four_behaviour_percent = int((float(global_ints.four_behaviour_score) / global_ints.total_behaviours) * 100)
|
||||
|
||||
global_ints.five_behaviour_percent = int((float(global_ints.five_behaviour_score) / global_ints.total_behaviours) * 100)
|
||||
|
||||
func on_interval_moment():
|
||||
print("Timer reaches 0 - Let's check if buttons have been pressed and count something")
|
||||
toggle_observation = false
|
||||
# Otherwise - a 6 is registered (nothing selected)
|
||||
# Buttons are to become visible again
|
||||
global_ints.locked_observations_intervals_remaining -= 1
|
||||
global_ints.locked_observations_completed += 1
|
||||
$"Panel/BehaviourButtons".visible = false
|
||||
|
||||
if observation_button_pressed == false:
|
||||
global_ints.six_behaviour_score += 1
|
||||
global_ints.total_behaviours += 1
|
||||
|
||||
observation_button_pressed = false
|
||||
|
||||
# The thing below here should become a graphic bar as well
|
||||
$"Panel/DescriptorBox/ObservationsRemaining".text = str(global_ints.locked_observations_intervals_remaining)
|
||||
|
||||
|
||||
func _on_TwentySecondTimer_timeout():
|
||||
if global_ints.locked_observations_intervals_remaining == 1:
|
||||
on_interval_moment()
|
||||
print("We're completely done - no intervals remain")
|
||||
# So I should end the observation and move to the Results window.
|
||||
|
||||
var obs_date_time = OS.get_time()
|
||||
if obs_date_time.minute < 10:
|
||||
global_ints.observation_end_time = str(obs_date_time.hour, ":0", obs_date_time.minute)
|
||||
if obs_date_time.minute >= 10:
|
||||
global_ints.observation_end_time = str(obs_date_time.hour, ":", obs_date_time.minute)
|
||||
|
||||
|
||||
$"TwentySecondTimer".stop()
|
||||
global_ints.generate_results = true
|
||||
calculate_percentages()
|
||||
$"../Results".visible = true
|
||||
|
||||
if global_ints.locked_observations_intervals_remaining > 1:
|
||||
on_interval_moment()
|
||||
|
||||
|
||||
func _on_BehaviourOne_pressed():
|
||||
global_ints.one_behaviour_score += 1
|
||||
global_ints.total_behaviours += 1
|
||||
observation_button_pressed = true
|
||||
$"Panel/BehaviourButtons".visible = false
|
||||
print(str(global_ints.one_behaviour_score))
|
||||
|
||||
|
||||
func _on_BehaviourTwo_pressed():
|
||||
global_ints.two_behaviour_score += 1
|
||||
global_ints.total_behaviours += 1
|
||||
observation_button_pressed = true
|
||||
$"Panel/BehaviourButtons".visible = false
|
||||
|
||||
|
||||
func _on_BehaviourThree_pressed():
|
||||
global_ints.three_behaviour_score += 1
|
||||
global_ints.total_behaviours += 1
|
||||
observation_button_pressed = true
|
||||
$"Panel/BehaviourButtons".visible = false
|
||||
|
||||
|
||||
func _on_BehaviourFour_pressed():
|
||||
global_ints.four_behaviour_score += 1
|
||||
global_ints.total_behaviours += 1
|
||||
observation_button_pressed = true
|
||||
$"Panel/BehaviourButtons".visible = false
|
||||
|
||||
|
||||
func _on_BehaviourFive_pressed():
|
||||
global_ints.five_behaviour_score += 1
|
||||
global_ints.total_behaviours += 1
|
||||
observation_button_pressed = true
|
||||
$"Panel/BehaviourButtons".visible = false
|
||||
|
||||
|
||||
func _on_Button_pressed():
|
||||
on_interval_moment()
|
||||
print("We're aborting, so deal with as completely done - no intervals remain")
|
||||
|
||||
# This to set the original total count to what's actually been completed
|
||||
global_ints.locked_observation_intervals = global_ints.locked_observations_completed
|
||||
# So I should end the observation and move to the Results window.
|
||||
|
||||
var obs_date_time = OS.get_time()
|
||||
if obs_date_time.minute < 10:
|
||||
global_ints.observation_end_time = str(obs_date_time.hour, ":0", obs_date_time.minute)
|
||||
if obs_date_time.minute >= 10:
|
||||
global_ints.observation_end_time = str(obs_date_time.hour, ":", obs_date_time.minute)
|
||||
|
||||
$"TwentySecondTimer".stop()
|
||||
global_ints.generate_results = true
|
||||
calculate_percentages()
|
||||
$"../Results".visible = true
|
@ -1,13 +0,0 @@
|
||||
extends ProgressBar
|
||||
|
||||
|
||||
onready var global_ints = $"/root/GlobalInts"
|
||||
|
||||
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
func _process(_delta):
|
||||
value = global_ints.locked_observations_intervals_remaining
|
||||
max_value = global_ints.locked_observation_intervals
|
118
godot/Results.gd
@ -1,118 +0,0 @@
|
||||
extends CanvasLayer
|
||||
|
||||
|
||||
onready var global_ints = $"/root/GlobalInts"
|
||||
|
||||
var js_callback = JavaScript.create_callback(self, "load_handler");
|
||||
var js_interface;
|
||||
var image : Image
|
||||
var fileName : String = "results.png"
|
||||
|
||||
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 _process(_delta):
|
||||
# $"%SaveReport".visible = true
|
||||
# $"%BackMainMenu".visible = true
|
||||
pass
|
||||
|
||||
func _on_SaveReport_pressed():
|
||||
$"%SaveReport".visible = false
|
||||
$"%BackMainMenu".visible = false
|
||||
|
||||
print("I've disabled the buttons")
|
||||
print("That means the screenshot SHOULD be button free")
|
||||
|
||||
image = get_viewport().get_texture().get_data()
|
||||
image.flip_y()
|
||||
|
||||
if OS.get_name() == "HTML5" or OS.has_feature('JavaScript'):
|
||||
# We're on the web
|
||||
print("We're on the web")
|
||||
|
||||
image.clear_mipmaps()
|
||||
var buffer = image.save_png_to_buffer()
|
||||
JavaScript.download_buffer(buffer, fileName)
|
||||
|
||||
if OS.get_name() != "HTML5" or !OS.has_feature('JavaScript'):
|
||||
# We're not on the web
|
||||
print("We're not on the web")
|
||||
|
||||
var docs = OS.get_environment("HOME") + "/Documents"
|
||||
|
||||
var title = str(docs + "/results",global_ints.observed_person_name, global_ints.observation_minutes,".png")
|
||||
|
||||
print(title)
|
||||
|
||||
var _saveimage = image.save_png(title)
|
||||
|
||||
if OS.get_name() != "OSX":
|
||||
print("We're not on MacOS")
|
||||
var _openfolder = OS.shell_open(docs)
|
||||
|
||||
if OS.get_name() == "OSX":
|
||||
print("We're on MacOS")
|
||||
|
||||
var _openfolder = OS.shell_open("file://" + docs)
|
||||
|
||||
$"%SaveReport".visible = true
|
||||
$"%BackMainMenu".visible = true
|
||||
|
||||
func _on_BackMainMenu_pressed():
|
||||
global_ints.reset_all_vars()
|
||||
var _ignore = get_tree().reload_current_scene()
|
||||
|
||||
|
||||
func _on_Results_visibility_changed():
|
||||
if global_ints.generate_results == true:
|
||||
global_ints.generate_results = false
|
||||
|
||||
var result_text : String
|
||||
|
||||
result_text = str("Date: " , global_ints.ddmmyyyy , "\nTime: ", global_ints.observation_start_time , " to " , global_ints.observation_end_time , "\n \nThis Time Sampling Form (TSF) observation was completed by " , global_ints.observer_person_name , ". " , global_ints.observed_person_name , " was observed for " , global_ints.total_observed_time , " minute(s) during " , global_ints.observed_activity , ". \n \nDuring the observation, The ", global_ints.one_behaviour," behaviour was observed ", global_ints.one_behaviour_score, " out of ",global_ints.total_behaviours," times, resulting in ",global_ints.one_behaviour_percent,"%. The ",global_ints.two_behaviour," behaviour was observed ",global_ints.two_behaviour_score," out of ",global_ints.total_behaviours," times, resulting in ",global_ints.two_behaviour_percent,"%. The ",global_ints.three_behaviour," behaviour was observed ",global_ints.three_behaviour_score," out of ",global_ints.total_behaviours," times, resulting in ",global_ints.three_behaviour_percent,"%. The ", global_ints.four_behaviour," behaviour was observed ",global_ints.four_behaviour_score," out of ",global_ints.total_behaviours," times, resulting in ",global_ints.four_behaviour_percent,"%. The ",global_ints.five_behaviour," behaviour was observed ",global_ints.five_behaviour_score," out of ",global_ints.total_behaviours," times, resulting in ",global_ints.five_behaviour_percent,"%. ",global_ints.six_behaviour_score," intervals were not scored.")
|
||||
$"%FullResult".text = result_text
|
||||
|
||||
# This is where we generate the bars
|
||||
|
||||
$"%ObsBar1".max_value = global_ints.total_behaviours
|
||||
$"%ObsBar1".value = global_ints.one_behaviour_score
|
||||
$"%ObsBar2".max_value = global_ints.total_behaviours
|
||||
$"%ObsBar2".value = global_ints.two_behaviour_score
|
||||
$"%ObsBar3".max_value = global_ints.total_behaviours
|
||||
$"%ObsBar3".value = global_ints.three_behaviour_score
|
||||
$"%ObsBar4".max_value = global_ints.total_behaviours
|
||||
$"%ObsBar4".value = global_ints.four_behaviour_score
|
||||
$"%ObsBar5".max_value = global_ints.total_behaviours
|
||||
$"%ObsBar5".value = global_ints.five_behaviour_score
|
@ -1,14 +0,0 @@
|
||||
extends ProgressBar
|
||||
|
||||
|
||||
onready var global_ints = $"/root/GlobalInts"
|
||||
|
||||
var time_lefts : int
|
||||
|
||||
func _ready():
|
||||
pass
|
||||
|
||||
|
||||
func _process(_delta):
|
||||
time_lefts = $"%TwentySecondTimer".time_left
|
||||
value = time_lefts
|
@ -1,80 +0,0 @@
|
||||
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)
|
@ -1,15 +0,0 @@
|
||||
[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"
|
@ -1,10 +0,0 @@
|
||||
tool
|
||||
extends EditorPlugin
|
||||
|
||||
|
||||
func _enter_tree():
|
||||
add_autoload_singleton("HTML5File", "res://addons/HTML5FileExchange/HTML5FileExchange.gd")
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
remove_autoload_singleton("HTML5File")
|
@ -1,7 +0,0 @@
|
||||
[gd_resource type="Environment" load_steps=2 format=2]
|
||||
|
||||
[sub_resource type="ProceduralSky" id=1]
|
||||
|
||||
[resource]
|
||||
background_mode = 2
|
||||
background_sky = SubResource( 1 )
|
@ -1,120 +0,0 @@
|
||||
extends Node
|
||||
|
||||
var date
|
||||
var ddmmyyyy
|
||||
|
||||
var web_release_version : float
|
||||
var release_version = 0.15
|
||||
|
||||
var total_observed_time : int
|
||||
|
||||
var timer_duration : int = 20
|
||||
|
||||
var observation_minutes : int = 10
|
||||
|
||||
var observation_start_time : String
|
||||
var observation_end_time : String
|
||||
|
||||
var generate_results : bool = false
|
||||
|
||||
var observed_person_name : String
|
||||
var observer_person_name : String
|
||||
var observed_activity : String
|
||||
|
||||
var locked_observation_minutes : int
|
||||
var locked_observation_intervals : int
|
||||
var locked_observations_intervals_remaining : int
|
||||
var locked_observations_completed : int
|
||||
|
||||
var one_acronym = "OnT"
|
||||
var two_acronym = "Loo"
|
||||
var three_acronym = "Dis"
|
||||
var four_acronym = "Wal"
|
||||
var five_acronym = "Oth"
|
||||
var six_acronym = "Emp"
|
||||
|
||||
var one_behaviour = "On Task"
|
||||
var two_behaviour = "Looking"
|
||||
var three_behaviour = "Distracting"
|
||||
var four_behaviour = "Walking"
|
||||
var five_behaviour = "Other"
|
||||
var six_behaviour = "Empty"
|
||||
|
||||
var one_explanation = "The pupil is on task"
|
||||
var two_explanation = "The pupil is looking around in a distracted manner or is staring into the distance"
|
||||
var three_explanation = "The pupil is distracting other pupils or talking to them"
|
||||
var four_explanation = "The pupil is walking through the class"
|
||||
var five_explanation = "The pupil is otherwise distracted and not on task"
|
||||
var six_explanation = "No answer was selected for this round"
|
||||
|
||||
var total_behaviours : int
|
||||
var one_behaviour_score : int
|
||||
var two_behaviour_score : int
|
||||
var three_behaviour_score : int
|
||||
var four_behaviour_score : int
|
||||
var five_behaviour_score : int
|
||||
var six_behaviour_score : int
|
||||
|
||||
var one_behaviour_percent : float
|
||||
var two_behaviour_percent : float
|
||||
var three_behaviour_percent : float
|
||||
var four_behaviour_percent : float
|
||||
var five_behaviour_percent : float
|
||||
|
||||
func reset_all_vars():
|
||||
observation_minutes = 15
|
||||
|
||||
generate_results = false
|
||||
|
||||
observed_person_name = ""
|
||||
observer_person_name = ""
|
||||
observed_activity = ""
|
||||
|
||||
locked_observation_minutes = 0
|
||||
locked_observation_intervals = 0
|
||||
locked_observations_intervals_remaining = 0
|
||||
locked_observations_completed = 0
|
||||
|
||||
one_acronym = "OnT"
|
||||
two_acronym = "Loo"
|
||||
three_acronym = "Dis"
|
||||
four_acronym = "Wal"
|
||||
five_acronym = "Oth"
|
||||
six_acronym = "Emp"
|
||||
|
||||
one_behaviour = "On Task"
|
||||
two_behaviour = "Looking"
|
||||
three_behaviour = "Distracting"
|
||||
four_behaviour = "Walking"
|
||||
five_behaviour = "Other"
|
||||
six_behaviour = "Empty"
|
||||
|
||||
one_explanation = "The pupil is on task"
|
||||
two_explanation = "The pupil is looking around in a distracted manner or is staring into the distance"
|
||||
three_explanation = "The pupil is distracting other pupils or talking to them"
|
||||
four_explanation = "The pupil is walking through the class"
|
||||
five_explanation = "The pupil is otherwise distracted and not on task"
|
||||
six_explanation = "No answer was selected for this round"
|
||||
|
||||
total_behaviours = 0
|
||||
one_behaviour_score = 0
|
||||
two_behaviour_score = 0
|
||||
three_behaviour_score = 0
|
||||
four_behaviour_score = 0
|
||||
five_behaviour_score = 0
|
||||
six_behaviour_score = 0
|
||||
|
||||
one_behaviour_percent = 0.0
|
||||
two_behaviour_percent = 0.0
|
||||
three_behaviour_percent = 0.0
|
||||
four_behaviour_percent = 0.0
|
||||
five_behaviour_percent = 0.0
|
||||
|
||||
observation_start_time = ""
|
||||
observation_end_time = ""
|
||||
|
||||
date = ""
|
||||
|
||||
ddmmyyyy = ""
|
||||
|
||||
total_observed_time = 0
|
BIN
godot/icon.png
Before Width: | Height: | Size: 3.2 KiB |
@ -1,185 +0,0 @@
|
||||
extends CanvasLayer
|
||||
|
||||
|
||||
var date_time
|
||||
var check_time_var : int
|
||||
var ddmmyyyy : String
|
||||
var date
|
||||
var csv_url = "https://raw.githubusercontent.com/hobbesjaap/time-sampling-form/main/version_info.csv"
|
||||
var update_text_url = "https://raw.githubusercontent.com/hobbesjaap/time-sampling-form/main/updater/update_text.md"
|
||||
var update_text : String
|
||||
|
||||
|
||||
onready var date_time_display = $"%CurrentTime"
|
||||
onready var global_ints = $"/root/GlobalInts"
|
||||
onready var minute_label = $"StartScreen/InstructionPanel/MinuteBox/MinuteLabel"
|
||||
|
||||
|
||||
func check_for_updates():
|
||||
var os_check : String
|
||||
os_check = OS.get_name()
|
||||
print(os_check)
|
||||
if os_check == "X11" and "Windows" and "OSX":
|
||||
print("We're on desktop. So let's check for updates!")
|
||||
$"%HTTPRequest".request(csv_url)
|
||||
$"%HTTPRequest2".request(update_text_url)
|
||||
|
||||
|
||||
func _on_HTTPRequest_request_completed(_result, _response_code, _headers, body):
|
||||
var json = JSON.parse(body.get_string_from_utf8())
|
||||
global_ints.web_release_version = json.result
|
||||
if global_ints.web_release_version > global_ints.release_version:
|
||||
print("There's an update!")
|
||||
$"%UpdatePanel".visible = true
|
||||
$"%UpdateText".text = str(update_text)
|
||||
$"%UpdateIntro".text = str("You are currently using version ",global_ints.release_version,". The latest version available is ",global_ints.web_release_version,".")
|
||||
|
||||
|
||||
func _on_HTTPRequest2_request_completed(_result, _response_code, _headers, _body):
|
||||
# Need to find a way to load .txt file contents from a URL into a label. This to show what the update changes are.
|
||||
# var json = JSON.parse(body.get_string_from_utf8())
|
||||
# update_text = str(json.result)
|
||||
pass
|
||||
|
||||
|
||||
func refresh_descriptors():
|
||||
$"%1Acronym".text = global_ints.one_acronym
|
||||
$"%1AcronymE".text = $"%1Acronym".text
|
||||
$"%2Acronym".text = global_ints.two_acronym
|
||||
$"%2AcronymE".text = $"%2Acronym".text
|
||||
$"%3Acronym".text = global_ints.three_acronym
|
||||
$"%3AcronymE".text = $"%3Acronym".text
|
||||
$"%4Acronym".text = global_ints.four_acronym
|
||||
$"%4AcronymE".text = $"%4Acronym".text
|
||||
$"%5Acronym".text = global_ints.five_acronym
|
||||
$"%5AcronymE".text = $"%5Acronym".text
|
||||
$"%1Item".text = global_ints.one_behaviour
|
||||
$"%1ItemE".text = $"%1Item".text
|
||||
$"%2Item".text = global_ints.two_behaviour
|
||||
$"%2ItemE".text = $"%2Item".text
|
||||
$"%3Item".text = global_ints.three_behaviour
|
||||
$"%3ItemE".text = $"%3Item".text
|
||||
$"%4Item".text = global_ints.four_behaviour
|
||||
$"%4ItemE".text = $"%4Item".text
|
||||
$"%5Item".text = global_ints.five_behaviour
|
||||
$"%5ItemE".text = $"%5Item".text
|
||||
$"%1Explanation".text = global_ints.one_explanation
|
||||
$"%1ExplanationE".text = $"%1Explanation".text
|
||||
$"%2Explanation".text = global_ints.two_explanation
|
||||
$"%2ExplanationE".text = $"%2Explanation".text
|
||||
$"%3Explanation".text = global_ints.three_explanation
|
||||
$"%3ExplanationE".text = $"%3Explanation".text
|
||||
$"%4Explanation".text = global_ints.four_explanation
|
||||
$"%4ExplanationE".text = $"%4Explanation".text
|
||||
$"%5Explanation".text = global_ints.five_explanation
|
||||
$"%5ExplanationE".text = $"%5Explanation".text
|
||||
|
||||
func _ready():
|
||||
minute_label.text = str(global_ints.observation_minutes)
|
||||
global_ints.observed_person_name = ""
|
||||
refresh_descriptors()
|
||||
$"StartScreen".visible = true
|
||||
$"%NameChangePanel".visible = true
|
||||
$"%InstructionScreen".visible = true
|
||||
$"%WarningLabel".visible = false
|
||||
$"ObservationWindow".visible = false
|
||||
$"Results".visible = false
|
||||
$"EditScreen".visible = false
|
||||
$"%UpdatePanel".visible = false
|
||||
|
||||
global_ints.date = OS.get_date()
|
||||
global_ints.ddmmyyyy = str(global_ints.date.day, "-", global_ints.date.month, "-", global_ints.date.year)
|
||||
|
||||
check_for_updates()
|
||||
|
||||
func _process(_delta):
|
||||
check_time_var += 1
|
||||
|
||||
if check_time_var == 10:
|
||||
check_time_var = 0
|
||||
date_time = OS.get_time()
|
||||
if date_time.minute < 10:
|
||||
date_time_display.text = str(date_time.hour, ":0", date_time.minute)
|
||||
if date_time.minute >= 10:
|
||||
date_time_display.text = str(date_time.hour, ":", date_time.minute)
|
||||
|
||||
|
||||
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():
|
||||
if global_ints.observation_minutes < 60:
|
||||
global_ints.observation_minutes += 1
|
||||
minute_label.text = str(global_ints.observation_minutes)
|
||||
|
||||
|
||||
func _on_Manual_pressed():
|
||||
var _error = OS.shell_open("https://www.internationalsengroup.org/resources/time-sampling-form/")
|
||||
|
||||
|
||||
func _on_PupilName_pressed():
|
||||
$"%NameLine".text = global_ints.observed_person_name
|
||||
$"%InstructionPanel".visible = false
|
||||
$"%NameChangePanel".visible = true
|
||||
|
||||
|
||||
func _on_Start_pressed():
|
||||
$"StartScreen".visible = false
|
||||
refresh_descriptors()
|
||||
$"ObservationWindow".visible = true
|
||||
$"%BehaviourOne".text = global_ints.one_acronym
|
||||
$"%BehaviourTwo".text = global_ints.two_acronym
|
||||
$"%BehaviourThree".text = global_ints.three_acronym
|
||||
$"%BehaviourFour".text = global_ints.four_acronym
|
||||
$"%BehaviourFive".text = global_ints.five_acronym
|
||||
$"%BTitle1".text = global_ints.one_behaviour
|
||||
$"%BTitle2".text = global_ints.two_behaviour
|
||||
$"%BTitle3".text = global_ints.three_behaviour
|
||||
$"%BTitle4".text = global_ints.four_behaviour
|
||||
$"%BTitle5".text = global_ints.five_behaviour
|
||||
$"%ObsTitle1".text = global_ints.one_behaviour
|
||||
$"%ObsTitle2".text = global_ints.two_behaviour
|
||||
$"%ObsTitle3".text = global_ints.three_behaviour
|
||||
$"%ObsTitle4".text = global_ints.four_behaviour
|
||||
$"%ObsTitle5".text = global_ints.five_behaviour
|
||||
|
||||
global_ints.locked_observation_minutes = global_ints.observation_minutes
|
||||
global_ints.locked_observation_intervals = global_ints.locked_observation_minutes * 3
|
||||
global_ints.locked_observations_intervals_remaining = global_ints.locked_observation_intervals
|
||||
|
||||
$"%ObservationsTotal".text = str(global_ints.locked_observation_intervals)
|
||||
$"%ObservationsRemaining".text = str(global_ints.locked_observations_intervals_remaining)
|
||||
|
||||
var obs_date_time = OS.get_time()
|
||||
if obs_date_time.minute < 10:
|
||||
global_ints.observation_start_time = str(obs_date_time.hour, ":0", obs_date_time.minute)
|
||||
if obs_date_time.minute >= 10:
|
||||
global_ints.observation_start_time = str(obs_date_time.hour, ":", obs_date_time.minute)
|
||||
|
||||
$"%TwentySecondTimer".start(global_ints.timer_duration)
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
func _on_GoToUpdate_pressed():
|
||||
var _error = OS.shell_open("https://github.com/hobbesjaap/time-sampling-form/releases")
|
||||
|
||||
|
||||
func _on_IgnoreUpdate_pressed():
|
||||
$"%UpdatePanel".visible = false
|
@ -1,51 +0,0 @@
|
||||
; Engine configuration file.
|
||||
; It's best edited using the editor UI and not directly,
|
||||
; since the parameters that go here are not all obvious.
|
||||
;
|
||||
; Format:
|
||||
; [section] ; section goes between []
|
||||
; param=value ; assign values to parameters
|
||||
|
||||
config_version=4
|
||||
|
||||
[application]
|
||||
|
||||
config/name="Time Sampling Form"
|
||||
run/main_scene="res://main_screen.tscn"
|
||||
run/low_processor_mode=true
|
||||
boot_splash/image="res://Assets/icons/main_icon.png"
|
||||
boot_splash/bg_color=Color( 0.952941, 0.933333, 0.847059, 1 )
|
||||
config/icon="res://Assets/icons/main_icon.png"
|
||||
config/macos_native_icon="res://Assets/icons/main_icon.icns"
|
||||
config/windows_native_icon="res://Assets/icons/icon.ico"
|
||||
|
||||
[autoload]
|
||||
|
||||
GlobalInts="*res://global_ints.gd"
|
||||
HTML5File="*res://addons/HTML5FileExchange/HTML5FileExchange.gd"
|
||||
|
||||
[display]
|
||||
|
||||
window/size/width=1280
|
||||
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
|
||||
|
||||
[physics]
|
||||
|
||||
common/enable_pause_aware_picking=true
|
||||
|
||||
[rendering]
|
||||
|
||||
quality/intended_usage/framebuffer_allocation=0
|
||||
quality/intended_usage/framebuffer_allocation.mobile=0
|
||||
2d/snapping/use_gpu_pixel_snap=true
|
||||
environment/default_environment="res://default_env.tres"
|
@ -1,104 +0,0 @@
|
||||
[gd_resource type="Theme" load_steps=16 format=2]
|
||||
|
||||
[ext_resource path="res://Assets/fonts/noto_sans_display_bold.ttf" type="DynamicFontData" id=1]
|
||||
[ext_resource path="res://Assets/fonts/noto_sans_display.ttf" type="DynamicFontData" id=2]
|
||||
|
||||
[sub_resource type="DynamicFont" id=1]
|
||||
size = 24
|
||||
font_data = ExtResource( 1 )
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=4]
|
||||
bg_color = Color( 0.207843, 0.219608, 0.317647, 1 )
|
||||
corner_radius_top_left = 10
|
||||
corner_radius_top_right = 10
|
||||
corner_radius_bottom_right = 10
|
||||
corner_radius_bottom_left = 10
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=5]
|
||||
bg_color = Color( 0.862745, 0.435294, 0.329412, 1 )
|
||||
corner_radius_top_left = 10
|
||||
corner_radius_top_right = 10
|
||||
corner_radius_bottom_right = 10
|
||||
corner_radius_bottom_left = 10
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=6]
|
||||
bg_color = Color( 0.941176, 0.772549, 0.517647, 1 )
|
||||
corner_radius_top_left = 10
|
||||
corner_radius_top_right = 10
|
||||
corner_radius_bottom_right = 10
|
||||
corner_radius_bottom_left = 10
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=2]
|
||||
bg_color = Color( 0.862745, 0.435294, 0.329412, 1 )
|
||||
corner_radius_top_left = 10
|
||||
corner_radius_top_right = 10
|
||||
corner_radius_bottom_right = 10
|
||||
corner_radius_bottom_left = 10
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=7]
|
||||
bg_color = Color( 0.941176, 0.772549, 0.517647, 1 )
|
||||
corner_radius_top_left = 10
|
||||
corner_radius_top_right = 10
|
||||
corner_radius_bottom_right = 10
|
||||
corner_radius_bottom_left = 10
|
||||
|
||||
[sub_resource type="DynamicFont" id=3]
|
||||
size = 24
|
||||
font_data = ExtResource( 2 )
|
||||
|
||||
[sub_resource type="DynamicFont" id=8]
|
||||
size = 24
|
||||
font_data = ExtResource( 2 )
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=9]
|
||||
content_margin_left = 15.0
|
||||
content_margin_right = 5.0
|
||||
bg_color = Color( 0.207843, 0.219608, 0.317647, 1 )
|
||||
corner_radius_top_left = 10
|
||||
corner_radius_top_right = 10
|
||||
corner_radius_bottom_right = 10
|
||||
corner_radius_bottom_left = 10
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=11]
|
||||
bg_color = Color( 0.952941, 0.933333, 0.847059, 1 )
|
||||
border_width_left = 2
|
||||
border_width_top = 2
|
||||
border_width_right = 2
|
||||
border_width_bottom = 2
|
||||
border_color = Color( 0.207843, 0.219608, 0.317647, 1 )
|
||||
corner_radius_top_left = 10
|
||||
corner_radius_top_right = 10
|
||||
corner_radius_bottom_right = 10
|
||||
corner_radius_bottom_left = 10
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id=12]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=13]
|
||||
bg_color = Color( 0.862745, 0.435294, 0.329412, 1 )
|
||||
corner_radius_top_left = 5
|
||||
corner_radius_top_right = 5
|
||||
corner_radius_bottom_right = 5
|
||||
corner_radius_bottom_left = 5
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=14]
|
||||
bg_color = Color( 0.941176, 0.772549, 0.517647, 1 )
|
||||
corner_radius_top_left = 5
|
||||
corner_radius_top_right = 5
|
||||
corner_radius_bottom_right = 5
|
||||
corner_radius_bottom_left = 5
|
||||
|
||||
[resource]
|
||||
Button/fonts/font = SubResource( 1 )
|
||||
Button/styles/disabled = SubResource( 4 )
|
||||
Button/styles/focus = SubResource( 5 )
|
||||
Button/styles/hover = SubResource( 6 )
|
||||
Button/styles/normal = SubResource( 2 )
|
||||
Button/styles/pressed = SubResource( 7 )
|
||||
Label/colors/font_color = Color( 0, 0, 0, 1 )
|
||||
Label/fonts/font = SubResource( 3 )
|
||||
LineEdit/fonts/font = SubResource( 8 )
|
||||
LineEdit/styles/normal = SubResource( 9 )
|
||||
Panel/styles/panel = SubResource( 11 )
|
||||
PanelContainer/styles/panel = SubResource( 12 )
|
||||
ProgressBar/styles/bg = SubResource( 13 )
|
||||
ProgressBar/styles/fg = SubResource( 14 )
|
@ -1,5 +0,0 @@
|
||||
"This text is just a placeholder.
|
||||
|
||||
- But I want to test if it works.
|
||||
- Like this.
|
||||
- Or this."
|
@ -1 +0,0 @@
|
||||
0.1
|
|