diff options
Diffstat (limited to 'srb_tk.py')
-rwxr-xr-x | srb_tk.py | 72 |
1 files changed, 49 insertions, 23 deletions
@@ -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.") |