Clear stale hover on capture-loss and Alt-delete; derive gutter test via chromeRects
This commit is contained in:
+1
-1
@@ -1034,7 +1034,7 @@ target_link_libraries(capture_browser_tests PRIVATE capture_browser)
|
|||||||
add_test(NAME capture_browser_tests COMMAND capture_browser_tests)
|
add_test(NAME capture_browser_tests COMMAND capture_browser_tests)
|
||||||
|
|
||||||
add_executable(keyboard_strip_tests tests/test_keyboard_strip.cpp)
|
add_executable(keyboard_strip_tests tests/test_keyboard_strip.cpp)
|
||||||
target_link_libraries(keyboard_strip_tests PRIVATE keyboard_strip sample_bands)
|
target_link_libraries(keyboard_strip_tests PRIVATE keyboard_strip sample_bands sample_chrome)
|
||||||
add_test(NAME keyboard_strip_tests COMMAND keyboard_strip_tests)
|
add_test(NAME keyboard_strip_tests COMMAND keyboard_strip_tests)
|
||||||
|
|
||||||
# waveform_view (S11): the pure marker geometry + zero-crossing snap. Links waveform_view (+
|
# waveform_view (S11): the pure marker geometry + zero-crossing snap. Links waveform_view (+
|
||||||
|
|||||||
@@ -82,7 +82,10 @@ void ReaSamplerEditor::onMouseUp(int x, int y) {
|
|||||||
// hover_ is deliberately not re-resolved during a drag (see resolveHover's caller), so it
|
// hover_ is deliberately not re-resolved during a drag (see resolveHover's caller), so it
|
||||||
// still names wherever the drag started. Re-resolve now against the release position, for
|
// still names wherever the drag started. Re-resolve now against the release position, for
|
||||||
// every drag kind — otherwise the next paint latches a stale hover (wrong note name/tooltip,
|
// every drag kind — otherwise the next paint latches a stale hover (wrong note name/tooltip,
|
||||||
// wrong control outline) until the next WM_MOUSEMOVE.
|
// wrong control outline) until the next WM_MOUSEMOVE. This resolve runs before the release
|
||||||
|
// branches below can delete or relocate the hovered element; a future branch that does so
|
||||||
|
// must clear hover_ itself afterwards (as the curve drag-off delete does below) rather than
|
||||||
|
// rely on this resolve, which reflects pre-mutation state.
|
||||||
resolveHover(x, y);
|
resolveHover(x, y);
|
||||||
// A scrollbar drag is transient UI (no parameter change), and the processor-side knobs
|
// A scrollbar drag is transient UI (no parameter change), and the processor-side knobs
|
||||||
// (the preview-velocity -2 sentinel, voice count, master gain) are per-instance settings
|
// (the preview-velocity -2 sentinel, voice count, master gain) are per-instance settings
|
||||||
|
|||||||
@@ -47,7 +47,10 @@ void ReaSamplerEditor::handleCurveMouseDown(const Rect& r, int x, int y) {
|
|||||||
// Modifier-click (Alt) deletes an interior node — a discrete, final edit committed at once
|
// Modifier-click (Alt) deletes an interior node — a discrete, final edit committed at once
|
||||||
// (deletePoint refuses the two endpoints, so an Alt-click on them is a safe no-op).
|
// (deletePoint refuses the two endpoints, so an Alt-click on them is a safe no-op).
|
||||||
if (idx >= 0 && (GetKeyState(VK_MENU) & 0x8000) != 0) {
|
if (idx >= 0 && (GetKeyState(VK_MENU) & 0x8000) != 0) {
|
||||||
if (params_.velocityCurve.deletePoint(static_cast<std::size_t>(idx))) commitAndReload();
|
if (params_.velocityCurve.deletePoint(static_cast<std::size_t>(idx))) {
|
||||||
|
hover_ = HoverTarget{}; // a stale kCurveNode index would light a shifted node
|
||||||
|
commitAndReload();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -231,6 +231,10 @@ LRESULT CALLBACK ReaSamplerEditor::wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||||||
self->drag_ = DragKind::kNone;
|
self->drag_ = DragKind::kNone;
|
||||||
self->dragParamId_ = -1;
|
self->dragParamId_ = -1;
|
||||||
self->curvePointIndex_ = -1; // curve-node drag state (peer reset)
|
self->curvePointIndex_ = -1; // curve-node drag state (peer reset)
|
||||||
|
// No cursor position is available here to re-resolve hover (unlike
|
||||||
|
// onMouseUp's release coordinates), so clear rather than leave it naming
|
||||||
|
// wherever the drag started.
|
||||||
|
self->hover_ = HoverTarget{};
|
||||||
self->invalidate();
|
self->invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,11 @@
|
|||||||
// unverified by this suite (see src/core/instrument/CLAUDE.md).
|
// unverified by this suite (see src/core/instrument/CLAUDE.md).
|
||||||
|
|
||||||
#include "../src/core/instrument/ui/keyboard_strip.h"
|
#include "../src/core/instrument/ui/keyboard_strip.h"
|
||||||
#include "../src/core/instrument/ui/sample_bands.h" // kPad, to derive the strip width the
|
#include "../src/core/instrument/ui/sample_bands.h" // computeSampleBands, to derive the CHROME
|
||||||
// shipped default window (840x620,
|
// band the shipped default window (840x620,
|
||||||
// editor_session.cpp) hands the strip
|
// editor_session.cpp) hands the strip
|
||||||
|
#include "../src/core/instrument/ui/sample_chrome.h" // chromeRects, to derive rootStrip's width
|
||||||
|
// the same way the shell does
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -288,8 +290,15 @@ static void testNoteNamesFollowTheC4Convention() {
|
|||||||
// one pixel of resize (840->841) collapses both gutters to zero and grows every white key
|
// one pixel of resize (840->841) collapses both gutters to zero and grows every white key
|
||||||
// from 10px to 11px.
|
// from 10px to 11px.
|
||||||
static void testGutterAtTheShippedDefaultWindowSize() {
|
static void testGutterAtTheShippedDefaultWindowSize() {
|
||||||
constexpr int kShippedDefaultWindowW = 840; // editor_session.cpp's ViewRect default
|
constexpr int kShippedDefaultWindowW = 840; // editor_session.cpp's ViewRect default
|
||||||
const int stripW = kShippedDefaultWindowW - 2 * kPad; // chromeRects insets rootStrip by kPad
|
constexpr int kShippedDefaultWindowH = 620; // editor_session.cpp's ViewRect default
|
||||||
|
// Derive rootStrip's width the same way the shell does, through the real allocator +
|
||||||
|
// chrome layout, rather than re-deriving the inset formula — so a change to either one
|
||||||
|
// fails this test instead of silently moving the shipped gutter out from under it.
|
||||||
|
const SampleBands bands =
|
||||||
|
computeSampleBands(kShippedDefaultWindowW, kShippedDefaultWindowH, 0);
|
||||||
|
const ChromeRects chrome = chromeRects(bands.chrome, /*knobSize=*/24);
|
||||||
|
const int stripW = chrome.rootStrip.width;
|
||||||
CHECK(stripW == 824);
|
CHECK(stripW == 824);
|
||||||
|
|
||||||
const StripLayout L = layoutStrip(stripW, 30);
|
const StripLayout L = layoutStrip(stripW, 30);
|
||||||
|
|||||||
Reference in New Issue
Block a user