Files
whetstone_DSL/editor/src/CompletionOverlayUXHardening.h

103 lines
3.1 KiB
C++

#pragma once
// Step 520: Completion Overlay UX Hardening
#include <string>
#include <algorithm>
struct OverlayRect {
float x = 0.0f;
float y = 0.0f;
float w = 0.0f;
float h = 0.0f;
};
struct CompletionOverlayState {
bool visible = false;
bool dismissed = false;
int selectedIndex = 0;
std::string lastTriggerToken;
OverlayRect rect;
};
class CompletionOverlayUXHardening {
public:
static OverlayRect placeOverlayNearCursor(float cursorX,
float cursorY,
float lineHeight,
float viewportW,
float viewportH,
float overlayW,
float overlayH) {
OverlayRect r;
r.w = overlayW;
r.h = overlayH;
r.x = cursorX;
r.y = cursorY + lineHeight;
if (r.x + r.w > viewportW) r.x = clampMin(viewportW - r.w, 0.0f);
if (r.y + r.h > viewportH) r.y = clampMin(cursorY - r.h - 4.0f, 0.0f);
return r;
}
static CompletionOverlayState onDismiss(const CompletionOverlayState& in) {
CompletionOverlayState out = in;
out.visible = false;
out.dismissed = true;
return out;
}
static CompletionOverlayState onTrigger(const CompletionOverlayState& in,
const std::string& token,
bool semanticTriggerChanged) {
CompletionOverlayState out = in;
if (semanticTriggerChanged || token != in.lastTriggerToken) {
out.dismissed = false;
}
out.lastTriggerToken = token;
out.visible = !out.dismissed;
return out;
}
static CompletionOverlayState onPointerSelect(const CompletionOverlayState& in,
int index,
int itemCount) {
CompletionOverlayState out = in;
out.selectedIndex = clampIndex(index, itemCount);
out.visible = itemCount > 0;
return out;
}
static CompletionOverlayState onKeyNav(const CompletionOverlayState& in,
int delta,
int itemCount) {
CompletionOverlayState out = in;
if (itemCount <= 0) {
out.selectedIndex = 0;
out.visible = false;
return out;
}
out.selectedIndex = wrapIndex(in.selectedIndex + delta, itemCount);
out.visible = true;
return out;
}
private:
static float clampMin(float v, float lo) {
return v < lo ? lo : v;
}
static int clampIndex(int idx, int count) {
if (count <= 0) return 0;
if (idx < 0) return 0;
if (idx >= count) return count - 1;
return idx;
}
static int wrapIndex(int idx, int count) {
if (count <= 0) return 0;
int m = idx % count;
if (m < 0) m += count;
return m;
}
};