L5: dock-panel button refinements — overflow menu, tooltips, opposite-mode tag buttons

Top-bar rare-capture variants move to a right-anchored More popup; short faces gain
hover-delay full-name tooltips (prefix stripped); bottom bar becomes four opposite-mode
Item/Track tag buttons + Show Both (Toggle/Activates dropped); wider cluster gaps. New
pure overflow_menu/mode_enable/tooltip modules, CTest-covered. Same actions, same contract.
This commit is contained in:
2026-07-26 23:56:49 -04:00
parent 0c7b871d8d
commit 7cd0771e45
11 changed files with 1025 additions and 53 deletions
+64
View File
@@ -0,0 +1,64 @@
// Standalone tests for reasampler::mode_enable — no REAPER, no test framework. Asserts the
// opposite-mode tag-button enablement predicate for BOTH active modes (the acceptance criterion:
// covered for both, not only whichever a DAW pass sat in).
//
// The rule (L5 refinement 3): a tag button whose target is `t` is LIVE iff `t` != the active
// mode — you tag INTO the mode you are not currently in. When Design is active, "…: Arrange"
// buttons are live and "…: Design" buttons are dead; when Arrange is active, the reverse. An
// unrecognized active id fails OPEN (every button live) so a future mode never dead-locks the bar.
#include "../src/mode_enable.h"
#include "../src/view_mode_model.h" // kArrangeModeId / kDesignModeId — the ids the rule keys off
#include <cstdio>
#include <string>
using namespace reasampler;
static int g_fail = 0;
#define CHECK(cond) do { if(!(cond)) { \
std::printf("FAIL line %d: %s\n", __LINE__, #cond); ++g_fail; } } while(0)
// When ARRANGE is active: only the Design-target buttons are live (tag into Design); the
// Arrange-target buttons are dead (already in Arrange — nothing to do).
static void testArrangeActive() {
const std::string active = kArrangeModeId;
CHECK(!tagButtonEnabled(active, TagTarget::Arrange)); // dead — already active mode
CHECK(tagButtonEnabled(active, TagTarget::Design)); // live — opposite mode
}
// When DESIGN is active: the reverse — only the Arrange-target buttons are live.
static void testDesignActive() {
const std::string active = kDesignModeId;
CHECK(tagButtonEnabled(active, TagTarget::Arrange)); // live — opposite mode
CHECK(!tagButtonEnabled(active, TagTarget::Design)); // dead — already active mode
}
// Exactly one of the two targets is live in each mode (the buttons are complementary — a real
// pair, never both-live or both-dead). This is the invariant the disabled/enabled visuals rely on.
static void testExactlyOneTargetLivePerMode() {
CHECK(tagButtonEnabled(kArrangeModeId, TagTarget::Arrange) !=
tagButtonEnabled(kArrangeModeId, TagTarget::Design));
CHECK(tagButtonEnabled(kDesignModeId, TagTarget::Arrange) !=
tagButtonEnabled(kDesignModeId, TagTarget::Design));
}
// An unrecognized active id (neither seed mode — e.g. empty when no session, or a future mode)
// fails OPEN: every button live, so the user can always reach the action.
static void testUnknownActiveFailsOpen() {
CHECK(tagButtonEnabled("", TagTarget::Arrange));
CHECK(tagButtonEnabled("", TagTarget::Design));
CHECK(tagButtonEnabled("some-future-mode", TagTarget::Arrange));
CHECK(tagButtonEnabled("some-future-mode", TagTarget::Design));
}
int main() {
testArrangeActive();
testDesignActive();
testExactlyOneTargetLivePerMode();
testUnknownActiveFailsOpen();
if (g_fail == 0) std::printf("mode_enable: all tests passed\n");
else std::printf("mode_enable: %d CHECK(s) FAILED\n", g_fail);
return g_fail == 0 ? 0 : 1;
}