Files
SonicForgeStudio/tools/patch_tcp_wheel.py
T
admin 8874e42596 fix(tcp): move vol/pan ruler wheel+dblclick handler to whole row
Scroll wheel giảm/tăng volume chỉ hoạt động trên input 4px; chuyển
onWheel+onDoubleClick lên row div (label+dB span cũng ăn), giữ bubbling
từ input. Áp dụng cho main TCP và sub-tab, cả app.jsx và precompiled.
2026-08-19 12:29:11 +07:00

100 lines
5.5 KiB
Python

# Patch TCP vol/pan: move onWheel+onDoubleClick from 4px input to whole row div
# Áp dụng cho app.jsx (formatted, CRLF) và app.precompiled.js (minified)
# Cách làm: (1) xóa wheel handlers khỏi input, (2) chèn chúng vào props của row div.
# Row vol mở đầu "}, " (con đầu flex-col), row pan mở đầu "), " (con thứ hai).
import io
def patch_file(path, spots):
with io.open(path, 'r', encoding='utf-8', newline='') as f:
s = f.read()
for i, spot in enumerate(spots):
anchor = spot['anchor']
n = s.count(anchor)
assert n == 1, f"{path}: anchor count {n} for {anchor[:60]}"
p_anchor = s.index(anchor)
p_wheel = s.rfind(spot['wheel_marker'], 0, p_anchor + len(anchor) + 1)
assert p_wheel != -1, f"{path}: wheel_marker not found for {anchor[:40]}"
p_class = s.index(spot['class_marker'], p_wheel)
wheel_props = s[p_wheel:p_class].rstrip()
# (1) xóa handlers khỏi input (giữ dấu phẩy trước className)
del_start = p_wheel - spot['pre_wheel']
del_end = p_class - spot['pre_class']
s = s[:del_start] + s[del_end:]
# (2) chèn handlers vào props row div
p_row = s.rfind(spot['row_open'], 0, del_start)
assert p_row != -1, f"{path}: row_open not found for spot {i} ({anchor[:40]})"
p_insert = spot['insert_pos'](s, p_row)
s = s[:p_insert] + spot['insert_prefix'] + wheel_props + s[p_insert:]
with io.open(path, 'w', encoding='utf-8', newline='') as f:
f.write(s)
print(f"patched {path}")
def spots_formatted():
NL = '\r\n'
def row_open(pre):
return (pre + '/*#__PURE__*/React.createElement("div", {' + NL +
' className: "flex items-center gap-1"' + NL +
' }, /*#__PURE__*/React.createElement("span", {')
def spot(anchor, class_marker, pre):
return dict(
anchor=anchor,
wheel_marker='onWheel: e => {',
class_marker=class_marker,
pre_wheel=10, # '\r\n' + 8 spaces trước onWheel (bỏ dấu phẩy trước nó? KHÔNG: giữ phẩy sau onChange)
pre_class=10, # '\r\n' + 8 spaces trước className (xóa cả phẩy sau onDoubleClick)
row_open=row_open(pre),
insert_pos=lambda s, p_row: s.index('className: "flex items-center gap-1"', p_row) + len('className: "flex items-center gap-1"'),
insert_prefix=',\r\n ',
)
return [
spot("wheelSteps('vol:' + track.id,",
'className: "flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-cyan-500"',
'}, '),
spot("wheelSteps('pan:' + track.id,",
'className: "flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-purple-500"',
'), '),
spot("wheelSteps('vol:' + vTrack.id,",
'className: "flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-cyan-500"',
'}, '),
spot("wheelSteps('pan:' + vTrack.id,",
'className: "flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-purple-500"',
'), '),
]
def spots_minified():
def spot(anchor, wheel_marker, class_marker, row_open):
return dict(
anchor=anchor,
wheel_marker=wheel_marker,
class_marker=class_marker,
pre_wheel=1, # ',' trước onWheel
pre_class=1, # ',' trước className
row_open=row_open,
insert_pos=lambda s, p_row: s.index('},/*#__PURE__*/React.createElement("span",{', p_row),
insert_prefix=',',
)
return [
spot("wheelSteps('vol:'+track.id",
"onWheel:e=>{e.preventDefault();const steps=wheelSteps('vol:'+track.id",
'className:"flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-cyan-500"',
'React.createElement("div",{className:"flex items-center gap-1"},/*#__PURE__*/React.createElement("span",{className:"w-8 text-right text-zinc-500 text-xs"},"Vol:"),'),
spot("wheelSteps('pan:'+track.id",
"onWheel:e=>{e.preventDefault();const steps=wheelSteps('pan:'+track.id",
'className:"flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-purple-500"',
'React.createElement("div",{className:"flex items-center gap-1"},/*#__PURE__*/React.createElement("span",{className:"w-8 text-right text-zinc-500 text-xs"},"Pan:"),'),
spot("wheelSteps('vol:'+vTrack.id",
"onWheel:e=>{e.preventDefault();const steps=wheelSteps('vol:'+vTrack.id",
'className:"flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-cyan-500"',
'React.createElement("div",{className:"flex items-center gap-1"},/*#__PURE__*/React.createElement("span",{className:"w-10 text-right text-zinc-500 text-[14px]"},"Vol:"),'),
spot("wheelSteps('pan:'+vTrack.id",
"onWheel:e=>{e.preventDefault();const steps=wheelSteps('pan:'+vTrack.id",
'className:"flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-purple-500"',
'React.createElement("div",{className:"flex items-center gap-1"},/*#__PURE__*/React.createElement("span",{className:"w-10 text-right text-zinc-500 text-[14px]"},"Pan:"),'),
]
if __name__ == '__main__':
patch_file('app/static/js/app.jsx', spots_formatted())
patch_file('app/static/js/app.precompiled.js', spots_minified())