aboutsummaryrefslogtreecommitdiff
path: root/srb_tk.py
diff options
context:
space:
mode:
Diffstat (limited to 'srb_tk.py')
-rwxr-xr-xsrb_tk.py72
1 files changed, 49 insertions, 23 deletions
diff --git a/srb_tk.py b/srb_tk.py
index c9afee4..0f74e8d 100755
--- a/srb_tk.py
+++ b/srb_tk.py
@@ -136,7 +136,6 @@ class App(tk.Frame):
self.statustext = tk.StringVar()
# app label, for vanity
- # WORKHERE, vanity tag does not actually fill two columns.
self.lbl_app = tk.Label(self.master,text="Savegame editor for Snoopy vs. the Red Baron")
self.lbl_app.grid(row=0,column=0,columnspan=2)
stk.Tooltip(self.lbl_app,text="Also checkout the cli with ./srb.py")
@@ -148,7 +147,6 @@ class App(tk.Frame):
self.chk_silent = tk.Checkbutton(self.master,text="silent",variable=self.silent)
self.chk_silent.grid(row=2,column=1)
self.frm_profiles = tk.Frame(self.master,background="orange",borderwidth=1)
- # WORKHERE: firm up column/placement of things so there is less whitespace.
self.frm_profiles.grid(row=3,column=0,columnspan=2)
# investigate radio button key-bind, up-down, to increment/decrement choice?
self.rad_prof1 = stk.Radiobutton(self.frm_profiles,value=1,text="Profile 1",variable=self.selected_profile,underline=8)
@@ -279,21 +277,20 @@ class App(tk.Frame):
x = 1
for i in range(0,len(srb_lib.LEVELSETS)):
tl = srb_lib.get_levelset_info(i)[0]
- # WORKHERE: will have to set up variables for all this stuff, and then populate this stuff only on the load_form_into_data_for_profile.
self.lbl_levelsets.append(tk.Label(self.frm_levels,text=tl["name"]))
self.lbl_levelsets[i].grid(row=x,column=0,sticky="EW",columnspan=2)
self.spn_levelsets.append(stk.Spinbox(self.frm_levels,textvariable=self.levelset_status_ints[i],from_=0,to=tl["l"],width=2))
self.spn_levelsets[i].grid(row=x+1,column=0)
tk.Label(self.frm_levels,text="/ " + str(tl["l"])).grid(row=x+1,column=1,sticky="EW")
- print(f"For levelset {tl},")
+ #print(f"For levelset {tl},")
these_levels = [k for k in srb_lib.LEVELS if k["setid"] == tl["id"]]
sorted(these_levels,key=lambda i: i["id"])
y = 0
for j in these_levels:
- print(f"Process level {j}")
+ #print(f"Process level {j}")
self.lbl_levels.append(tk.Label(self.frm_levels,text=j["name"]))
self.lbl_levels[-1].grid(row=x,column=3)
- self.opt_levels_hex.append(tk.Entry(self.frm_levels,state="readonly",textvariable=self.level_statuses_hex[j["id"]],width=3))
+ self.opt_levels_hex.append(tk.Entry(self.frm_levels,state="readonly",textvariable=self.level_statuses_hex[j["id"]],width=2))
self.opt_levels_hex[-1].grid(row=x,column=4)
self.opt_levels.append(tk.OptionMenu(self.frm_levels,self.level_statuses[j["id"]],*statuses))
self.opt_levels[-1].config(indicatoron=False,padx=0,pady=0,takefocus=1,width=8)
@@ -303,17 +300,17 @@ class App(tk.Frame):
self.ent_levels_balloons.append(tk.Entry(self.frm_levels,state="readonly",textvariable=self.level_balloons[j["id"]],width=2))
self.ent_levels_balloons[-1].grid(row=x,column=6)
tk.Label(self.frm_levels,text="/ " + str(j["b"])).grid(row=x,column=7)
- self.btn_balloons_none.append(tk.Button(self.frm_levels,text="none",padx=0,pady=0))
+ self.btn_balloons_none.append(tk.Button(self.frm_levels,text="none",padx=0,pady=0,command=lambda tl=j,action="none",ty="balloons": self.button_action_level(tl,action,ty)))
self.btn_balloons_none[-1].grid(row=x,column=8)
- self.btn_balloons_all.append(tk.Button(self.frm_levels,text="all",padx=0,pady=0))
+ self.btn_balloons_all.append(tk.Button(self.frm_levels,text="all",padx=0,pady=0,command=lambda tl=j,action="all",ty="balloons": self.button_action_level(tl,action,ty)))
self.btn_balloons_all[-1].grid(row=x,column=9)
# every level has letters though
self.ent_levels_letters.append(tk.Entry(self.frm_levels,state="readonly",textvariable=self.level_letters[j["id"]],width=2))
self.ent_levels_letters[-1].grid(row=x,column=10)
tk.Label(self.frm_levels,text="/ " + str(len(str(j["l"])))).grid(row=x,column=11)
- self.btn_letters_none.append(tk.Button(self.frm_levels,text="none",padx=0,pady=0))
+ self.btn_letters_none.append(tk.Button(self.frm_levels,text="none",padx=0,pady=0,command=lambda tl=j,action="none",ty="letters": self.button_action_level(tl,action,ty)))
self.btn_letters_none[-1].grid(row=x,column=12)
- self.btn_letters_all.append(tk.Button(self.frm_levels,text="all",padx=0,pady=0))
+ self.btn_letters_all.append(tk.Button(self.frm_levels,text="all",padx=0,pady=0,command=lambda tl=j,action="all",ty="letters": self.button_action_level(tl,action,ty)))
self.btn_letters_all[-1].grid(row=x,column=13)
x += 1
x += 1
@@ -325,6 +322,26 @@ class App(tk.Frame):
# and now open the first file
self.func_open(self.current_file.get())
+ def button_action_level(self, level_obj, action, type_):
+ """ Handle button press from "none" and "all" for balloons and letters for a level """
+ #print(f"debug (button_action_level): {level_obj}, {action}, {type_}")
+ if type_ not in ["balloons","letters"]:
+ raise Exception("Button for level action got invalid type {type_}")
+ action = action.lower()
+ if action not in ["none","all"]:
+ raise Exception("Button for level action got invalid action {action}.")
+ if level_obj not in srb_lib.LEVELS:
+ raise Exception("Button for level action got invalid level {level_obj}.")
+ profile_id = self.selected_profile.get()
+ bdata = self.bdata
+ func = srb_lib.set_level_balloons if type_ == "balloons" else srb_lib.set_level_letters
+ bdata, message = func(bdata,profile_id,level_obj,action, silent=self.silent.get())
+ if bdata == -1 or message != "":
+ raise Exception("Failed to set {type_} to {action} for level {level_obj}, because {message}")
+ else:
+ self.bdata = bdata
+ self.load_form_into_data()
+
def load_form_into_data(self, arg1 = None, arg2 = None, arg3 = None):
"""
Update self.bdata with the values currently displayed/edited on the form. This also updates the checksum.
@@ -415,6 +432,12 @@ class App(tk.Frame):
bdata, message = srb_lib.set_levelset_available_levels(bdata, profile_id, i, self.levelset_status_ints[i].get())
if bdata == -1 or message != "":
raise Exception(f"Failed to set levelset available levels for levelset {i}, message {message}.")
+ for i in range(0,len(srb_lib.LEVELS)):
+ ts = self.level_statuses[i].get()
+ if ts != "unknown":
+ bdata, current_status, message = srb_lib.set_level_status(bdata, profile_id, i, ts, fix_levelset_available_levels=False)
+ if bdata == -1 or current_status == -1 or message != "":
+ raise Exception(f"Failed to set level status for {i} to {ts}, because {message}")
except Exception as e:
bdata = -1
print(f"ERROR! Invalid {e}")
@@ -475,9 +498,9 @@ class App(tk.Frame):
"""
self.func_open(self.current_file.get())
- def mark_traces(self,action):
+ def mark_traces(self,enable = False):
""" Enable or disable traces for variables. This protects the form from always calling load-form-into-data while we are populating the form initially! """
- if action == "enable":
+ if enable:
for j in [
self.health,
self.stunt,
@@ -486,10 +509,14 @@ class App(tk.Frame):
#self.prof1name, # do not trace the profile names, because it prevents spaces ending on the variables
#self.prof2name,
#self.prof3name,
- ] + [i for i in self.levelset_status_ints]:
+ ] + self.levelset_status_ints + self.level_statuses:
+ #print(f"adding w trace for {j}")
j.trace("w",self.load_form_into_data)
# different one
- self.selected_profile.trace("w",self.load_data_into_form_for_current_profile)
+ for j in [
+ self.selected_profile
+ ]:
+ j.trace("w",self.load_data_into_form_for_current_profile)
else: # disable
for j in [
self.health,
@@ -497,18 +524,16 @@ class App(tk.Frame):
self.stunt,
self.gun,
self.equipped_weapon,
- #self.prof1name,
- #self.prof2name,
- #self.prof3name,
- ] + [i for i in self.levelset_status_ints]:
+ ] + self.levelset_status_ints + self.level_statuses:
for i in j.trace_info():
if i[0][0] == "write":
+ #print(f"removing w trace for {j}")
j.trace_remove(i[0][0],i[1])
def load_data_into_form(self, arg1 = None, arg2 = None, arg3 = None):
""" Update all fields in dialog with contents of bdata. """
#print(f"debug (load_data_into_form): {arg1}, {arg2}, {arg3}")
- self.mark_traces("disable")
+ self.mark_traces(False)
# set all variables that are tied to entry boxes
self.checksum.set(hex(self.bchecksum)[2:])
self.prof1_used.set(srb_lib.get_profile_in_use(self.bdata,1))
@@ -525,7 +550,7 @@ class App(tk.Frame):
self.prof3name.set(prof3name)
self.load_data_into_form_for_current_profile()
# not necessary because for_current_profile runs the enable.
- #self.mark_traces("enable")
+ #self.mark_traces(True)
def load_data_into_form_for_current_profile(self, arg1 = None, arg2 = None, arg3 = None):
""" Determine the currently-selected radio button for profile and load those values into the form. """
@@ -537,7 +562,7 @@ class App(tk.Frame):
#print(f"debug: arg2 {arg2}")
#print(f"debug: arg3 {arg3}")
if profile_id >= 1 and profile_id <= 3:
- self.mark_traces("disable")
+ self.mark_traces(False)
# money
self.money.set(srb_lib.get_money(self.bdata,profile_id))
# equipped weapon
@@ -596,7 +621,6 @@ class App(tk.Frame):
#print(f"for levelset {i}, need to set max {i['l']}, current {mission_mask}")
self.levelset_status_ints[x].set(mission_mask)
x += 1
- self.mark_traces("enable")
# levelset available levels
for i in range(0,len(srb_lib.LEVELSETS)):
this_mission_mask, collected_letters = srb_lib.get_levelset_status(self.bdata,profile_id,i,silent=True)
@@ -607,7 +631,7 @@ class App(tk.Frame):
tl_status = int(tl_status,16)
# look up name of status if possible else put "unknown". Thankfully tk handles it gracefully and shows it, but does not let a user pick it if he selects the drop-down menu.
tl_status_str = ""
- print(f"got tl_status {tl_status}, type {type(tl_status)}")
+ #print(f"got tl_status {tl_status}, type {type(tl_status)}")
try:
tl_status_str = [i["name"] for i in srb_lib.LEVEL_STATUSES if i["b"] == tl_status][0]
except:
@@ -618,6 +642,8 @@ class App(tk.Frame):
self.level_balloons[i].set(tl_balloons)
self.level_letters[i].set(tl_letters)
# end if-profile_id is 1,2 or 3.
+ # mark-traces-enable must happen at the end!
+ self.mark_traces(True)
else:
print(f"Error! Cannot load that profile_id into the form.")
bgstack15