77import funscript_editor .utils .logging as logging
88import copy
99import sys
10+ import os
11+ import json
1012import numpy as np
1113import pyqtgraph as pg
1214from scipy .signal import savgol_filter , find_peaks , find_peaks_cwt
1315
1416from funscript_editor .algorithms .signal import Signal ,SignalParameter
1517from funscript_editor .ui .cut_tracking_result import Slider
18+ from funscript_editor .definitions import CONFIG_DIR
19+
1620
1721class QHLine (QtWidgets .QFrame ):
1822 def __init__ (self ):
@@ -32,6 +36,8 @@ def __init__(self, metric, raw_score, video_info, parent=None):
3236 self .raw_score_idx = [x for x in range (len (raw_score ))]
3337 self .raw_score = raw_score
3438 self .raw_score_np = [[i , raw_score [i ]] for i in range (len (raw_score ))]
39+ self .ui_settings_file = os .path .join (CONFIG_DIR , "postprocessing_ui_settings.json" )
40+ self .load_prev_ui_settings ()
3541
3642 self .verticalLayout .addWidget (QtWidgets .QLabel (f"Postprocessing for { metric } " ))
3743
@@ -65,6 +71,11 @@ def __init__(self, metric, raw_score, video_info, parent=None):
6571 self .result_val = []
6672
6773 self .close_with_ok = False
74+
75+ for index in range (self .tabs .count ()):
76+ if self .prev_ui_settings ["selected" ] == self .tabs .tabText (index ):
77+ self .tabs .setCurrentIndex (index )
78+
6879 self .update_plot ()
6980
7081
@@ -73,9 +84,15 @@ def __init__(self, metric, raw_score, video_info, parent=None):
7384
7485 def add_rdp_tab (self ):
7586 tab_name = "Ramer–Douglas–Peucker"
87+ if tab_name not in self .prev_ui_settings ["tabs" ]:
88+ self .prev_ui_settings ["tabs" ][tab_name ] = {}
89+
90+ previous_or_default = lambda name , default : \
91+ self .prev_ui_settings ["tabs" ][tab_name ][name ] if name in self .prev_ui_settings ["tabs" ][tab_name ] else default
92+
7693 self .tabs_content [tab_name ] = {"main" : QtWidgets .QWidget (), "widgets" : {}}
7794 self .tabs_content [tab_name ]["main" ].layout = QtWidgets .QVBoxLayout (self )
78- self .tabs_content [tab_name ]["widgets" ]["epsilon" ] = Slider ("Epsilon" , 100 , 10 )
95+ self .tabs_content [tab_name ]["widgets" ]["epsilon" ] = Slider ("Epsilon" , 100 , previous_or_default ( "epsilon" , 20 ) )
7996 self .tabs_content [tab_name ]["main" ].layout .addWidget (self .tabs_content [tab_name ]["widgets" ]["epsilon" ])
8097 self .tabs_content [tab_name ]["widgets" ]["epsilon" ].slider .valueChanged .connect (self .update_plot )
8198 self .tabs_content [tab_name ]["main" ].setLayout (self .tabs_content [tab_name ]["main" ].layout )
@@ -84,9 +101,15 @@ def add_rdp_tab(self):
84101
85102 def add_vw_tab (self ):
86103 tab_name = "Visvalingam-Whyatt"
104+ if tab_name not in self .prev_ui_settings ["tabs" ]:
105+ self .prev_ui_settings ["tabs" ][tab_name ] = {}
106+
107+ previous_or_default = lambda name , default : \
108+ self .prev_ui_settings ["tabs" ][tab_name ][name ] if name in self .prev_ui_settings ["tabs" ][tab_name ] else default
109+
87110 self .tabs_content [tab_name ] = {"main" : QtWidgets .QWidget (), "widgets" : {}}
88111 self .tabs_content [tab_name ]["main" ].layout = QtWidgets .QVBoxLayout (self )
89- self .tabs_content [tab_name ]["widgets" ]["epsilon" ] = Slider ("Epsilon" , 200 , 50 )
112+ self .tabs_content [tab_name ]["widgets" ]["epsilon" ] = Slider ("Epsilon" , 200 , previous_or_default ( "epsilon" , 50 ) )
90113 self .tabs_content [tab_name ]["main" ].layout .addWidget (self .tabs_content [tab_name ]["widgets" ]["epsilon" ])
91114 self .tabs_content [tab_name ]["widgets" ]["epsilon" ].slider .valueChanged .connect (self .update_plot )
92115 self .tabs_content [tab_name ]["main" ].setLayout (self .tabs_content [tab_name ]["main" ].layout )
@@ -95,44 +118,60 @@ def add_vw_tab(self):
95118
96119 def add_custom_tab (self ):
97120 tab_name = "Custom"
121+
122+ if tab_name not in self .prev_ui_settings ["tabs" ]:
123+ self .prev_ui_settings ["tabs" ][tab_name ] = {}
124+
125+ previous_or_default = lambda name , default : \
126+ self .prev_ui_settings ["tabs" ][tab_name ][name ] if name in self .prev_ui_settings ["tabs" ][tab_name ] else default
127+
98128 self .tabs_content [tab_name ] = {"main" : QtWidgets .QWidget (), "widgets" : {}}
99129 self .tabs_content [tab_name ]["main" ].layout = QtWidgets .QVBoxLayout (self )
100130
101131 self .tabs_content [tab_name ]["widgets" ]["points" ] = QtWidgets .QComboBox ()
102132 self .tabs_content [tab_name ]["widgets" ]["points" ].addItems (["Local Min Max" , "Direction Changed" ])
133+
134+ if "points" in self .prev_ui_settings ["tabs" ][tab_name ]:
135+ index = self .tabs_content [tab_name ]["widgets" ]["points" ].findText (str (self .prev_ui_settings ["tabs" ][tab_name ]["points" ]), QtCore .Qt .MatchFixedString )
136+ if index >= 0 :
137+ self .tabs_content [tab_name ]["widgets" ]["points" ].setCurrentIndex (index )
138+
103139 self .tabs_content [tab_name ]["widgets" ]["points" ].currentIndexChanged .connect (self .update_plot )
104140
105- self .tabs_content [tab_name ]["widgets" ]["filterLen" ] = Slider ("Filter Len" , 10 , 2 )
141+ self .tabs_content [tab_name ]["widgets" ]["filterLen" ] = Slider ("Filter Len" , 10 , previous_or_default ( "filterLen" , 2 ) )
106142 self .tabs_content [tab_name ]["widgets" ]["filterLen" ].slider .sliderReleased .connect (self .update_plot )
107143
108144 self .tabs_content [tab_name ]["widgets" ]["high_second_derivate" ] = QtWidgets .QCheckBox ("High Second Derivate" )
145+ self .tabs_content [tab_name ]["widgets" ]["high_second_derivate" ].setChecked (previous_or_default ("high_second_derivate" , False ))
109146 self .tabs_content [tab_name ]["widgets" ]["high_second_derivate" ].stateChanged .connect (self .update_plot )
110147
111148 self .tabs_content [tab_name ]["widgets" ]["distance_minimization" ] = QtWidgets .QCheckBox ("Distance Minimization" )
149+ self .tabs_content [tab_name ]["widgets" ]["distance_minimization" ].setChecked (previous_or_default ("distance_minimization" , False ))
112150 self .tabs_content [tab_name ]["widgets" ]["distance_minimization" ].stateChanged .connect (self .update_plot )
113151
114152 self .tabs_content [tab_name ]["widgets" ]["evenly_intermediate" ] = QtWidgets .QCheckBox ("Evenly Intermediate" )
153+ self .tabs_content [tab_name ]["widgets" ]["evenly_intermediate" ].setChecked (previous_or_default ("evenly_intermediate" , False ))
115154 self .tabs_content [tab_name ]["widgets" ]["evenly_intermediate" ].stateChanged .connect (self .update_plot )
116155
117- self .tabs_content [tab_name ]["widgets" ]["runs" ] = Slider ("Max Iterations" , 8 , 2 )
156+ self .tabs_content [tab_name ]["widgets" ]["runs" ] = Slider ("Max Iterations" , 8 , previous_or_default ( "runs" , 2 ) )
118157 self .tabs_content [tab_name ]["widgets" ]["runs" ].slider .sliderReleased .connect (self .update_plot )
119158
120- self .tabs_content [tab_name ]["widgets" ]["mergeThresholdMs" ] = Slider ("Merge Threshold Time in ms" , 1000 , 60 )
159+ self .tabs_content [tab_name ]["widgets" ]["mergeThresholdMs" ] = Slider ("Merge Threshold Time in ms" , 1000 , previous_or_default ( "mergeThresholdMs" , 60 ) )
121160 self .tabs_content [tab_name ]["widgets" ]["mergeThresholdMs" ].slider .sliderReleased .connect (self .update_plot )
122161
123- self .tabs_content [tab_name ]["widgets" ]["mergeThresholdDistance" ] = Slider ("Merge Threshold Distance" , 100 , 8 )
162+ self .tabs_content [tab_name ]["widgets" ]["mergeThresholdDistance" ] = Slider ("Merge Threshold Distance" , 100 , previous_or_default ( "mergeThresholdDistance" , 8 ) )
124163 self .tabs_content [tab_name ]["widgets" ]["mergeThresholdDistance" ].slider .sliderReleased .connect (self .update_plot )
125164
126- self .tabs_content [tab_name ]["widgets" ]["highSecondDerivateThreshold" ] = Slider ("Threshold" , 100 , 12 )
165+ self .tabs_content [tab_name ]["widgets" ]["highSecondDerivateThreshold" ] = Slider ("Threshold" , 100 , previous_or_default ( "highSecondDerivateThreshold" , 12 ) )
127166 self .tabs_content [tab_name ]["widgets" ]["highSecondDerivateThreshold" ].slider .sliderReleased .connect (self .update_plot )
128167
129- self .tabs_content [tab_name ]["widgets" ]["distanzMinimizationThreshold" ] = Slider ("Threshold" , 100 , 12 )
168+ self .tabs_content [tab_name ]["widgets" ]["distanzMinimizationThreshold" ] = Slider ("Threshold" , 100 , previous_or_default ( "distanzMinimizationThreshold" , 12 ) )
130169 self .tabs_content [tab_name ]["widgets" ]["distanzMinimizationThreshold" ].slider .sliderReleased .connect (self .update_plot )
131170
132- self .tabs_content [tab_name ]["widgets" ]["lower" ] = Slider ("Lower Offset" , 100 , 0 )
171+ self .tabs_content [tab_name ]["widgets" ]["lower" ] = Slider ("Lower Offset" , 100 , previous_or_default ( "lower" , 0 ) )
133172 self .tabs_content [tab_name ]["widgets" ]["lower" ].slider .sliderReleased .connect (self .update_plot )
134173
135- self .tabs_content [tab_name ]["widgets" ]["upper" ] = Slider ("Upper Offset" , 100 , 0 )
174+ self .tabs_content [tab_name ]["widgets" ]["upper" ] = Slider ("Upper Offset" , 100 , previous_or_default ( "upper" , 0 ) )
136175 self .tabs_content [tab_name ]["widgets" ]["upper" ].slider .sliderReleased .connect (self .update_plot )
137176
138177 self .tabs_content [tab_name ]["main" ].layout .addWidget (QtWidgets .QLabel ("Points:" ))
@@ -159,6 +198,43 @@ def add_custom_tab(self):
159198 self .tabs_content [tab_name ]["main" ].setLayout (self .tabs_content [tab_name ]["main" ].layout )
160199 self .tabs .addTab (self .tabs_content [tab_name ]["main" ], tab_name )
161200
201+ def load_prev_ui_settings (self ):
202+ if not os .path .exists (self .ui_settings_file ):
203+ self .prev_ui_settings = {}
204+ else :
205+ with open (self .ui_settings_file , "r" ) as f :
206+ self .prev_ui_settings = json .load (f )
207+
208+ if "selected" not in self .prev_ui_settings :
209+ self .prev_ui_settings ["selected" ] = ""
210+
211+ if "tabs" not in self .prev_ui_settings :
212+ self .prev_ui_settings ["tabs" ] = {}
213+
214+
215+ def save_ui_settings (self ):
216+ settings = {
217+ "selected" : self .get_current_tab_name (),
218+ "tabs" : {}
219+ }
220+ for tab_name in self .tabs_content :
221+ settings ["tabs" ][tab_name ] = {}
222+ for widget in self .tabs_content [tab_name ]["widgets" ]:
223+ if isinstance (self .tabs_content [tab_name ]["widgets" ][widget ], Slider ):
224+ settings ["tabs" ][tab_name ][widget ] = self .tabs_content [tab_name ]["widgets" ][widget ].slider .value ()
225+ elif isinstance (self .tabs_content [tab_name ]["widgets" ][widget ], QtWidgets .QCheckBox ):
226+ settings ["tabs" ][tab_name ][widget ] = self .tabs_content [tab_name ]["widgets" ][widget ].isChecked ()
227+ elif isinstance (self .tabs_content [tab_name ]["widgets" ][widget ], QtWidgets .QComboBox ):
228+ settings ["tabs" ][tab_name ][widget ] = self .tabs_content [tab_name ]["widgets" ][widget ].currentText ()
229+ else :
230+ print ("ERROR: widget" , widget , "not implemented" )
231+
232+ try :
233+ with open (self .ui_settings_file , "w" ) as f :
234+ json .dump (settings , f )
235+ except :
236+ print ("Warning: failed to save post processing settings" )
237+
162238 def add_auto_tab (self ):
163239 tab_name = "Developer"
164240 self .tabs_content [tab_name ] = {"main" : QtWidgets .QWidget (), "widgets" : {}}
@@ -180,6 +256,7 @@ def closeEvent(self, event):
180256
181257 def confirm (self ):
182258 self .close_with_ok = True
259+ self .save_ui_settings ()
183260 self .hide ()
184261 self .postprocessingCompleted .emit (self .metric , self .result_idx , self .result_val )
185262 self .close ()
0 commit comments