nlve/tests/pickcycle.sh
4aiman ffd105a8c0 Щелчок в месте наезда перебирает клипы
Наезд двух клипов на одной дорожке — заказ на переход, то есть обычное
дело. Нажатие же всегда попадало в верхний по списку, и нижний клип
нельзя было ни выделить, ни потащить: чтобы до него добраться,
приходилось сперва убирать верхний.

Правило такое. Нажатие берёт тот из накрытых клипов, который уже выделен,
иначе верхний. Щелчок без движения по уже выделенному переводит выделение
на следующий, после последнего снова на верхний. Переключение сделано на
отпускании намеренно: пока кнопку не отпустили, неизвестно, щелчок это
или начало протяжки, а менять клип под рукой посреди протяжки нельзя.
Благодаря этому протяжка тащит именно то, что перед ней выбрали
щелчками.

Строка состояния говорит, сколько клипов под указателем: перебор, о
котором не сказали, — тайное знание.

Отбор вынесен в TTrack.ClipsAt, числовая проверка — в lfmcheck.
tests/pickcycle.sh щёлкает дважды и тащит: на прежней сборке уезжает
верхний клип, а нижний едет за ним схлопыванием.
2026-10-16 15:43:01 +03:00

141 lines
5.9 KiB
Bash
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
# Повторный щелчок в месте наезда берёт следующий клип.
#
# Наезд двух клипов на одной дорожке — это заказ на переход, то есть
# обычное дело. Щелчок же всегда попадал в один и тот же клип, верхний по
# списку, и до нижнего было не добраться: ни выделить, ни потащить. Чтобы
# взять его, приходилось сначала убирать верхний.
#
# Проверяется так: два клипа внахлёст, щелчок по месту наезда, второй
# щелчок туда же, затем протяжка. Уехать обязан ВТОРОЙ клип. Выделение в
# файл проекта не пишется, а позиция пишется, поэтому смотрим по ней.
#
# Запуск (экран :99 поднят):
# tests/pickcycle.sh [<путь к nlve>]
set -e
cd "$(dirname "$0")/.."
BIN=${1:-$PWD/nlve}
DISP=${NLVE_DISPLAY:-:99}
SRC=$PWD/test/поток/пара.nlve
PROJ=$PWD/test/поток/перебор.nlve
[ -f "$SRC" ] || { echo "нет монтажа $SRC"; exit 2; }
export DISPLAY=$DISP
reachable() { timeout 5 xdotool getdisplaygeometry >/dev/null 2>&1; }
if ! reachable; then
for p in $(pgrep -x Xvfb); do
A=$(tr '\0' '\n' < /proc/$p/cmdline | grep -A1 -x -- -auth | tail -1)
[ -f "$A" ] || continue
XAUTHORITY=$A; export XAUTHORITY
reachable && break
done
fi
reachable ||
{ echo "нет доступа к экрану $DISP: подними его (xvfb-run) и повтори"; exit 2; }
# Два клипа внахлёст: 0..10 и 8..18. Наезд с 8 по 10.
python3 - "$SRC" "$PROJ" <<'PY'
import json, sys, copy
d = json.load(open(sys.argv[1]))
V = next(t for t in d['tracks'] if t['name'] == 'V1')
A = next(t for t in d['tracks'] if t['name'] == 'A1')
ов, оа = copy.deepcopy(V['clips'][0]), copy.deepcopy(A['clips'][0])
def клип(обр, ид, группа, старт, длина, вход):
c = copy.deepcopy(обр)
c.update(id=ид, group=группа, tl_start=старт, duration=длина,
src_in=вход, fade_in=0.0, fade_out=0.0)
return c
V['clips'] = [клип(ов, 'a_v', 'ga', 0.0, 10.0, 100.0),
клип(ов, 'b_v', 'gb', 8.0, 10.0, 200.0)]
A['clips'] = [клип(оа, 'a_a', 'ga', 0.0, 10.0, 100.0),
клип(оа, 'b_a', 'gb', 8.0, 10.0, 200.0)]
json.dump(d, open(sys.argv[2], 'w'), ensure_ascii=False)
print(' клипы 0..10 и 8..18, наезд с 8 по 10')
PY
for p in $(pgrep -x nlve); do
tr '\0' '\n' < /proc/$p/environ 2>/dev/null | grep -qx "DISPLAY=$DISP" && kill $p
done
sleep 1
SP=$PWD/test/поток/профиль-перебор
rm -rf "$SP"; mkdir -p "$SP"
rm -rf "$PROJ-cache"
rm -f "$PROJ.autosave"
XDG_CONFIG_HOME=$SP XDG_CACHE_HOME=$SP XDG_DATA_HOME=$SP \
setsid "$BIN" "$PROJ" >/dev/null 2>&1 < /dev/null &
sleep 14
X="timeout 8 xdotool"
WID=
for w in $($X search --name "перебор.nlve" 2>/dev/null); do
xwininfo -id "$w" 2>/dev/null | grep -q IsViewable && { WID=$w; break; }
done
[ -n "$WID" ] || { echo "живое окно редактора не найдено"; exit 2; }
$X windowmove "$WID" 0 0 windowsize "$WID" 1270 990
sleep 2
ROW=${NLVE_ROW:-505}
starts() {
$X key ctrl+s
sleep 2
python3 -c "
import json
d = json.load(open('$PROJ'))
for t in d['tracks']:
if t['name'] != 'V1': continue
print(' '.join('%s=%.3f' % (c['id'], c['tl_start'])
for c in sorted(t['clips'], key=lambda c: c['id'])))
"
}
echo " до правок: $(starts)"
# Место наезда: середина отрезка 8..10 с. Замерено по линейке в окне
# 1270x990 на этом монтаже: ноль в точке 592, в секунде 56.3 точки.
PX=${NLVE_PX:-1098}
# Первый щелчок берёт верхний, второй — переводит выделение на нижний.
# Мышь между щелчками не двигаем.
$X mousemove "$PX" "$ROW" click 1; sleep 1
$X click 1; sleep 1
# Теперь тащим выбранный клип вправо на заметную величину. Нажатие берёт
# именно выделенный — иначе протяжкой нельзя было бы взять то, что
# только что выбрали щелчками.
$X mousedown 1; sleep 0.3
$X mousemove $((PX + 60)) "$ROW"; sleep 0.3
$X mousemove $((PX + 120)) "$ROW"; sleep 0.4
$X mouseup 1; sleep 1.5
AFTER=$(starts)
echo " после второго щелчка и протяжки: $AFTER"
for p in $(pgrep -x nlve); do
tr '\0' '\n' < /proc/$p/environ 2>/dev/null | grep -qx "DISPLAY=$DISP" && kill $p
done
rm -f "$PROJ.autosave"
python3 - "$PROJ" <<'PY'
import json, sys
d = json.load(open(sys.argv[1]))
V = next(t for t in d['tracks'] if t['name'] == 'V1')
старт = {c['id']: c['tl_start'] for c in V['clips']}
a, b = старт['a_v'], старт['b_v']
# Верхний обязан стоять там, где стоял. Если уехал он — значит второй
# щелчок не переключил, потащили верхний, а нижний уехал следом за ним
# схлопыванием, и выглядит это обманчиво похоже на успех.
if abs(a - 0.0) > 0.05:
print(' ПЛОХО: второй щелчок не переключил — потащили верхний '
'(a_v: 0.000 -> %.3f, b_v: 8.000 -> %.3f)' % (a, b))
raise SystemExit(1)
if abs(b - 8.0) <= 0.05:
print(' ПЛОХО: никто никуда не уехал — проверка ничего не значит')
raise SystemExit(1)
print(' ok: потащили нижний клип (b_v: 8.000 -> %.3f), верхний на месте'
% b)
PY