Calendar Painting Pipeline
11 partial files for calendar rendering — centralized Paint() dispatcher, Month/Week/Day/List/Timeline views, design-time preview, sidebar, and LayoutTheme subsystem (9 files)
Table of Contents
Overview
Calendar rendering is decomposed across 11 partial files plus a 9-file LayoutTheme subsystem. The architecture uses a centralized dispatcher method Paint() that chooses between a new style-based painter system (_usePainterSystem) and a legacy renderer fallback (DrawWithLegacyRenderer). At design time in Visual Studio, the calendar renders a simplified preview instead.
Paint Dispatcher
// Centralized entry point called from DrawContent and Draw:
private void Paint(Graphics g, Rectangle bounds)
{
if (IsDesignModeSafe)
DrawDesignTimePreview(g, bounds); // VS designer placeholder
else if (_usePainterSystem && _stylePainter != null)
DrawWithPainter(g, contentRect); // New style-based system
else
DrawWithLegacyRenderer(g, contentRect); // Legacy fallback
}
// Entry points from BaseControl framework:
protected override void DrawContent(Graphics g)
=> Paint(g, DrawingRect);
public override void Draw(Graphics graphics, Rectangle rectangle)
=> Paint(graphics, rectangle);View Renderers
| View | Files | Content Rendered |
|---|---|---|
| Month View | Painting.MonthView.cs, MonthView.Events.cs, MonthView.Headers.cs | 7-column grid of day cells (Sun-Sat). Each cell: day number, up to maxEventsPerCell event blocks. Overflow shows "+N more". Selected day highlighted. |
| Week View | Painting.WeekView.cs, WeekView.Events.cs | 7-day week grid with hourly time slots on the left. Event bars span their time range vertically. Supports WorkWeek (Mon-Fri). |
| Day View | Painting.DayView.cs | Single day with 24 one-hour slots (~60px each). Event blocks show title, time, location. All-day events in a header band. |
| List View / Agenda | Painting.ListView.cs | Chronological event list with date headers. Each entry shows time, title, location, and category color indicator. |
| Timeline View | Painting.Views.cs | Horizontal timeline with event spans. Time scale configurable. Supports resource grouping on the Y axis. |
| Pipeline | Painting.Pipeline.cs (5 sub-files) | Rendering orchestration (Pipeline.cs), view dispatch (Pipeline.Views.cs), telemetry (Pipeline.Telemetry.cs), header formatting (Pipeline.HeaderFormatting.cs), legacy compatibility (Pipeline.Legacy.cs) |
View Rendering Details
Month View
Renders a 7x5 or 7x6 grid of day cells. Each cell contains: day number (top-left), event blocks (colored by category), "+N more" indicator for overflow. Events that span multiple days are rendered across consecutive cells. The current cell's category colors come from LayoutTheme.MonthCells.cs.
Week / Day View
Time slots are rendered at 30 or 60 minute intervals depending on DensityMode. The current time line (red) is drawn when the view contains today. Event blocks are positioned absolutely within the time grid, with their top offset proportional to start time and height proportional to duration. Events that overlap share column width equally.
List View
Events displayed chronologically in a single scrollable list. Each row: date header (group separator), time column (left), event title (center), location and category badge (right). Multi-day events span multiple entries with a "continues" indicator.
Design-Time Preview
Controlled by BeepCalendar.Painting.DesignTime.cs. When IsDesignModeSafe returns true (hosted in Visual Studio designer):
- Renders a simplified month grid for the current month
- 2-3 sample events spanning multiple days with sample titles
- Today cell highlighted with accent color
- No interaction support — static preview only
- Uses placeholder data, no real event model required
Sidebar Calendar
When ShowSidebar is true, BeepCalendar.Painting.Sidebar.cs renders a compact mini-calendar in a narrow sidebar panel (~200px):
- One month displayed at a time with abbreviated day-of-week headers (S M T W T F S)
- Navigation arrows (</>) to scroll months forward/backward
- Dot indicator beneath days that have one or more events
- Today date highlighted with a colored circle
- Clicking a date in the sidebar navigates the main view to that date
LayoutTheme Subsystem (9 Files)
| File | Role |
|---|---|
| LayoutTheme.cs | Main theme coordinator, initializes all theme-related visual properties |
| LayoutTheme.ApplyTheme.cs | Maps IBeepTheme tokens to calendar-specific visual properties (colors, fonts, borders, padding) |
| LayoutTheme.Layout.cs | Cell positions, margins, padding, grid spacing calculations |
| LayoutTheme.MonthCells.cs | Month view cell colors: today, selected, hovered, weekend, other-month, event-colors |
| LayoutTheme.HeaderText.cs | Header text formatting, day-of-week label colors, month/year title rendering |
| LayoutTheme.ResponsiveLabels.cs | Text truncation based on available cell size. Shrinks font or abbreviates text when cell is narrow |
| LayoutTheme.Controls.cs | Control-level visual properties: navigation buttons, view selector, density toggle |
| LayoutTheme.Controls.Categories.cs | Event category color mapping from theme. Resolves EventCategory.Color when category uses theme-defined colors |
Visual Updates
3 files manage rendering performance via scoped invalidation:
- VisualUpdates.Flush.cs — Full redraw of the entire calendar surface via
Invalidate() - VisualUpdates.Scope.cs — Partial invalidation: only redraws the area containing a changed event for better performance during drag operations
- VisualUpdates.Strategy.cs — Dirty-rect tracking optimization: maintains a union of dirty rectangles to avoid redundant repaints
Code Examples
// Switch view modes
cal.ViewMode = CalendarViewMode.Month; // 7-column grid
cal.ViewMode = CalendarViewMode.Week; // 7-day + hourly slots
cal.ViewMode = CalendarViewMode.Day; // Single day
cal.ViewMode = CalendarViewMode.Agenda; // Event list
// Density modes
cal.DensityMode = CalendarDensityMode.Compact; // Smaller fonts, tight
cal.DensityMode = CalendarDensityMode.Comfortable; // Larger fonts, spaced
// Sidebar
cal.ShowSidebar = true; // Compact mini-calendar panel