From 63dfaf1a6d9383374c7092ad9994384740cca78d Mon Sep 17 00:00:00 2001 From: will wade Date: Sun, 21 Jun 2026 07:58:59 +0100 Subject: [PATCH] Fix circle start clicks, BP_STOP_OUTSIDE, control box colours Three fixes from Steve Saling feedback: 1. Circle start: clicking outside the circle no longer starts/stops Dasher. dasher_mouse_down now checks LP_START_MODE and returns early in circle_start mode. 2. BP_STOP_OUTSIDE: pointer leave detection now works. Removed coordinate clamping in PointerInput::SetPosition so out-of-bounds positions reach the DefaultFilter. IsPointVisible now checks actual screen bounds instead of always returning true. 3. Control box colours: custom control XML with arbitrary colour indices now gets distinct, readable colours via a 12-colour cycle instead of everything falling to the same default purple-blue. Signed-off-by: will wade --- src/CAPI.cpp | 15 ++++++++++++--- src/DasherCore/ControlManager.cpp | 23 +++++++++++++++++++++-- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/CAPI.cpp b/src/CAPI.cpp index 52d0a278..d4ae78cf 100644 --- a/src/CAPI.cpp +++ b/src/CAPI.cpp @@ -267,7 +267,9 @@ class CommandScreen final : public Dasher::CDasherScreen { } void Display() override {} - bool IsPointVisible(Dasher::screenint, Dasher::screenint) override { return true; } + bool IsPointVisible(Dasher::screenint x, Dasher::screenint y) override { + return x >= 0 && y >= 0 && x < GetWidth() && y < GetHeight(); + } private: void push(int op, int a, int b, int c, int d, int32_t colour) { @@ -301,8 +303,10 @@ class PointerInput : public Dasher::CScreenCoordInput { void SetPosition(float x, float y) { m_hasPos = true; - m_x = clamp_int(lround_int(static_cast(x)), 0, m_width - 1); - m_y = clamp_int(lround_int(static_cast(y)), 0, m_height - 1); + // Don't clamp — allow out-of-bounds coordinates so BP_STOP_OUTSIDE + // can detect when the pointer leaves the canvas area. + m_x = lround_int(static_cast(x)); + m_y = lround_int(static_cast(y)); } bool GetScreenCoords(Dasher::screenint& iX, Dasher::screenint& iY, Dasher::CDasherView*) override { @@ -731,6 +735,11 @@ DASHER_API void dasher_mouse_down(dasher_ctx* ctx) { if (!ctx || !ctx->intf) return; if (ctx->mouseDown) return; ctx->mouseDown = true; + + // In circle start mode, clicking should NOT start/stop Dasher — + // only hovering inside the circle should. (Steve Saling feedback) + if (ctx->intf->GetLongParameter(Dasher::LP_START_MODE) == Dasher::Options::StartMode::circle_start) return; + ctx->intf->SetBoolParameter(Dasher::BP_START_MOUSE, true); ctx->intf->KeyDown(nowMs(), Dasher::Keys::Primary_Input); } diff --git a/src/DasherCore/ControlManager.cpp b/src/DasherCore/ControlManager.cpp index 63962696..0bf3e8e4 100644 --- a/src/DasherCore/ControlManager.cpp +++ b/src/DasherCore/ControlManager.cpp @@ -123,11 +123,11 @@ const ColorPalette::Color& CContNode::getNodeColor(const ColorPalette*) { // ── Colour mapping ───────────────────────────────────────────────────────── const ColorPalette::Color& CControlManager::indexToColor(int iIndex) { + // Semantic colors matching the default control.xml static const ColorPalette::Color controlGrey(128, 128, 128); static const ColorPalette::Color controlGreen(60, 180, 75); static const ColorPalette::Color controlAmber(220, 160, 0); static const ColorPalette::Color controlRed(200, 50, 50); - static const ColorPalette::Color controlDefault(90, 90, 140); switch (iIndex) { case 8: @@ -139,8 +139,27 @@ const ColorPalette::Color& CControlManager::indexToColor(int iIndex) { case 242: return controlRed; default: - return controlDefault; + break; } + + // For custom control XML with arbitrary color indices (e.g. v5 imports), + // cycle through a palette of distinct, readable colors. This approximates + // v5's behavior of looking up palette indices. + static const ColorPalette::Color cyclePalette[] = { + ColorPalette::Color(60, 140, 200), // blue + ColorPalette::Color(80, 170, 100), // green + ColorPalette::Color(200, 120, 50), // orange + ColorPalette::Color(160, 80, 180), // purple + ColorPalette::Color(50, 160, 180), // teal + ColorPalette::Color(220, 140, 60), // amber + ColorPalette::Color(180, 60, 100), // pink + ColorPalette::Color(100, 100, 110), // grey + ColorPalette::Color(90, 130, 50), // olive + ColorPalette::Color(140, 90, 200), // violet + ColorPalette::Color(200, 80, 80), // coral + ColorPalette::Color(50, 130, 210), // sky + }; + return cyclePalette[iIndex % 12]; } // ── Built-in action implementations ────────────────────────────────────────