You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
270 lines
7.7 KiB
270 lines
7.7 KiB
extends Control
|
|
|
|
|
|
# A scene displaying the poll results as linear merit profiles.
|
|
# This scene is updated dynamically as the poll receives new judgments.
|
|
|
|
|
|
const MeritProfileScene = preload("res://addons/majority_judgment/nodes/MajorityJudgmentMeritProfileControl.tscn")
|
|
|
|
|
|
export(Resource) var poll setget set_poll, get_poll
|
|
|
|
export(int) var vertical_gap := 4 # pixels
|
|
export(int) var candidates_labels_width := 200 # pixels
|
|
export(bool) var align_with_bottom := false # pixels
|
|
export(int) var padding_with_window_top := 20 # pixels
|
|
export(int) var padding_with_window_bottom := 95 # pixels
|
|
|
|
|
|
onready var ClosePollButton = find_node("ClosePollButton", true)
|
|
onready var ClosePollDialog = find_node("ClosePollConfirmationDialog", true)
|
|
onready var ProfilesContainer = find_node("ProfilesContainer", true)
|
|
|
|
|
|
var providers:Array # of MajorityJudgmentAbstractJudgmentsProvider
|
|
#var provider:MajorityJudgmentAbstractJudgmentsProvider
|
|
|
|
|
|
func _ready():
|
|
ClosePollDialog.connect("confirmed", self, "close_and_exit")
|
|
|
|
|
|
func _input(_event):
|
|
if Input.is_action_just_pressed("ui_cancel"):
|
|
prompt_close_and_exit()
|
|
if Input.is_action_just_pressed("ui_toggle_elements"):
|
|
ClosePollButton.visible = not ClosePollButton.visible
|
|
|
|
|
|
func prompt_close_and_exit():
|
|
ClosePollDialog.popup_centered()
|
|
|
|
|
|
func close_and_exit():
|
|
close_poll()
|
|
exit_scene()
|
|
|
|
|
|
func exit_scene():
|
|
# Close things up
|
|
# stop_providers()
|
|
App.go_to_main_menu()
|
|
|
|
|
|
func get_poll() -> MajorityJudgmentPoll:
|
|
return poll
|
|
|
|
|
|
func set_poll(__poll:MajorityJudgmentPoll):
|
|
poll = __poll
|
|
craft_nodes()
|
|
update_scene()
|
|
App.save_ongoing_poll()
|
|
|
|
self.providers = App.get_providers()
|
|
for provider in self.providers:
|
|
start_provider(provider)
|
|
|
|
|
|
func close_poll():
|
|
App.close_ongoing_poll()
|
|
|
|
|
|
var candidates_lines_nodes := Array()
|
|
var profiles_nodes := Array()
|
|
func craft_nodes():
|
|
var tally : MajorityJudgmentPollTally = get_poll().tally()
|
|
|
|
var candidate_index = 0 # as they were initially written, before the sort
|
|
for candidate in get_poll().get_candidates():
|
|
|
|
var profile = create_merit_profile_scene(6)
|
|
if tally:
|
|
profile.refresh(tally.get_tally_of_candidate(candidate).merit_profile)
|
|
var height = profile.compute_height()
|
|
profile.rect_min_size = Vector2(400, height)
|
|
|
|
var container = self.ProfilesContainer
|
|
|
|
var wrapper = HBoxContainer.new()
|
|
wrapper.name = "Candidate%sLine" % char(candidate_index+65)
|
|
wrapper.anchor_right = 1.0
|
|
# wrapper.rect_min_size = Vector2(400, height)
|
|
var position = candidate_index
|
|
if tally:
|
|
position = tally.get_position_of_candidate(candidate, true)
|
|
|
|
wrapper.margin_top = position * (height + vertical_gap)
|
|
wrapper.margin_bottom = wrapper.margin_top + height
|
|
self.candidates_lines_nodes.append(wrapper)
|
|
|
|
var candidate_label = Label.new()
|
|
candidate_label.name = "CandidateLabel"
|
|
candidate_label.text = candidate.get_name()
|
|
candidate_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|
# candidate_label.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
|
candidate_label.rect_min_size = Vector2(candidates_labels_width, height)
|
|
candidate_label.rect_size = Vector2(candidates_labels_width, height)
|
|
candidate_label.clip_text = true
|
|
candidate_label.autowrap = true
|
|
candidate_label.valign = Label.VALIGN_CENTER
|
|
candidate_label.align = Label.ALIGN_RIGHT
|
|
var candidate_font = preload("res://addons/majority_judgment/fonts/KenneyMini.tres")
|
|
candidate_font.set_size(int(height*0.62))
|
|
candidate_label.set("custom_fonts/font", candidate_font)
|
|
|
|
var candidate_letter := Label.new()
|
|
candidate_letter.name = "CandidateLetterLabel"
|
|
candidate_letter.text = char(candidate_index+65)
|
|
# candidate_letter.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|
# candidate_letter.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
|
candidate_letter.rect_min_size = Vector2(height, height)
|
|
# candidate_letter.rect_size = Vector2(candidates_labels_width, height)
|
|
candidate_letter.valign = Label.VALIGN_CENTER
|
|
candidate_letter.align = Label.ALIGN_CENTER
|
|
var letter_font = preload("res://addons/majority_judgment/fonts/KenneyMiniSquare.tres")
|
|
letter_font.set_size(height*0.75)
|
|
candidate_letter.set("custom_fonts/font", letter_font)
|
|
|
|
wrapper.add_child(candidate_label)
|
|
wrapper.add_child(candidate_letter)
|
|
wrapper.add_child(profile)
|
|
container.add_child(wrapper)
|
|
|
|
# wrapper.margin_top = position * height
|
|
# wrapper.margin_bottom = wrapper.margin_top + height
|
|
|
|
candidate_label.owner = self
|
|
profile.owner = self
|
|
wrapper.owner = self
|
|
self.profiles_nodes.append(profile)
|
|
|
|
candidate_index += 1
|
|
|
|
|
|
func update_scene():
|
|
$Tween.remove_all()
|
|
var tally : MajorityJudgmentPollTally = get_poll().tally()
|
|
var candidate_index = 0 # as they were initially written, before the sort
|
|
var candidates_amount = get_poll().count_candidates()
|
|
var container_height = $ProfilesContainer.rect_size.y
|
|
for candidate in get_poll().get_candidates():
|
|
var profile = profiles_nodes[candidate_index]
|
|
var candidate_line_node = self.candidates_lines_nodes[candidate_index]
|
|
var position = candidate_index
|
|
var height = profile.compute_height()
|
|
if tally:
|
|
position = tally.get_position_of_candidate(candidate, true)
|
|
|
|
var tween_transition = Tween.TRANS_SINE
|
|
var tween_ease = Tween.EASE_IN_OUT
|
|
var tween_duration = 0.818
|
|
var tween_delay = 0
|
|
var cln_margin_top = position * (height + vertical_gap)
|
|
if align_with_bottom:
|
|
cln_margin_top += (
|
|
container_height
|
|
-
|
|
candidates_amount * (height + vertical_gap)
|
|
-
|
|
padding_with_window_bottom
|
|
)
|
|
else:
|
|
cln_margin_top += padding_with_window_top
|
|
|
|
|
|
$Tween.interpolate_property(
|
|
candidate_line_node,
|
|
"margin_top",
|
|
candidate_line_node.margin_top,
|
|
cln_margin_top,
|
|
tween_duration,
|
|
tween_transition,
|
|
tween_ease,
|
|
tween_delay
|
|
)
|
|
$Tween.interpolate_property(
|
|
candidate_line_node,
|
|
"margin_bottom",
|
|
candidate_line_node.margin_bottom,
|
|
cln_margin_top + height,
|
|
tween_duration,
|
|
tween_transition,
|
|
tween_ease,
|
|
tween_delay
|
|
)
|
|
$Tween.start()
|
|
|
|
# candidate_line_node.margin_top = position * (height + vertical_gap)
|
|
# candidate_line_node.margin_bottom = wrapper.margin_top + height
|
|
|
|
if tally:
|
|
var merit = tally.get_tally_of_candidate(candidate).merit_profile
|
|
profile.refresh(merit)
|
|
else:
|
|
var merit = poll.get_dummy_merit_profile(candidate)
|
|
profile.refresh(merit)
|
|
|
|
candidate_index += 1
|
|
|
|
|
|
func create_merit_profile_scene(gradation_size:int):
|
|
var mps = MeritProfileScene.instance()
|
|
mps.set_poll(get_poll())
|
|
mps.craft_nodes(gradation_size)
|
|
return mps
|
|
|
|
|
|
func start_provider(__provider):
|
|
# self.provider = __provider
|
|
var connected = __provider.connect(
|
|
"judgment_emitted",
|
|
self, "__on_judgment_emitted"
|
|
)
|
|
__provider.start_providing()
|
|
|
|
|
|
var known_participants := Dictionary() # id => Participant
|
|
|
|
func get_or_create_participant(identifier:String) -> MajorityJudgmentParticipant:
|
|
if not known_participants.has(identifier):
|
|
known_participants[identifier] = MajorityJudgmentParticipant.make(identifier)
|
|
return known_participants[identifier]
|
|
|
|
|
|
var __save_mutex := Mutex.new() # perhaps overzealous
|
|
|
|
func __on_judgment_emitted(author_identifier, grade_index, candidate_index):
|
|
# Data comes from userland, best be careful here
|
|
if (
|
|
grade_index < 0
|
|
or
|
|
grade_index >= poll.grading.grades.size()
|
|
):
|
|
# printerr("Ignoring grade #%d since it's out of range.")
|
|
return
|
|
if (
|
|
candidate_index < 0
|
|
or
|
|
candidate_index >= poll.candidates.size()
|
|
):
|
|
# printerr("Ignoring candidate %s since it's out of range." % [char(candidate_index)])
|
|
return
|
|
|
|
__save_mutex.lock()
|
|
var j = MajorityJudgmentJudgment.new()
|
|
j.set_participant(get_or_create_participant(author_identifier))
|
|
j.set_grade(poll.grading.grades[grade_index])
|
|
j.set_candidate(poll.candidates[candidate_index])
|
|
poll.add_judgment(j)
|
|
|
|
App.save_ongoing_poll()
|
|
__save_mutex.unlock()
|
|
|
|
update_scene()
|
|
|
|
|
|
func _on_ClosePollButton_pressed():
|
|
prompt_close_and_exit()
|