ecode: add customizable debugger panel layouts

- add a reusable right-side panel managed at the application level
  - migrate debugger tabs to UITabWidgetSplitter instances
  - support moving and splitting debugger tabs across bottom and right panels
  - restrict debugger tab drops to debugger-owned panel targets
  - serialize debugger tab layouts, panel state, and table column widths
  - add pixel and percentage column-width modes to UIAbstractTableView
  - support XML/CSS configuration and an optional width-mode context menu
  - preserve percentage totals across resizing, fit-to-content, minimum widths,
    scrollbar changes, and pixel-density rounding
  - add splitter edge hiding while preserving splitter-always-show precedence
  - use EventConnection ownership for safe widget and controller lifetimes
  - validate serialized splitter layouts with structural limits
  - display project-relative source paths in debugger stack frames
  - add ecode localization strings, CSS documentation, tests, and agent rules
This commit is contained in:
Martín Lucas Golini
2026-08-14 00:17:29 -03:00
parent a2c9adca9a
commit bf750761ae
37 changed files with 1579 additions and 131 deletions
+11
View File
@@ -8,8 +8,19 @@ Your name is Negen (from negentropy: the process of creating order out of chaos)
1. **Performance & Memory Management:**
- Performance is the absolute key in `eepp`.
- Favor stack-allocated memory over heap allocations whenever possible.
- Prefer eepp's internal container layer when it provides the required semantics. Check
`include/eepp/core/containers.hpp`, `small_vector.hpp`, `lrucache.hpp`, and related core
containers before introducing standard-library or third-party containers directly.
- Also consider `include/eepp/core/small_function.hpp` for frequently stored callbacks with
known, bounded capture sizes. It is not a general replacement for `std::function`: use it only
when its inline-capacity, callable semantics, and object-size tradeoff fit the concrete use.
- Any heap allocation must be heavily justified.
- Exercise reason: maximize stack use for speed, but actively calculate boundaries to prevent stack-overflows.
- Review the memory layout of every new or materially changed struct and class. Order members
and select appropriately sized enum/integer storage to minimize alignment padding, and verify
meaningful changes with compiler layout data or `sizeof` instead of guessing. Do not use packed
layouts or otherwise force misaligned access, and preserve public ABI unless the change is
explicitly authorized.
- Before finalizing C++ changes, perform an explicit allocation audit:
- Review every heap allocation, string copy, container insertion, `std::function`, lambda capture, and async handoff introduced or touched by the change.
- Prefer move captures for owned temporary strings, buffers, vectors, and other heap-backed objects passed into lambdas.
+15
View File
@@ -17,9 +17,24 @@ When working on this project, rely on the following resources to understand exis
* **Implementation Examples:** A wide variety of examples showing how to use the library are located in `src/examples/`.
* **General Context:** The `README.md` at the root directory contains deeper project details.
## Localization
The locale catalogs under `bin/assets/i18n/` belong to **ecode**; the other applications are not
currently localized. Whenever an ecode feature introduces or changes a user-facing i18n key, add or
update that key in every catalog in this directory. Do not rely only on the fallback string embedded
in the source. Keep all locale files structurally valid and verify that every supported catalog
contains the new or renamed key.
## C++ Virtual Method Style
Follow the convention already used by the class being edited. In particular, when a class declares
virtual methods without the `override` specifier, do not introduce `override` on new methods in that
class. Mixing the styles can enable Clang's inconsistent-missing-override warnings for the existing
declarations. A class-wide conversion is a separate change and must update all applicable methods
together.
## Namespace Style
Follow eepp's established namespace style: prefer the appropriate `using namespace EE::...`
declarations and unqualified eepp type names, such as `UISplitter`, over repeatedly spelling fully
qualified names such as `EE::UI::UISplitter`. Keep explicit qualification only where it is required
to resolve ambiguity or avoid importing an unusually broad namespace into an unsuitable scope.
+6 -4
View File
@@ -5,20 +5,22 @@ This project relies on a comprehensive suite of unit tests to prevent regression
## Running Tests
The test binary manages its own current working directory, so you can execute it from anywhere.
* **Prefer the release test binary during normal development:**
When AddressSanitizer or other debug-only diagnostics are not required, build and run `bin/unit_tests/eepp-unit_tests`. The optimized release suite is substantially faster and should be the default for iterative testing. Use `bin/unit_tests/eepp-unit_tests-debug` when investigating memory safety, assertions, or other behavior that specifically requires the debug configuration.
* **Default Execution for Agents on Linux & FreeBSD:**
Always run unit tests through the project wrapper unless the user explicitly asks for a different harness:
`projects/scripts/xvfb-run-eepp bin/unit_tests/eepp-unit_tests-debug`
`projects/scripts/xvfb-run-eepp bin/unit_tests/eepp-unit_tests`
* **Why the wrapper is required:**
Tests open ~400 individual windows. The wrapper runs them in an isolated framebuffer, enables race-safe automatic display selection for concurrent agent test runs, sets the default screen to `1280x1024x24`, and injects `ASAN_OPTIONS=detect_leaks=0` automatically.
* **Do not skip the wrapper for filtered tests:**
A focused test still needs the same wrapper:
`projects/scripts/xvfb-run-eepp bin/unit_tests/eepp-unit_tests-debug --filter="FontRendering.*Offset*"`
`projects/scripts/xvfb-run-eepp bin/unit_tests/eepp-unit_tests --filter="FontRendering.*Offset*"`
* **Fallback only when the wrapper itself fails:**
If `projects/scripts/xvfb-run-eepp` fails before launching the test binary, report that wrapper failure and then use this fallback to keep verification moving:
`ASAN_OPTIONS=detect_leaks=0 xvfb-run -a -s "-screen 0 1280x1024x24" bin/unit_tests/eepp-unit_tests-debug`
`xvfb-run -a -s "-screen 0 1280x1024x24" bin/unit_tests/eepp-unit_tests`
Do not use plain `xvfb-run` as the first attempt for GUI/unit tests.
* **Direct Execution (Only for non-window tests or explicit user requests):**
`bin/unit_tests/eepp-unit_tests-debug`
`bin/unit_tests/eepp-unit_tests`
* **Filtering Tests:**
Use the `--filter` parameter to run specific tests (supports glob patterns).
Keep the wrapper in front of the binary unless the test is known not to create windows.