feat: add a basic GUI to create a poll and set up twitch

Nothing happens yet on poll creation ; this is a WIP.
master
Dominique Merle 4 years ago
parent cf08bd1944
commit 435c5c3b72

@ -0,0 +1,11 @@
extends Control
func _on_NewPollButton_pressed():
var changed = get_tree().change_scene("res://gui/forms/NewPollForm.tscn")
if OK != changed:
printerr("Failed to open the new poll form scene.")
func _on_ExitButton_pressed():
get_tree().quit()

@ -0,0 +1,54 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://gui/MainMenu.gd" type="Script" id=1]
[ext_resource path="res://gui/widgets/Background.tscn" type="PackedScene" id=2]
[node name="Application" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Background" parent="." instance=ExtResource( 2 )]
[node name="CenterContainer" type="CenterContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
__meta__ = {
"_edit_lock_": true,
"_edit_use_anchors_": false
}
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"]
margin_left = 478.0
margin_top = 257.0
margin_right = 546.0
margin_bottom = 343.0
[node name="NewPollButton" type="Button" parent="CenterContainer/VBoxContainer"]
margin_right = 68.0
margin_bottom = 20.0
text = "New Poll"
[node name="SettingsButton" type="Button" parent="CenterContainer/VBoxContainer"]
margin_top = 24.0
margin_right = 68.0
margin_bottom = 44.0
text = "Settings"
[node name="ExitButton" type="Button" parent="CenterContainer/VBoxContainer"]
margin_top = 48.0
margin_right = 68.0
margin_bottom = 68.0
text = "Exit"
[node name="VersionLabel" type="Label" parent="CenterContainer/VBoxContainer"]
margin_top = 72.0
margin_right = 68.0
margin_bottom = 86.0
text = "v0.1"
align = 1
[connection signal="pressed" from="CenterContainer/VBoxContainer/NewPollButton" to="." method="_on_NewPollButton_pressed"]
[connection signal="pressed" from="CenterContainer/VBoxContainer/ExitButton" to="." method="_on_ExitButton_pressed"]

@ -0,0 +1,131 @@
extends Tree
const TEXT_COLUMN := 0
# section == 0 if dropping on item
# section == -1 if dropping above item
# section == +1 if dropping below item
signal item_moved(item, to_item, section)
func _ready():
setup()
setup_dummy_items()
append_item_invitation()
func setup():
var root := create_item()
root.set_text(TEXT_COLUMN, "Candidates")
connect("item_edited", self, "__on_item_edited")
connect("item_moved", self, "__on_item_moved")
func setup_dummy_items():
create_candidate_item("Candidate A")
create_candidate_item("Candidate B")
func create_candidate_item(__name:String):
var candidate_item := create_item()
candidate_item.set_editable(TEXT_COLUMN, true)
candidate_item.set_text(TEXT_COLUMN, __name)
func append_item_invitation():
var invite_text = "+"
var root = get_root()
# var item = root.get_children() # get_first_child(), probably
var items = __get_children_items(root)
if items and items.back().get_text(TEXT_COLUMN) == invite_text:
return
var invite = create_item(root)
invite.set_editable(TEXT_COLUMN, true)
invite.set_text(TEXT_COLUMN, invite_text)
invite.move_to_bottom() # superfluous
func prune_empty_items():
var items_to_prune = Array()
for item in __get_children_items(get_root()):
if item.get_text(TEXT_COLUMN) == '':
if item.get_next():
item.get_next().select(TEXT_COLUMN)
ensure_cursor_is_visible()
item.free()
func __on_item_edited():
append_item_invitation()
var selected = get_next_selected(null)
if selected and selected.get_next():
selected.get_next().select(TEXT_COLUMN)
ensure_cursor_is_visible()
prune_empty_items() # after, since it may change item selection
func __on_item_moved(item, to_item, section):
if not to_item:
printerr("No item unto which to drop. Weird.")
var offset = 0 if section <= 0 else 1
var new_item = create_item(get_root(), __get_item_index(to_item)+offset)
new_item.set_text(TEXT_COLUMN, item.get_text(TEXT_COLUMN))
new_item.set_editable(TEXT_COLUMN, true)
new_item.select(TEXT_COLUMN)
item.free()
ensure_cursor_is_visible()
func __get_children_items(parent:TreeItem) -> Array:
var items := Array()
var item = parent.get_children()
while (item):
items.append(item)
item = item.get_next()
return items
func __get_item_index(of_item:TreeItem):
var parent = of_item.get_parent()
assert(parent) # or return … what, zero?
var index := 0
var item : TreeItem = parent.get_children()
while (item):
if item == of_item:
return index
item = item.get_next()
index += 1
assert(false, "Item not found")
return -1
func get_drag_data(_position) -> TreeItem:
set_drop_mode_flags(DROP_MODE_INBETWEEN)
var item_preview = Label.new()
item_preview.text = get_selected().get_text(TEXT_COLUMN)
set_drag_preview(item_preview)
return get_selected()
func can_drop_data(_position, data):
return data is TreeItem
func drop_data(position, item):
var to_item = get_item_at_position(position)
var section = get_drop_section_at_position(position)
if not to_item or section == -100:
#printerr("Dropping in the void")
to_item = get_root().get_children()
section = 0
emit_signal('item_moved', item, to_item, section)

@ -0,0 +1,24 @@
extends Control
func _on_CancelButton_pressed():
get_tree().change_scene("res://gui/MainMenu.tscn")
func _on_LaunchButton_pressed():
var poll = collect_poll_from_form(self)
if poll:
App.start_poll(poll)
func collect_poll_from_form(form:Control) -> MajorityJudgmentPoll:
var poll = MajorityJudgmentPoll.new()
var title_line_edit = form.find_node("TitleLineEdit", true, false)
if title_line_edit.text:
poll.set_title(title_line_edit.text)
var candidates_tree = form.find_node("CandidatesTree", true, false)
return poll

@ -0,0 +1,128 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://gui/widgets/Background.tscn" type="PackedScene" id=1]
[ext_resource path="res://gui/forms/NewPollForm.gd" type="Script" id=2]
[ext_resource path="res://gui/forms/CandidatesTree.gd" type="Script" id=3]
[node name="NewPollForm" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Background" parent="." instance=ExtResource( 1 )]
[node name="CenterContainer" type="CenterContainer" parent="."]
anchor_top = -0.00187078
anchor_right = 1.0
anchor_bottom = 0.998129
__meta__ = {
"_edit_lock_": true,
"_edit_use_anchors_": false
}
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"]
margin_left = 397.0
margin_top = 179.0
margin_right = 627.0
margin_bottom = 419.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="TitleHBoxContainer" type="HBoxContainer" parent="CenterContainer/VBoxContainer"]
margin_right = 230.0
margin_bottom = 24.0
[node name="Label" type="Label" parent="CenterContainer/VBoxContainer/TitleHBoxContainer"]
margin_top = 5.0
margin_right = 28.0
margin_bottom = 19.0
text = "Title"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="TitleLineEdit" type="LineEdit" parent="CenterContainer/VBoxContainer/TitleHBoxContainer"]
margin_left = 32.0
margin_right = 230.0
margin_bottom = 24.0
size_flags_horizontal = 3
max_length = 256
placeholder_text = "Who should we raid?"
[node name="CandidatesContainer" type="MarginContainer" parent="CenterContainer/VBoxContainer"]
margin_top = 28.0
margin_right = 230.0
margin_bottom = 148.0
rect_min_size = Vector2( 230, 120 )
size_flags_vertical = 3
[node name="CandidatesTree" type="Tree" parent="CenterContainer/VBoxContainer/CandidatesContainer"]
margin_right = 230.0
margin_bottom = 120.0
size_flags_horizontal = 3
size_flags_vertical = 3
hide_folding = true
hide_root = true
script = ExtResource( 3 )
[node name="GradingHBoxContainer" type="HBoxContainer" parent="CenterContainer/VBoxContainer"]
margin_top = 152.0
margin_right = 230.0
margin_bottom = 172.0
[node name="Label" type="Label" parent="CenterContainer/VBoxContainer/GradingHBoxContainer"]
self_modulate = Color( 1, 1, 1, 0.25098 )
margin_top = 3.0
margin_right = 49.0
margin_bottom = 17.0
text = "Grading"
[node name="GradingMenuButton" type="MenuButton" parent="CenterContainer/VBoxContainer/GradingHBoxContainer"]
margin_left = 53.0
margin_right = 230.0
margin_bottom = 20.0
size_flags_horizontal = 3
disabled = true
text = "Quality (6 grades)"
flat = false
clip_text = true
items = [ "Quality (2 grades)", null, 2, true, false, 0, 0, null, "", false, "Quality (3 grades)", null, 2, false, false, 0, 0, null, "", false, "Quality (4 grades)", null, 2, false, false, 2, 0, null, "", false ]
[node name="DelegationCheckButton" type="CheckButton" parent="CenterContainer/VBoxContainer"]
margin_top = 176.0
margin_right = 230.0
margin_bottom = 216.0
disabled = true
text = "Allow Delegations"
[node name="ButtonsHBoxContainer" type="HBoxContainer" parent="CenterContainer/VBoxContainer"]
margin_top = 220.0
margin_right = 230.0
margin_bottom = 240.0
[node name="CancelButton" type="Button" parent="CenterContainer/VBoxContainer/ButtonsHBoxContainer"]
margin_right = 109.0
margin_bottom = 20.0
size_flags_horizontal = 3
text = "CANCEL"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VSeparator" type="VSeparator" parent="CenterContainer/VBoxContainer/ButtonsHBoxContainer"]
margin_left = 113.0
margin_right = 117.0
margin_bottom = 20.0
[node name="LaunchButton" type="Button" parent="CenterContainer/VBoxContainer/ButtonsHBoxContainer"]
margin_left = 121.0
margin_right = 230.0
margin_bottom = 20.0
size_flags_horizontal = 3
text = "CREATE"
[connection signal="pressed" from="CenterContainer/VBoxContainer/ButtonsHBoxContainer/CancelButton" to="." method="_on_CancelButton_pressed"]
[connection signal="pressed" from="CenterContainer/VBoxContainer/ButtonsHBoxContainer/LaunchButton" to="." method="_on_LaunchButton_pressed"]

@ -0,0 +1,116 @@
extends Control
# Allow streamers to define their twitch credentials.
# Since this config is sensitive, should it be encrypted?
#
# Generate application
# https://dev.twitch.tv/console/apps/create
#
# Get OAuth Token
# https://twitchapps.com/tmi/
var config := {
'nick': '', # whatever you want
'channel': '', # twitch identifier, usually lowercase
'client': '', # Identifies the application registered on twitch
'oauth': '', # https://twitchapps.com/tmi/
}
const TWITCH_OAUTH_FILE_PATH = "user://twitch_chat_auth_config.json"
onready var OAuthEdit = find_node("OAuthLineEdit")
onready var NickEdit = find_node("NickLineEdit")
onready var ClientIdEdit = find_node("ClientIdLineEdit")
onready var ChannelEdit = find_node("ChannelLineEdit")
func _ready():
read_from_file()
write_to_ui()
# _____ _ _
# | ___(_) | ___
# | |_ | | |/ _ \
# | _| | | | __/
# |_| |_|_|\___|
#
func read_from_file():
var file = File.new()
if not file.file_exists(TWITCH_OAUTH_FILE_PATH):
return Dictionary()
file.open(TWITCH_OAUTH_FILE_PATH, File.READ)
var json = file.get_as_text()
var dson = JSON.parse(json)
if dson.error:
printerr("Auth config file exists but is confusing me.")
return null
self.config = dson.result
file.close()
return self.config
func write_to_file():
var file = File.new()
file.open(TWITCH_OAUTH_FILE_PATH, File.WRITE)
file.store_string(JSON.print(self.config, ' '))
file.close()
# _ _ ___
# | | | |_ _|
# | | | || |
# | |_| || |
# \___/|___|
#
func read_from_ui():
self.config['oauth'] = OAuthEdit.text
self.config['nick'] = NickEdit.text
self.config['channel'] = ChannelEdit.text
self.config['client'] = ClientIdEdit.text
func write_to_ui():
OAuthEdit.text = self.config['oauth']
NickEdit.text = self.config['nick']
ChannelEdit.text = self.config['channel']
ClientIdEdit.text = self.config['client']
# _____ _
# | ____|_ _____ _ __ | |_ ___
# | _| \ \ / / _ \ '_ \| __/ __|
# | |___ \ V / __/ | | | |_\__ \
# |_____| \_/ \___|_| |_|\__|___/
#
func _on_SaveButton_pressed():
read_from_ui()
write_to_file()
App.go_to_main_menu()
func _on_CancelButton_pressed():
App.go_to_main_menu()
func _on_ClientIdHelpButton_pressed():
OS.shell_open("https://dev.twitch.tv/dashboard/apps/create")
func _on_OAuthHelpButton_pressed():
OS.shell_open("https://twitchapps.com/tmi/")

@ -0,0 +1,158 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://gui/forms/twitch_config/TwitchAuthConfig.gd" type="Script" id=1]
[ext_resource path="res://gui/widgets/Background.tscn" type="PackedScene" id=2]
[node name="TwitchAuthConfig" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Background" parent="." instance=ExtResource( 2 )]
[node name="CenterContainer" type="CenterContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
margin_top = -1.05945
margin_bottom = -1.05945
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"]
margin_left = 410.0
margin_top = 221.0
margin_right = 613.0
margin_bottom = 379.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="TitleLabel" type="Label" parent="CenterContainer/VBoxContainer"]
margin_right = 203.0
margin_bottom = 14.0
text = "TWITCH CHAT CONFIGURATION"
[node name="NickContainer" type="HBoxContainer" parent="CenterContainer/VBoxContainer"]
margin_top = 18.0
margin_right = 203.0
margin_bottom = 42.0
size_flags_horizontal = 3
[node name="NickLabel" type="Label" parent="CenterContainer/VBoxContainer/NickContainer"]
margin_top = 5.0
margin_right = 28.0
margin_bottom = 19.0
text = "Nick"
[node name="NickLineEdit" type="LineEdit" parent="CenterContainer/VBoxContainer/NickContainer"]
margin_left = 32.0
margin_right = 203.0
margin_bottom = 24.0
hint_tooltip = "May be whatever you want."
size_flags_horizontal = 3
[node name="ChannelContainer" type="HBoxContainer" parent="CenterContainer/VBoxContainer"]
margin_top = 46.0
margin_right = 203.0
margin_bottom = 70.0
size_flags_horizontal = 3
[node name="ChannelLabel" type="Label" parent="CenterContainer/VBoxContainer/ChannelContainer"]
margin_top = 5.0
margin_right = 51.0
margin_bottom = 19.0
text = "Channel"
[node name="ChannelLineEdit" type="LineEdit" parent="CenterContainer/VBoxContainer/ChannelContainer"]
margin_left = 55.0
margin_right = 203.0
margin_bottom = 24.0
hint_tooltip = "Your twitch username, usually. Usually lowercase."
size_flags_horizontal = 3
[node name="ClientIdContainer" type="HBoxContainer" parent="CenterContainer/VBoxContainer"]
margin_top = 74.0
margin_right = 203.0
margin_bottom = 98.0
size_flags_horizontal = 3
[node name="ClientIdLabel" type="Label" parent="CenterContainer/VBoxContainer/ClientIdContainer"]
margin_top = 5.0
margin_right = 54.0
margin_bottom = 19.0
text = "Client Id"
[node name="ClientIdLineEdit" type="LineEdit" parent="CenterContainer/VBoxContainer/ClientIdContainer"]
margin_left = 58.0
margin_right = 181.0
margin_bottom = 24.0
hint_tooltip = "May be generated here : https://dev.twitch.tv/dashboard/apps/create"
size_flags_horizontal = 3
[node name="ClientIdHelpButton" type="Button" parent="CenterContainer/VBoxContainer/ClientIdContainer"]
margin_left = 185.0
margin_right = 203.0
margin_bottom = 24.0
text = "?"
[node name="OAuthContainer" type="HBoxContainer" parent="CenterContainer/VBoxContainer"]
margin_top = 102.0
margin_right = 203.0
margin_bottom = 126.0
size_flags_horizontal = 3
[node name="OAuthLabel" type="Label" parent="CenterContainer/VBoxContainer/OAuthContainer"]
margin_top = 5.0
margin_right = 83.0
margin_bottom = 19.0
text = "OAuth Token"
[node name="OAuthLineEdit" type="LineEdit" parent="CenterContainer/VBoxContainer/OAuthContainer"]
margin_left = 87.0
margin_right = 181.0
margin_bottom = 24.0
hint_tooltip = "May be generated here : https://twitchapps.com/tmi/"
size_flags_horizontal = 3
secret = true
[node name="OAuthHelpButton" type="Button" parent="CenterContainer/VBoxContainer/OAuthContainer"]
margin_left = 185.0
margin_right = 203.0
margin_bottom = 24.0
text = "?"
[node name="HSeparator" type="HSeparator" parent="CenterContainer/VBoxContainer"]
margin_top = 130.0
margin_right = 203.0
margin_bottom = 134.0
rect_min_size = Vector2( 200, 0 )
[node name="ButtonsContainer" type="HBoxContainer" parent="CenterContainer/VBoxContainer"]
margin_top = 138.0
margin_right = 203.0
margin_bottom = 158.0
[node name="CancelButton" type="Button" parent="CenterContainer/VBoxContainer/ButtonsContainer"]
margin_right = 54.0
margin_bottom = 20.0
text = "Cancel"
[node name="VSeparator" type="VSeparator" parent="CenterContainer/VBoxContainer/ButtonsContainer"]
margin_left = 58.0
margin_right = 158.0
margin_bottom = 20.0
size_flags_horizontal = 3
[node name="SaveButton" type="Button" parent="CenterContainer/VBoxContainer/ButtonsContainer"]
margin_left = 162.0
margin_right = 203.0
margin_bottom = 20.0
text = "Save"
[connection signal="pressed" from="CenterContainer/VBoxContainer/ClientIdContainer/ClientIdHelpButton" to="." method="_on_ClientIdHelpButton_pressed"]
[connection signal="pressed" from="CenterContainer/VBoxContainer/OAuthContainer/OAuthHelpButton" to="." method="_on_OAuthHelpButton_pressed"]
[connection signal="pressed" from="CenterContainer/VBoxContainer/ButtonsContainer/CancelButton" to="." method="_on_CancelButton_pressed"]
[connection signal="pressed" from="CenterContainer/VBoxContainer/ButtonsContainer/SaveButton" to="." method="_on_SaveButton_pressed"]

@ -0,0 +1,21 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://sprites/mieuxvoter_logo.png" type="Texture" id=1]
[node name="Background" type="Panel"]
anchor_right = 1.0
anchor_bottom = 1.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="TextureRect" type="TextureRect" parent="."]
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -150.193
margin_top = -88.2292
margin_right = -0.193359
margin_bottom = -0.229187
texture = ExtResource( 1 )
Loading…
Cancel
Save