AGT Coding Style
AGT Coding Style
AGT follows axl-sdk’s coding style (AXL-Coding-Style.md) verbatim, with the small set of C++-specific adaptations documented here. When a rule below differs from AXL’s, the AGT version wins for AGT code; when this doc is silent, AXL applies.
One prefix throughout: AGT for everything — project name, doc
filenames, class names (AgtObject, AgtApp), macros
(AGT_MAP_BEGIN), source filenames (src/agt-app.cpp), build
artifacts (libagt.a). Same pattern as axl-sdk uses for AXL.
This doc is intentionally short — the substantive style work lives in AXL-Coding-Style.md. Don’t restate things from there here; only document deltas.
Deltas from AXL-Coding-Style.md
Message-ID enum chain
FOX-style: every class that defines AGT_MAP_COMMAND ids
declares them in a public enum chained through Base::ID_LAST,
so subclass and consumer IDs never collide with whatever IDs
the AGT base classes happen to use today (or add tomorrow).
class MyDialog : public AgtDialog {
public:
enum {
ID_OK = AgtDialog::ID_LAST,
ID_CANCEL,
ID_LAST // re-emit so descendants can chain
};
// ...
};
AgtObject::ID_LAST = 0 is the chain root. Each
AGT-shipped class re-emits ID_LAST; consumer classes follow
the same convention. File-scope constexpr uint16_t ID_FOO
constants are an anti-pattern — they don’t chain, and collision
risk grows silently as the class hierarchy evolves.
Constructor design
Common-case wiring goes in the constructor with default values; rare-case tweaks stay as setters. The goal is consumer code that reads cleanly as a single new-expression:
new AgtButton(parent, x, y, w, h, "Quit", &window, ID_QUIT);
NOT the chained variant — (new Foo(...))->set_X() is valid
C++ but jars readers (operator precedence forces the parens).
Match FOX’s trailing-arg pattern: identity / geometry first,
target + selector last (e.g. FXButton(parent, label, icon, target, sel)).
7+ constructor args is the line where readability suffers; at
that point use an AgtFooOpts struct value passed by const ref
instead of a flat arg list. Optional rare-case configuration
(e.g. set_enabled(false), set_normal_color(...)) stays as
post-construction setters.
Naming
Element |
AXL convention |
AGT convention |
Example |
|---|---|---|---|
Free functions / variables / params |
|
same ( |
|
Class / struct names |
|
|
|
Class methods |
n/a (C) |
|
|
Member variables |
|
|
|
Macros / constants |
|
|
|
Enum values |
|
|
|
Namespaces |
n/a (C) |
none — Agt prefix replaces namespace |
|
Why no agt:: namespace: AGT is FOX-shape (per AGT-Design.md),
not glibmm-shape. Matches FOX’s FXObject/FXApp convention
(adapted: project=AGT, prefix=Agt; FOX uses 2-letter FX for
historical reasons but AGT follows axl-sdk’s 3-letter
project=prefix unification). The agt/ directory in include
paths and the Agt prefix together carry the namespace.
Cursor vs. pointer (terminology). Two distinct concepts, kept verbally distinct everywhere (symbols, comments, docs):
cursor — the text insertion point (the blinking caret in an editable widget). API:
cursor(),set_cursor(),cursor_line(),cursor_color(), … (AGT does not use the word “caret”.)pointer — the mouse arrow. API:
AgtWindow::pointer_x(),set_pointer_enabled(), the software-pointer sprite, etc.
The one exception is the menu keyboard-navigation cursor
(AgtMenuItem/AgtMenuBar highlight driven by arrow keys) — a third
concept that is neither, kept as “keyboard cursor” in its (always
qualified) prose.
File naming
Headers and sources use kebab-case (matching AXL):
Element |
Convention |
Example |
|---|---|---|
Public headers |
|
|
Umbrella header |
|
|
Internal headers |
|
|
Source files |
|
|
Test files |
|
|
Examples |
|
|
Header guards
Use #pragma once instead of #ifndef AGT_FOO_HPP guards. AGT
is greenfield C++; #pragma once is universally supported by GCC
and the cross-compiler we target (ARM bare-metal toolchain). Saves
a line, removes the chance of a typo’d guard.
(AXL uses #ifndef guards because it’s older C code and the guard
convention is established; AGT doesn’t inherit that history.)
Includes
Order: freestanding C → axl-sdk → AGT headers → C++ stdlib.
#include <stddef.h> // freestanding C
#include <stdint.h>
#include <axl.h> // axl-sdk (or specific axl/axl-X.h)
#include <agt/agt-app.hpp> // AGT headers
#include <agt/agt-widget.hpp>
#include <utility> // C++ stdlib (header-only subset only)
#include <span>
axl-sdk umbrella <axl.h> is fine for examples; internal AGT
sources should prefer specific headers (<axl/axl-loop.h> etc.)
to minimize compile cost.
Forbidden C++ features (per AXLMM-Design.md toolchain
constraints)
Feature |
Status |
Why |
|---|---|---|
Exceptions ( |
forbidden |
libsupc++ symbols unresolvable in freestanding link |
RTTI ( |
forbidden |
|
|
forbidden |
libstdc++ allocator + exception machinery |
|
forbidden |
chains to exception machinery |
|
forbidden |
needs |
|
deferred |
not in C++23 freestanding subset (P0829); revisit if a real need surfaces |
|
avoid |
ref-counted ownership conflicts with AGT’s parent-child tree model |
Usable: <array>, <span>, <string_view>, <type_traits>,
<utility>, <initializer_list>, <new>, <optional>,
<variant>, <expected> (C++23), header-only subsets of
<algorithm> / <numeric> / <functional>.
Full list + rationale: AXLMM-Design.md §”Toolchain & constraints”.
Source file header
// SPDX-License-Identifier: Apache-2.0
// Copyright 2026 AximCode
Two-line SPDX header on every .cpp/.hpp. Same content as AXL,
different comment syntax (// C++-native instead of /* */).
Source file order
Matches AXL (1: includes → 2: log domain → 3: macros → 4: types → 5: file-scope vars → 6: forward decls → 7: implementations). See AXL-Coding-Style.md §”Source File Layout”.
Doc comments
Use /// line-comments + /// @brief block style for exported
API (Doxygen-compatible). Per-param ///< on the same line as
the parameter (matches AXL).
class AgtWidget {
public:
/// Construct a widget with the given bounding rect.
///
/// @param parent Owning parent widget; widget is added as the
/// last child of @a parent.
/// @param x,y,w,h Bounding rectangle in parent-local coordinates.
AgtWidget(
AgtWidget *parent, ///< owning parent (cascade-delete root)
int x, int y, ///< top-left in parent coords
int w, int h ///< width / height in pixels
);
};
Everything else: see AXL-Coding-Style.md
Formatting (4-space indent, K&R braces, always-braces, return type on its own line, pointer-with-variable, explicit NULL checks, etc.), return value conventions (predicates / pointers / int / typed status enum), event-loop callback convention, printf and variadic style — all carry over from AXL verbatim.