Step 516: add signature visual identity primitives
This commit is contained in:
@@ -3523,4 +3523,13 @@ target_link_libraries(step515_test PRIVATE
|
||||
tree_sitter_javascript tree_sitter_typescript
|
||||
tree_sitter_java tree_sitter_rust tree_sitter_go)
|
||||
|
||||
add_executable(step516_test tests/step516_test.cpp)
|
||||
target_include_directories(step516_test PRIVATE src)
|
||||
target_link_libraries(step516_test PRIVATE
|
||||
nlohmann_json::nlohmann_json
|
||||
unofficial::tree-sitter::tree-sitter
|
||||
tree_sitter_python tree_sitter_cpp tree_sitter_elisp
|
||||
tree_sitter_javascript tree_sitter_typescript
|
||||
tree_sitter_java tree_sitter_rust tree_sitter_go)
|
||||
|
||||
# Step 12: Dear ImGui shell scaffolding created (main.cpp exists but not built due to dependencies)
|
||||
|
||||
81
editor/src/SignatureVisualIdentity.h
Normal file
81
editor/src/SignatureVisualIdentity.h
Normal file
@@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
// Step 516: Signature Visual Identity Pack
|
||||
// Encodes black-surface gradient treatment, blade-edge accents, and
|
||||
// electric-blue logic link styling.
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
struct GradientStop {
|
||||
float t = 0.0f;
|
||||
float r = 0.0f;
|
||||
float g = 0.0f;
|
||||
float b = 0.0f;
|
||||
float a = 1.0f;
|
||||
};
|
||||
|
||||
struct EdgeAccent {
|
||||
std::string edge; // left/right/top/bottom
|
||||
float thickness = 1.0f;
|
||||
float intensity = 0.0f;
|
||||
bool active = false;
|
||||
};
|
||||
|
||||
struct LogicLinkStyle {
|
||||
float width = 1.0f;
|
||||
float glow = 0.0f;
|
||||
float r = 0.15f;
|
||||
float g = 0.56f;
|
||||
float b = 0.95f;
|
||||
float alpha = 1.0f;
|
||||
};
|
||||
|
||||
class SignatureVisualIdentity {
|
||||
public:
|
||||
static std::vector<GradientStop> blackSurfaceGradient(bool elevated) {
|
||||
if (elevated) {
|
||||
return {
|
||||
{0.0f, 0.02f, 0.02f, 0.02f, 1.0f},
|
||||
{0.45f, 0.08f, 0.08f, 0.08f, 1.0f},
|
||||
{1.0f, 0.14f, 0.14f, 0.14f, 1.0f}
|
||||
};
|
||||
}
|
||||
return {
|
||||
{0.0f, 0.01f, 0.01f, 0.01f, 1.0f},
|
||||
{0.60f, 0.05f, 0.05f, 0.05f, 1.0f},
|
||||
{1.0f, 0.09f, 0.09f, 0.09f, 1.0f}
|
||||
};
|
||||
}
|
||||
|
||||
static EdgeAccent bladeEdge(const std::string& edge, bool active, float emphasis) {
|
||||
EdgeAccent a;
|
||||
a.edge = edge;
|
||||
a.active = active;
|
||||
a.thickness = active ? 2.0f : 1.0f;
|
||||
a.intensity = active ? std::max(0.2f, std::min(1.0f, emphasis)) : 0.12f;
|
||||
return a;
|
||||
}
|
||||
|
||||
static LogicLinkStyle electricBlueLink(bool highlighted, float distanceNorm) {
|
||||
LogicLinkStyle s;
|
||||
s.width = highlighted ? 2.4f : 1.4f;
|
||||
s.glow = highlighted ? 0.80f : 0.35f;
|
||||
float fade = std::max(0.35f, 1.0f - std::max(0.0f, std::min(1.0f, distanceNorm)) * 0.45f);
|
||||
s.alpha = fade;
|
||||
return s;
|
||||
}
|
||||
|
||||
static bool isElectricBlue(const LogicLinkStyle& s) {
|
||||
return s.b > s.r && s.b > s.g && s.g > s.r;
|
||||
}
|
||||
|
||||
static float revealDurationMs(bool reducedMotion) {
|
||||
return reducedMotion ? 80.0f : 220.0f;
|
||||
}
|
||||
|
||||
static float staggerDelayMs(int index, bool reducedMotion) {
|
||||
if (reducedMotion) return 0.0f;
|
||||
return std::max(0, index) * 24.0f;
|
||||
}
|
||||
};
|
||||
123
editor/tests/step516_test.cpp
Normal file
123
editor/tests/step516_test.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
// Step 516: Signature Visual Identity Pack (12 tests)
|
||||
|
||||
#include "SignatureVisualIdentity.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
static int passed = 0, failed = 0;
|
||||
#define TEST(name) { std::cout << " " << #name << "... "; }
|
||||
#define PASS() { std::cout << "PASS\n"; ++passed; }
|
||||
#define FAIL(msg) { std::cout << "FAIL: " << msg << "\n"; ++failed; }
|
||||
#define CHECK(cond, msg) if (!(cond)) { FAIL(msg); return; } else {}
|
||||
|
||||
void test_gradient_has_three_stops() {
|
||||
TEST(gradient_has_three_stops);
|
||||
auto g = SignatureVisualIdentity::blackSurfaceGradient(false);
|
||||
CHECK(g.size() == 3, "expected 3 stops");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_elevated_gradient_brighter_than_base() {
|
||||
TEST(elevated_gradient_brighter_than_base);
|
||||
auto a = SignatureVisualIdentity::blackSurfaceGradient(false);
|
||||
auto b = SignatureVisualIdentity::blackSurfaceGradient(true);
|
||||
CHECK(b.back().r > a.back().r, "elevated gradient should be brighter");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_blade_edge_active_increases_thickness() {
|
||||
TEST(blade_edge_active_increases_thickness);
|
||||
auto idle = SignatureVisualIdentity::bladeEdge("left", false, 0.5f);
|
||||
auto active = SignatureVisualIdentity::bladeEdge("left", true, 0.5f);
|
||||
CHECK(active.thickness > idle.thickness, "active edge should be thicker");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_blade_edge_active_uses_higher_intensity() {
|
||||
TEST(blade_edge_active_uses_higher_intensity);
|
||||
auto idle = SignatureVisualIdentity::bladeEdge("left", false, 0.5f);
|
||||
auto active = SignatureVisualIdentity::bladeEdge("left", true, 0.7f);
|
||||
CHECK(active.intensity > idle.intensity, "active edge should be stronger");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_logic_link_highlight_increases_width() {
|
||||
TEST(logic_link_highlight_increases_width);
|
||||
auto normal = SignatureVisualIdentity::electricBlueLink(false, 0.1f);
|
||||
auto hi = SignatureVisualIdentity::electricBlueLink(true, 0.1f);
|
||||
CHECK(hi.width > normal.width, "highlight should increase width");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_logic_link_highlight_increases_glow() {
|
||||
TEST(logic_link_highlight_increases_glow);
|
||||
auto normal = SignatureVisualIdentity::electricBlueLink(false, 0.1f);
|
||||
auto hi = SignatureVisualIdentity::electricBlueLink(true, 0.1f);
|
||||
CHECK(hi.glow > normal.glow, "highlight should increase glow");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_logic_link_alpha_fades_with_distance() {
|
||||
TEST(logic_link_alpha_fades_with_distance);
|
||||
auto near = SignatureVisualIdentity::electricBlueLink(false, 0.0f);
|
||||
auto far = SignatureVisualIdentity::electricBlueLink(false, 1.0f);
|
||||
CHECK(near.alpha > far.alpha, "alpha should fade with distance");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_logic_link_is_electric_blue() {
|
||||
TEST(logic_link_is_electric_blue);
|
||||
auto s = SignatureVisualIdentity::electricBlueLink(true, 0.3f);
|
||||
CHECK(SignatureVisualIdentity::isElectricBlue(s), "expected electric-blue profile");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_reveal_duration_shorter_in_reduced_motion() {
|
||||
TEST(reveal_duration_shorter_in_reduced_motion);
|
||||
auto normal = SignatureVisualIdentity::revealDurationMs(false);
|
||||
auto reduced = SignatureVisualIdentity::revealDurationMs(true);
|
||||
CHECK(reduced < normal, "reduced-motion reveal should be shorter");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_stagger_delay_zero_in_reduced_motion() {
|
||||
TEST(stagger_delay_zero_in_reduced_motion);
|
||||
CHECK(SignatureVisualIdentity::staggerDelayMs(3, true) == 0.0f,
|
||||
"reduced-motion stagger should be zero");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_stagger_delay_grows_with_index() {
|
||||
TEST(stagger_delay_grows_with_index);
|
||||
auto a = SignatureVisualIdentity::staggerDelayMs(1, false);
|
||||
auto b = SignatureVisualIdentity::staggerDelayMs(4, false);
|
||||
CHECK(b > a, "stagger should increase with index");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_gradient_t_values_are_ordered() {
|
||||
TEST(gradient_t_values_are_ordered);
|
||||
auto g = SignatureVisualIdentity::blackSurfaceGradient(true);
|
||||
CHECK(g[0].t < g[1].t && g[1].t < g[2].t, "gradient t-values must be ordered");
|
||||
PASS();
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::cout << "Step 516: Signature Visual Identity Pack\n";
|
||||
|
||||
test_gradient_has_three_stops(); // 1
|
||||
test_elevated_gradient_brighter_than_base(); // 2
|
||||
test_blade_edge_active_increases_thickness(); // 3
|
||||
test_blade_edge_active_uses_higher_intensity(); // 4
|
||||
test_logic_link_highlight_increases_width(); // 5
|
||||
test_logic_link_highlight_increases_glow(); // 6
|
||||
test_logic_link_alpha_fades_with_distance(); // 7
|
||||
test_logic_link_is_electric_blue(); // 8
|
||||
test_reveal_duration_shorter_in_reduced_motion(); // 9
|
||||
test_stagger_delay_zero_in_reduced_motion(); // 10
|
||||
test_stagger_delay_grows_with_index(); // 11
|
||||
test_gradient_t_values_are_ordered(); // 12
|
||||
|
||||
std::cout << "\nResults: " << passed << "/" << (passed + failed) << " passed\n";
|
||||
return failed == 0 ? 0 : 1;
|
||||
}
|
||||
36
progress.md
36
progress.md
@@ -8247,3 +8247,39 @@ scales, derivation support, and AA contrast validation.
|
||||
- `editor/src/ThemeTokenSystemV2.h` within header-size limit (`107` <= `600`)
|
||||
- `editor/tests/step515_test.cpp` within test-file size guidance (`121` lines)
|
||||
- Header-only architecture and naming conventions remain aligned with `ARCHITECTURE.md`
|
||||
|
||||
### Step 516: Signature Visual Identity Pack
|
||||
**Status:** PASS (12/12 tests)
|
||||
|
||||
Implements Sprint 26’s signature visual identity primitives: black-surface
|
||||
gradient depth treatment, blade-edge accent semantics for active surfaces, and
|
||||
electric-blue logic-link styling with distance-aware fading and motion-aware
|
||||
reveal timing.
|
||||
|
||||
**Files added:**
|
||||
- `editor/src/SignatureVisualIdentity.h` - visual identity module:
|
||||
- elevated/base black-surface gradient presets
|
||||
- blade-edge accent model (edge, thickness, intensity, active state)
|
||||
- electric-blue logic-link style with highlight and distance fade behavior
|
||||
- reduced-motion aware reveal and stagger timing helpers
|
||||
- `editor/tests/step516_test.cpp` - 12 tests covering:
|
||||
- gradient stop structure/order and elevated-depth brightness
|
||||
- active blade-edge thickness/intensity behavior
|
||||
- highlighted link width/glow behavior
|
||||
- distance-based logic-link alpha fade
|
||||
- electric-blue profile detection
|
||||
- reduced-motion reveal/stagger behavior
|
||||
|
||||
**Files modified:**
|
||||
- `editor/CMakeLists.txt` - `step516_test` target
|
||||
|
||||
**Verification run:**
|
||||
- `cmake -S editor -B editor/build-native` - PASS
|
||||
- `cmake --build editor/build-native --target step516_test` - PASS
|
||||
- `./editor/build-native/step516_test` - PASS (12/12)
|
||||
- `./editor/build-native/step515_test` - PASS (12/12) regression coverage
|
||||
|
||||
**Architecture gate check:**
|
||||
- `editor/src/SignatureVisualIdentity.h` within header-size limit (`81` <= `600`)
|
||||
- `editor/tests/step516_test.cpp` within test-file size guidance (`123` lines)
|
||||
- Header-only architecture and naming conventions remain aligned with `ARCHITECTURE.md`
|
||||
|
||||
Reference in New Issue
Block a user