TimelineStoryLayout.h header
#include <ew/app/TimelineStoryLayout.h>
Namespace ew::app
StoryLane struct
struct ew::app::StoryLane
One category lane fed to the layout: the side it sits on and its events, in the caller's order.
Members
StorySide ew::app::StoryLane::side =
Which side of the central axis this lane sits on.
std::vector<LayoutEvent> ew::app::StoryLane::events
This lane's events, in the caller's order.
bool ew::app::StoryLane::axisBars = true
Whether this lane's DURATION events (endX > startX) get a dated span bar hugging the axis (R2.4) – the visible geometry a resize grabs. Lifespan lanes switch this off: a lifespan is R5.1's own span-bar treatment inside its lane, not an axis bar.
StoryLaneBox struct
struct ew::app::StoryLaneBox
The outlined box drawn for a lane – the region its pills live inside (never a bare line). Its height is however many pill rows the lane needs (events are stacked, never collapsed), so a busy lane grows and a quiet one stays thin.
Members
QRect ew::app::StoryLaneBox::box
The bordered area, spanning the plot width.
StorySide ew::app::StoryLaneBox::side =
Which side of the central axis the lane box sits on.
int ew::app::StoryLaneBox::rows = 0
How many pill rows it holds (>= 1 when it has events).
StoryLayout struct
struct ew::app::StoryLayout
The whole story-view geometry: the axis y, every lane's box, every event's pill + leader.
Members
int ew::app::StoryLayout::axisY = 0
The y coordinate of the central horizontal axis.
std::vector<StoryLaneBox> ew::app::StoryLayout::laneBoxes
Parallel to the input lanes.
std::vector<StoryPill> ew::app::StoryLayout::pills
Flattened across all lanes, in input order.
StoryLayoutParams struct
struct ew::app::StoryLayoutParams
The pixels the story layout works within.
Members
QRect ew::app::StoryLayoutParams::plot
The drawable area (the plot column, minus the left label gutter).
int ew::app::StoryLayoutParams::pillHeight = 18
Height of one pill (one stack row).
int ew::app::StoryLayoutParams::pillGap = 3
Vertical gap between two stacked pills in a lane.
int ew::app::StoryLayoutParams::laneGap = 8
Gap between two adjacent lane boxes on the same side.
int ew::app::StoryLayoutParams::axisGap = 12
Gap between the axis line and the nearest lane box, each side.
int ew::app::StoryLayoutParams::minPillWidth = 40
Narrowest a pill may be, so a short date-title still reads.
int ew::app::StoryLayoutParams::barHeight = 6
Height of one duration span bar hugging the axis (R2.4).
int ew::app::StoryLayoutParams::barGap = 2
Gap between two stacked span-bar rows (and two bars in one row).
StoryPill struct
struct ew::app::StoryPill
One event, laid out as a pill with a leader to the central axis. The pill is stacked OUTWARD from the axis (row 0 nearest it) so it never overlaps a neighbour – there is no clustering; a dense run uses vertical space (docs/TIMELINE_REDESIGN.md R2.3). The leader is the vertical line that ties the pill to its date on the axis (R2.2): both ends share the event's x.
Members
ew::core::ContentId ew::app::StoryPill::id
The event this pill represents.
QRect ew::app::StoryPill::pill
The date-title card, inside its lane box.
QPoint ew::app::StoryPill::leaderPill
The pill end of the leader (its axis-facing edge, at the event's x).
QPoint ew::app::StoryPill::leaderAxis
The axis end of the leader (the event's x, on the central axis).
int ew::app::StoryPill::row = 0
Its stack row within the lane (0 = nearest the axis).
QRect ew::app::StoryPill::spanBar
A duration event's dated bar hugging the axis on the lane's side (R2.4): startX..endX wide, so the span reads against the axis dates and its edges are the visible resize handles. Null for an instant (endX == startX) and for a lane with StoryLane::axisBars off. Bars on one side stack outward in thin rows so overlapping spans stay individually readable.
Enumerations
enum class StoryLaneKind { Event, Lifespan, Series }
What kind of content a lane holds, which drives its default side: event lanes read as the primary narrative ABOVE the axis; the derived lanes (lifespans, quantitative series) sit BELOW.
enum class StorySide { Above, Below }
The "Story view" layout (docs/TIMELINE_REDESIGN.md): ONE central horizontal axis with category lanes as outlined boxes above and below it, every event a pill joined to its exact point on the axis by a leader line. This is the geometry engine – pure, pixel-space, and unit-tested – so the panel that draws it holds no layout maths (per the redesign's Definition of Done). It reuses LayoutEvent (id / startX / endX / labelWidth, already time->pixel mapped by the caller). Which side of the central axis a lane sits on. Above lanes stack UPWARD from the axis, below lanes stack DOWNWARD, so the axis stays the shared anchor both read against.
Functions
std::vector< StorySide > ew::app::defaultStorySides(const std::vector< StoryLaneKind > &kinds)
The default side (above/below the axis) for each lane, by kind: event lanes above, lifespan and series lanes below. When a project has only event lanes (nothing would sit below), the latter half move below so the axis stays roughly central rather than pinned to the bottom. A user's explicit per-lane choice (persisted with the view settings) overrides this default at the caller.
StoryLayout ew::app::storyLayout(const std::vector< StoryLane > &lanes, const StoryLayoutParams ¶ms)
Computes the story-view geometry (pure). The central axis is anchored at the plot's vertical CENTRE and stays there however tall a lane grows (so a busy lane can never shove the axis off screen – the flaw the redesign fixes); above lanes stack upward from it and below lanes downward, a lane taller than its half simply overflowing the plot edge for the caller to clip or scroll. Each lane box is sized to its stacked pill rows; every pill is stacked outward from the axis (greedy by startX, so two events that overlap in x take different rows and none is ever collapsed); and every pill gets a vertical leader from its axis-facing edge to the event's x on the axis. Lanes with no events still get a thin box.