Repos / gorts / d75e83ee8b
commit d75e83ee8b79f75560820a79195b3bbdd9713dbd
Author: Nhân <hi@imnhan.com>
Date: Mon Jun 19 20:14:22 2023 +0700
slightly less dumb tracing
Put state variables into a `scoreboard` array to be able to iterate over
things instead of rewriting everything like a freshman.
diff --git a/tcl/main.tcl b/tcl/main.tcl
index f3535b7..0031dc9 100644
--- a/tcl/main.tcl
+++ b/tcl/main.tcl
@@ -27,28 +27,60 @@ wm protocol . WM_DELETE_WINDOW {
exit 0
}
+# Data that we send to the actual web-based overlay:
+array set scoreboard {
+ description ""
+ p1name ""
+ p1country ""
+ p1score 0
+ p1team ""
+ p2name ""
+ p2country ""
+ p2score 0
+ p2team ""
+}
+
+# $applied_scoreboard represents data that has actually been applied
+# to the overlay. This is used to display diff in the UI, and to restore data
+# when user clicks "Discard".
+foreach key [array names scoreboard] {
+ set applied_scoreboard($key) scoreboard($key)
+}
+
+array set var_to_widget {
+ description .c.description.entry
+ p1name .c.players.p1name
+ p1country .c.players.p1country
+ p1score .c.players.p1score
+ p1team .c.players.p1team
+ p2name .c.players.p2name
+ p2country .c.players.p2country
+ p2score .c.players.p2score
+ p2team .c.players.p2team
+}
+
# GUI
ttk::frame .c -padding 5
ttk::frame .c.description
ttk::label .c.description.lbl -text "Match description"
-ttk::entry .c.description.entry -textvariable description
+ttk::entry .c.description.entry -textvariable scoreboard(description)
ttk::frame .c.players
ttk::label .c.players.p1lbl -text "Player 1"
-ttk::combobox .c.players.p1name -textvariable p1name -width 35
-ttk::combobox .c.players.p1country -textvariable p1country -width 5
-ttk::spinbox .c.players.p1score -textvariable p1score -from 0 -to 999 -width 4
+ttk::combobox .c.players.p1name -textvariable scoreboard(p1name) -width 35
+ttk::combobox .c.players.p1country -textvariable scoreboard(p1country) -width 5
+ttk::spinbox .c.players.p1score -textvariable scoreboard(p1score) -from 0 -to 999 -width 4
ttk::button .c.players.p1win -text "▲ Win" -width 6 -state disabled
ttk::label .c.players.p1teamlbl -text "Team 1"
-ttk::combobox .c.players.p1team -textvariable p1team
+ttk::combobox .c.players.p1team -textvariable scoreboard(p1team)
ttk::separator .c.players.separator -orient horizontal
ttk::label .c.players.p2lbl -text "Player 2"
-ttk::combobox .c.players.p2name -textvariable p2name -width 35
-ttk::combobox .c.players.p2country -textvariable p2country -width 5
-ttk::spinbox .c.players.p2score -textvariable p2score -from 0 -to 999 -width 4
+ttk::combobox .c.players.p2name -textvariable scoreboard(p2name) -width 35
+ttk::combobox .c.players.p2country -textvariable scoreboard(p2country) -width 5
+ttk::spinbox .c.players.p2score -textvariable scoreboard(p2score) -from 0 -to 999 -width 4
ttk::button .c.players.p2win -text "▲ Win" -width 6 -state disabled
ttk::label .c.players.p2teamlbl -text "Team 2"
-ttk::combobox .c.players.p2team -textvariable p2team
+ttk::combobox .c.players.p2team -textvariable scoreboard(p2team)
ttk::frame .c.buttons
ttk::button .c.buttons.apply -text "▶ Apply" -command applystate
ttk::button .c.buttons.discard -text "✖ Discard" -state disabled
@@ -107,138 +139,56 @@ proc seticon {b64data} {
proc readstate {} {
puts "readstate"
- set ::description [gets stdin]
- set ::p1name [gets stdin]
- set ::p1country [gets stdin]
- set ::p1score [gets stdin]
- set ::p1team [gets stdin]
- set ::p2name [gets stdin]
- set ::p2country [gets stdin]
- set ::p2score [gets stdin]
- set ::p2team [gets stdin]
+ set ::scoreboard(description) [gets stdin]
+ set ::scoreboard(p1name) [gets stdin]
+ set ::scoreboard(p1country) [gets stdin]
+ set ::scoreboard(p1score) [gets stdin]
+ set ::scoreboard(p1team) [gets stdin]
+ set ::scoreboard(p2name) [gets stdin]
+ set ::scoreboard(p2country) [gets stdin]
+ set ::scoreboard(p2score) [gets stdin]
+ set ::scoreboard(p2team) [gets stdin]
update_applied_state
}
proc applystate {} {
puts "applystate"
- puts $::description
- puts $::p1name
- puts $::p1country
- puts $::p1score
- puts $::p1team
- puts $::p2name
- puts $::p2country
- puts $::p2score
- puts $::p2team
+ puts $::scoreboard(description)
+ puts $::scoreboard(p1name)
+ puts $::scoreboard(p1country)
+ puts $::scoreboard(p1score)
+ puts $::scoreboard(p1team)
+ puts $::scoreboard(p2name)
+ puts $::scoreboard(p2country)
+ puts $::scoreboard(p2score)
+ puts $::scoreboard(p2team)
update_applied_state
}
-set ::checkfunctions {}
proc update_applied_state {} {
- set ::applied_description $::description
- set ::applied_p1name $::p1name
- set ::applied_p1country $::p1country
- set ::applied_p1score $::p1score
- set ::applied_p1team $::p1team
- set ::applied_p2name $::p2name
- set ::applied_p2country $::p2country
- set ::applied_p2score $::p2score
- set ::applied_p2team $::p2team
- foreach f $::checkfunctions { $f "" "" "" }
+ foreach key [array names ::scoreboard] {
+ set ::applied_scoreboard($key) $::scoreboard($key)
+ ::checkdiff "" $key ""
+ }
}
proc setupdiffcheck {} {
# Define styling for "dirty"
foreach x {TEntry TCombobox TSpinbox} {
- ttk::style configure Dirty.${x} -fieldbackground #dffcde
+ ttk::style configure "Dirty.$x" -fieldbackground #dffcde
}
- # I _really_ need to properly learn how scopes and variables work
- proc checkdescription {_ _ _} {
- if {$::description == $::applied_description} {
- .c.description.entry configure -style TEntry
- } else {
- .c.description.entry configure -style Dirty.TEntry
- }
- }
- proc checkp1name {_ _ _} {
- if {$::p1name == $::applied_p1name} {
- .c.players.p1name configure -style TCombobox
- } else {
- .c.players.p1name configure -style Dirty.TCombobox
- }
- }
- proc checkp1country {_ _ _} {
- if {$::p1country == $::applied_p1country} {
- .c.players.p1country configure -style TCombobox
- } else {
- .c.players.p1country configure -style Dirty.TCombobox
- }
- }
- proc checkp1score {_ _ _} {
- if {$::p1score == $::applied_p1score} {
- .c.players.p1score configure -style TSpinbox
- } else {
- .c.players.p1score configure -style Dirty.TSpinbox
- }
- }
- proc checkp1team {_ _ _} {
- if {$::p1team == $::applied_p1team} {
- .c.players.p1team configure -style TCombobox
- } else {
- .c.players.p1team configure -style Dirty.TCombobox
- }
- }
- proc checkp2name {_ _ _} {
- if {$::p2name == $::applied_p2name} {
- .c.players.p2name configure -style TCombobox
- } else {
- .c.players.p2name configure -style Dirty.TCombobox
- }
- }
- proc checkp2country {_ _ _} {
- if {$::p2country == $::applied_p2country} {
- .c.players.p2country configure -style TCombobox
- } else {
- .c.players.p2country configure -style Dirty.TCombobox
- }
- }
- proc checkp2score {_ _ _} {
- if {$::p2score == $::applied_p2score} {
- .c.players.p2score configure -style TSpinbox
- } else {
- .c.players.p2score configure -style Dirty.TSpinbox
- }
- }
- proc checkp2team {_ _ _} {
- if {$::p2team == $::applied_p2team} {
- .c.players.p2team configure -style TCombobox
- } else {
- .c.players.p2team configure -style Dirty.TCombobox
- }
- }
- trace add variable ::description write checkdescription
- trace add variable ::p1name write checkp1name
- trace add variable ::p1country write checkp1country
- trace add variable ::p1score write checkp1score
- trace add variable ::p1team write checkp1team
- trace add variable ::p2name write checkp2name
- trace add variable ::p2country write checkp2country
- trace add variable ::p2score write checkp2score
- trace add variable ::p2team write checkp2team
- set ::checkfunctions {
- checkdescription
- checkp1name
- checkp1country
- checkp1score
- checkp1team
- checkp2name
- checkp2country
- checkp2score
- checkp2team
- }
+ trace add variable ::scoreboard write ::checkdiff
}
+proc checkdiff {_ key _} {
+ set widget $::var_to_widget($key)
+ if {$::scoreboard($key) == $::applied_scoreboard($key)} {
+ $widget configure -style [winfo class $widget]
+ } else {
+ $widget configure -style "Dirty.[winfo class $widget]"
+ }
+}
# By default this window is not focused and not even brought to
# foreground on Windows. I suspect it's because tcl is exec'ed from Go.