跳转至

Graphics_Complete_UserGuide.md

Source code

/**
 * @page Graphics_Complete_UserGuide Graphics Framework - Complete User Guide
 *
 * @tableofcontents
 *
 * ---
 *
 * @section PART_I PART I: Graphics Subsystem Overview
 *
 * @section GraphicsOverview Overview
 *
 * The Graphics subsystem provides a complete framework for rendering graphical
 * content on various display devices. It is built on a modular architecture
 * consisting of:
 *
 * - **Graphics Device Abstraction**: Unified interface for different display hardware
 * - **OLED Device Binding**: Integration with OLED displays
 * - **Animation Framework**: Smooth transitions and visual effects
 * - **Widget System**: High-level UI components (Text, Menu, ProgressBar, Image)
 * - **Resource Management**: Fonts, textures, and other rendering assets
 *
 * @section GraphicsArchitecture Architecture
 *
 * The Graphics subsystem is organized in layers:
 *
 * ```
 * Application Code
 *        |
 *        v
 * Widget Framework (text, menu, animation, image, etc.)
 *        |
 *        v
 * Graphics Device Abstraction (graphic_device.h)
 *        |
 *        +-> OLED Device Binding (oled_graphic_device.h)
 *        |
 *        v
 * Hardware Drivers (OLED, LCD, etc.)
 * ```
 *
 * @section GettingStartedGraphics Getting Started with Graphics
 *
 * @subsection Step1_Headers Include Required Headers
 *
 * ```cpp
 * #include "graphic_device.h"
 * #include "oled_graphic_device.h"
 * #include "oled.h"
 * #include "driver/backend/oled_iic.h"
 * ```
 *
 * @subsection Step2_InitializeOLED Initialize OLED Display
 *
 * ```cpp
 * CFBD_OLED oled;
 * CFBD_OLED_IICInitsParams iic_config = {
 *     .device_address = SSD1309_DRIVER_ADDRESS,
 *     .i2c_handle = &my_i2c,
 * };
 *
 * CFBD_GetOLEDHandle(&oled, CFBD_OLEDDriverType_IIC, &iic_config, CFBD_TRUE);
 * oled.ops->open(&oled);
 * ```
 *
 * @subsection Step3_CreateGraphicsDevice Create Graphics Device
 *
 * ```cpp
 * CFBD_GraphicDevice graphics;
 * CFBDGraphic_BindOLEDAsDevice(&graphics, &oled);
 * graphics.ops->open(&graphics);
 * ```
 *
 * @subsection Step4_RenderContent Render Graphics Content
 *
 * ```cpp
 * graphics.ops->clear(&graphics);
 * graphics.ops->setPixel(&graphics, 64, 32);
 * graphics.ops->update(&graphics);
 * ```
 *
 * @section DrawingModes Drawing Modes
 *
 * The graphics device supports two drawing modes:
 *
 * **Immediate Mode**: Each drawing operation immediately updates the display
 * ```cpp
 * CFBDGraphic_DeviceSetIfRequestUpdateAtOnce(&graphics, CFBD_TRUE);
 * graphics.ops->setPixel(&graphics, 64, 32);  // Visible immediately
 * ```
 *
 * **Deferred Mode**: Drawing operations are buffered; display is updated explicitly
 * ```cpp
 * CFBDGraphic_DeviceSetIfRequestUpdateAtOnce(&graphics, CFBD_FALSE);
 * graphics.ops->setPixel(&graphics, 64, 32);
 * graphics.ops->setPixel(&graphics, 65, 32);
 * graphics.ops->update(&graphics);  // Both pixels visible now
 * ```
 *
 * @section AnimationUsage Using Animations
 *
 * The Animation framework provides frame-based animations:
 *
 * ```cpp
 * // Initialize animation with defaults
 * CFBD_BaseAnimation anim;
 * CFBD_InitBaseAnimation(&anim);
 * anim.anim_frames = 16;
 * anim.anim_frame_delay_ms = 30;
 *
 * // Use in animation loop
 * for (uint8_t frame = 0; frame < anim.anim_frames; frame++) {
 *     float progress = (float)frame / anim.anim_frames;
 *     // Render frame based on progress
 *     if (anim.anim_frame_delay_ms > 0) {
 *         HAL_Delay(anim.anim_frame_delay_ms);
 *     }
 * }
 * ```
 *
 * @section ResourceConfiguration Resource Configuration
 *
 * Graphics resources (fonts, etc.) are configured in resource/config.h:
 *
 * ```cpp
 * // Enable/disable font resources
 * #define ENABLE_ASCII_6x8_SOURCES 1
 * #define ENABLE_ASCII_8x16_SOURCES 1
 *
 * // Or disable all defaults and customize
 * #define _USE_NO_DEFAULT_SOURCES
 * ```
 *
 * @section HelperUtilities Utility Functions
 *
 * The helpers module provides common utilities:
 *
 * ```cpp
 * // Min/Max operations
 * int larger = MAX(100, 200);
 * int smaller = MIN(100, 200);
 *
 * // Value clamping
 * int32_t x = clamp_i32(user_input, 0, 127);
 * ```
 *
 * @section CompleteGraphicsExample Complete Graphics Setup Example
 *
 * ```cpp
 * #include "graphic_device.h"
 * #include "oled_graphic_device.h"
 * #include "oled.h"
 * #include "widget/animation/animation.h"
 *
 * void graphics_demo(void) {
 *     // Initialize OLED
 *     CFBD_OLED oled;
 *     CFBD_OLED_IICInitsParams iic_config = {
 *         .device_address = SSD1309_DRIVER_ADDRESS,
 *         .i2c_handle = &my_i2c,
 *     };
 *     CFBD_GetOLEDHandle(&oled, CFBD_OLEDDriverType_IIC, &iic_config, CFBD_TRUE);
 *     oled.ops->open(&oled);
 *
 *     // Create graphics device
 *     CFBD_GraphicDevice graphics;
 *     CFBDGraphic_BindOLEDAsDevice(&graphics, &oled);
 *     graphics.ops->open(&graphics);
 *     CFBDGraphic_DeviceSetIfRequestUpdateAtOnce(&graphics, CFBD_FALSE);
 *
 *     // Setup animation
 *     CFBD_BaseAnimation anim;
 *     CFBD_InitBaseAnimation(&anim);
 *     anim.anim_frames = 8;
 *     anim.anim_frame_delay_ms = 50;
 *
 *     // Clear display
 *     graphics.ops->clear(&graphics);
 *     graphics.ops->update(&graphics);
 *
 *     // Draw animated pattern
 *     for (uint8_t frame = 0; frame < anim.anim_frames; frame++) {
 *         graphics.ops->clear(&graphics);
 *
 *         // Draw frame-dependent content
 *         for (uint16_t x = 0; x < 128; x += 2) {
 *             graphics.ops->setPixel(&graphics, x, 32 + frame);
 *         }
 *
 *         graphics.ops->update(&graphics);
 *         HAL_Delay(anim.anim_frame_delay_ms);
 *     }
 *
 *     // Cleanup
 *     graphics.ops->close(&graphics);
 *     oled.ops->close(&oled);
 * }
 * ```
 *
 * @section GraphicsPerformanceTips Performance Tips
 *
 * - **Deferred Mode**: Use for batch operations to reduce display updates
 * - **Area Updates**: Use update_area() for partial display refresh
 * - **Animation Frames**: 4-8 frames for UI feedback, 16+ for smooth transitions
 * - **Resource Management**: Disable unused resources (fonts) to save memory
 *
 * @section ErrorHandling Error Handling
 *
 * Always check return values for graphics operations:
 *
 * ```cpp
 * if (graphics.ops->setPixel(&graphics, x, y)) {
 *     // Operation succeeded
 * } else {
 *     // Operation failed (invalid coordinates, device error, etc.)
 * }
 * ```
 *
 * ---
 *
 * @section PART_II PART II: Text Widget System
 *
 * @section text_intro Introduction to Text Widget
 *
 * The Graphics Text Widget provides comprehensive text rendering capabilities
 * with support for multiple monospace fonts, multiline layout, and flexible
 * positioning. Text is rendered character-by-character using pre-compiled
 * font bitmaps.
 *
 * @section text_features Key Features
 *
 * - **Multiple Font Sizes**: 6x8 and 8x16 pixel ASCII fonts
 * - **Multiline Support**: Automatic line wrapping and manual line breaks
 * - **Flexible Layout**: Continuous flow or explicit newlines
 * - **Position Queries**: Get next character position without drawing
 * - **Compile-Time Configuration**: Enable/disable fonts via config macros
 * - **Device Agnostic**: Works with any graphics device (OLED, LCD, etc.)
 *
 * @section text_font_architecture Font System
 *
 * @subsection font_sizes Supported Font Sizes
 *
 * @verbatim
 * ASCII Fonts (Compile-Time Selectable):
 * ┌─────────────────────────────────────────────┐
 * │ ASCII_6x8:  6 pixels wide x 8 pixels tall   │
 * │             Compact, dense text layout      │
 * │             Good for: status messages       │
 * ├─────────────────────────────────────────────┤
 * │ ASCII_8x16: 8 pixels wide x 16 pixels tall  │
 * │             Standard readability            │
 * │             Good for: main menu text        │
 * └─────────────────────────────────────────────┘
 * @endverbatim
 *
 * @subsection font_enable Font Enablement
 *
 * Fonts are enabled/disabled via resource/config.h macros:
 *
 * @code
 * // In your project configuration:
 * #define ENABLE_ASCII_6x8_SOURCES    // Enable 6x8 font
 * #define ENABLE_ASCII_8x16_SOURCES   // Enable 8x16 font
 * @endcode
 *
 * @section text_quick_start Quick Start with Text
 *
 * @subsection quick_basic Basic Text Rendering
 *
 * @code
 * #include "graphic/widget/text.h"
 *
 * void display_text(CFBD_GraphicDevice* device) {
 *     // Initialize text widget
 *     CFBDGraphic_Text text;
 *     CFBDGraphic_Point pos = {0, 0};
 *     CFBDGraphicSize area = {128, 64};
 *     CFBDGraphic_InitText(&text, pos, area, ASCII_8x16);
 *
 *     // Set and render text
 *     CFBDGraphic_SetText(&text, "Hello World!");
 *     CFBDGraphic_DrawText(device, &text,
 *                         CCGraphic_AsciiTextItem_AppendContinously);
 *
 *     // Update display
 *     device->ops->update(device);
 * }
 * @endcode
 *
 * @subsection quick_multiline Multiline Text
 *
 * @code
 * void display_multiline(CFBD_GraphicDevice* device) {
 *     CFBDGraphic_Text text;
 *     CFBDGraphic_Point pos = {0, 0};
 *     CFBDGraphicSize area = {128, 64};
 *     CFBDGraphic_InitText(&text, pos, area, ASCII_8x16);
 *
 *     // First line
 *     CFBDGraphic_SetText(&text, "Menu:");
 *     CFBDGraphic_DrawText(device, &text,
 *                         CCGraphic_AsciiTextItem_AppendContinously);
 *
 *     // Second line
 *     CFBDGraphic_SetText(&text, "1. Start");
 *     CFBDGraphic_DrawText(device, &text,
 *                         CCGraphic_AsciiTextItem_AppendNextLine);
 *
 *     // Third line
 *     CFBDGraphic_SetText(&text, "2. Settings");
 *     CFBDGraphic_DrawText(device, &text,
 *                         CCGraphic_AsciiTextItem_AppendNextLine);
 *
 *     device->ops->update(device);
 * }
 * @endcode
 *
 * @section text_layout Layout Methods
 *
 * @subsection layout_continuous Continuous (Default)
 *
 * Characters flow continuously on same line until width limit, then wrap.
 *
 * @code
 * CCGraphic_AsciiTextItem_AppendContinously
 * @endcode
 *
 * Use for: Paragraph text, automatic wrapping, word processing
 *
 * @subsection layout_newline Explicit Newline
 *
 * Forces next text segment to start on new line.
 *
 * @code
 * CCGraphic_AsciiTextItem_AppendNextLine
 * @endcode
 *
 * Use for: Menu items, structured lists, formatted text
 *
 * @subsection layout_query Query Position
 *
 * Get position after hypothetical rendering without actual drawing.
 *
 * @code
 * CCGraphic_AsciiTextItem_RequestOldPoint
 * @endcode
 *
 * Use for: Calculate text metrics, layout planning, responsive design
 *
 * @section text_positioning Positioning and Layout
 *
 * @subsection pos_setup Initial Setup
 *
 * @code
 * CFBDGraphic_Text text;
 * CFBDGraphic_Point pos = {x_start, y_start};
 * CFBDGraphicSize area = {width, height};
 * CFBDGraphic_InitText(&text, pos, area, ASCII_8x16);
 * @endcode
 *
 * @subsection pos_relocate Repositioning
 *
 * @code
 * // Move text to new position and resize area
 * CFBDGraphic_Point new_pos = {20, 30};
 * CFBDGraphicSize new_area = {88, 34};
 * CCGraphicWidget_AsciiTextItem_relocate(&text, &new_pos, new_area);
 * @endcode
 *
 * @subsection pos_resume Resume at Position
 *
 * @code
 * // Continue text at specific position
 * CFBDGraphic_Point continue_pos = {0, 16};  // Next line
 * CFBDGraphic_SetTextIndexedPoint(&text, &continue_pos);
 * @endcode
 *
 * @section text_font_selection Font Selection
 *
 * @subsection font_compile Compile-Time Selection
 *
 * @code
 * // In project config:
 * #define ENABLE_ASCII_8x16_SOURCES  // Enable 8x16 only
 * #undef ENABLE_ASCII_6x8_SOURCES    // Disable 6x8
 *
 * // In code:
 * #if ENABLE_ASCII_8x16_SOURCES
 *     CFBDGraphic_InitText(&text, pos, area, ASCII_8x16);
 * #else
 *     printf("8x16 font not available\n");
 * #endif
 * @endcode
 *
 * @subsection font_runtime Runtime Query
 *
 * @code
 * // Get font dimensions
 * CFBDGraphicSize font_size = __fetch_font_size(ASCII_8x16);
 * printf("Font: %u x %u pixels\n", font_size.width, font_size.height);
 *
 * // Get character bitmap
 * uint8_t* char_bitmap = __select_from_ascii_font_size(ASCII_8x16, 'A');
 * if (char_bitmap == UNSUPPORTIVE_FONT_SOURCE) {
 *     printf("Font not available\n");
 * }
 * @endcode
 *
 * @section text_padding Spacing and Padding
 *
 * @code
 * // Character horizontal spacing (padding between chars)
 * #define CFBDGraphic_TEXT_PADDING_WIDTH (1)  // 1 pixel
 *
 * // Line vertical spacing
 * #define CFBDGraphic_TEXT_PADDING_HEIGHT (0) // 0 pixels
 * @endcode
 *
 * Configure these macros to adjust text layout density.
 *
 * @section text_best_practices Text Best Practices
 *
 * @subsection bp_font_check Always Check Font Availability
 *
 * @code
 * uint8_t* font = __select_from_ascii_font_size(ASCII_8x16, 'A');
 * if (font == UNSUPPORTIVE_FONT_SOURCE) {
 *     // Font not enabled - provide fallback
 *     return handle_missing_font();
 * }
 * @endcode
 *
 * @subsection bp_string_validity Maintain String Validity
 *
 * @code
 * // GOOD: Static string
 * CFBDGraphic_SetText(&text, "Static Text");
 * CFBDGraphic_DrawText(device, &text, ...);
 *
 * // GOOD: Stack buffer in local scope
 * char buffer[32];
 * sprintf(buffer, "Score: %d", score);
 * CFBDGraphic_SetText(&text, buffer);
 * CFBDGraphic_DrawText(device, &text, ...);
 * // buffer still valid during draw
 *
 * // BAD: Pointer to temporary
 * CFBDGraphic_SetText(&text, "Value: ");
 * // sprintf result to temporary - DON'T DO THIS
 * @endcode
 *
 * @subsection bp_deferred_mode Use Deferred Mode for Multiple Texts
 *
 * @code
 * // Multiple text elements - use deferred mode
 * CFBDGraphic_DeviceSetIfRequestUpdateAtOnce(device, CFBD_FALSE);
 *
 * // Draw multiple text elements
 * CFBDGraphic_DrawText(device, &title_text, ...);
 * CFBDGraphic_DrawText(device, &body_text, ...);
 * CFBDGraphic_DrawText(device, &footer_text, ...);
 *
 * // Single update for all
 * device->ops->update(device);
 * @endcode
 *
 * @subsection bp_bounds_check Plan for Text Bounds
 *
 * @code
 * // Calculate required size
 * CFBDGraphicSize font_size = __fetch_font_size(ASCII_8x16);
 * int text_width = 11 * (font_size.width + CFBDGraphic_TEXT_PADDING_WIDTH);
 * int text_height = font_size.height;
 *
 * // Allocate adequate area
 * CFBDGraphicSize area = {text_width + 10, text_height + 10};
 * CFBDGraphic_InitText(&text, pos, area, ASCII_8x16);
 * @endcode
 *
 * @section text_complete_example Complete Text System Example
 *
 * @code
 * #include "graphic/device/graphic_device.h"
 * #include "graphic/widget/text.h"
 *
 * void display_system_menu(CFBD_GraphicDevice* device) {
 *     // Initialize text for title
 *     CFBDGraphic_Text title;
 *     CFBDGraphic_Point title_pos = {0, 0};
 *     CFBDGraphicSize title_area = {128, 16};
 *     CFBDGraphic_InitText(&title, title_pos, title_area, ASCII_8x16);
 *
 *     // Initialize text for menu items
 *     CFBDGraphic_Text menu;
 *     CFBDGraphic_Point menu_pos = {10, 18};
 *     CFBDGraphicSize menu_area = {108, 46};
 *     CFBDGraphic_InitText(&menu, menu_pos, menu_area, ASCII_8x16);
 *
 *     // Draw title
 *     CFBDGraphic_SetText(&title, "MENU");
 *     CFBDGraphic_DrawText(device, &title, CCGraphic_AsciiTextItem_AppendContinously);
 *
 *     // Draw menu items
 *     CFBDGraphic_SetText(&menu, "Start");
 *     CFBDGraphic_DrawText(device, &menu, CCGraphic_AsciiTextItem_AppendContinously);
 *
 *     CFBDGraphic_SetText(&menu, "Settings");
 *     CFBDGraphic_DrawText(device, &menu, CCGraphic_AsciiTextItem_AppendNextLine);
 *
 *     CFBDGraphic_SetText(&menu, "About");
 *     CFBDGraphic_DrawText(device, &menu, CCGraphic_AsciiTextItem_AppendNextLine);
 *
 *     CFBDGraphic_SetText(&menu, "Exit");
 *     CFBDGraphic_DrawText(device, &menu, CCGraphic_AsciiTextItem_AppendNextLine);
 *
 *     // Update display
 *     device->ops->update(device);
 * }
 *
 * void display_score(CFBD_GraphicDevice* device, int score) {
 *     CFBDGraphic_Text score_text;
 *     CFBDGraphic_Point pos = {80, 55};
 *     CFBDGraphicSize area = {48, 8};
 *     CFBDGraphic_InitText(&score_text, pos, area, ASCII_6x8);
 *
 *     char score_buf[12];
 *     sprintf(score_buf, "Score:%d", score);
 *     CFBDGraphic_SetText(&score_text, score_buf);
 *     CFBDGraphic_DrawText(device, &score_text, CCGraphic_AsciiTextItem_AppendContinously);
 *
 *     device->ops->update(device);
 * }
 * @endcode
 *
 * ---
 *
 * @section PART_III PART III: Widget System
 *
 * @section widget_intro Introduction to Graphics Widgets
 *
 * The Graphics Widget system provides reusable, customizable UI components
 * built on top of the core Graphics Device abstraction. Widgets include:
 *
 * - **Image** - Bitmap rendering at arbitrary positions
 * - **Menu** - Hierarchical item selection with navigation
 * - **ProgressBar** - Progress visualization with animation
 * - **Text** - Text rendering (documented in previous section)
 * - **Animation** - Frame-based timing framework
 *
 * @section widget_architecture Widget Architecture
 *
 * @verbatim
 *  ┌─────────────────────────────────────────────┐
 *  │      Graphics Widgets                       │
 *  ├─────────────────────────────────────────────┤
 *  │ Image | Menu | ProgressBar | Text          │
 *  └─────────────────────────────────────────────┘
 *  *  ┌─────────────────────────────────────────────┐
 *  │    Graphics Device Abstraction              │
 *  │  (immediate_draw, deferred_draw, update)    │
 *  └─────────────────────────────────────────────┘
 *  *  ┌─────────────────────────────────────────────┐
 *  │    Display Driver (OLED, LCD, etc.)         │
 *  │              Transport Layer                 │
 *  │              (I2C, SPI, GPIO)               │
 *  └─────────────────────────────────────────────┘
 * @endverbatim
 *
 * @section widget_design Design Principles
 *
 * - **No Dynamic Allocation** - All widgets use stack-allocated structures
 * - **Reference-Based** - Widgets reference device and data structures owned by caller
 * - **Operation Tables** - Callbacks enable polymorphic behavior without inheritance
 * - **Animation Support** - All visual widgets support frame-based animation
 * - **Flexible Drawing** - Immediate or deferred mode for optimization
 *
 * @section widget_animation_framework Animation Framework
 *
 * All widgets support frame-based animation through CFBD_BaseAnimation:
 *
 * @code
 * #include "graphic/widget/animation/animation.h"
 *
 * // Animation configuration
 * CFBD_BaseAnimation anim;
 * CFBD_InitBaseAnimation(&anim);
 * anim.anim_frames = 16;        // 16 frames
 * anim.anim_frame_delay_ms = 25; // 25ms per frame = ~400ms total
 *
 * // Typical frame counts:
 * // UI feedback: 4-8 frames
 * // Smooth transitions: 8-16 frames
 * // Detailed animations: 16-32 frames
 * @endcode
 *
 * @section widget_image_guide Image Widget
 *
 * @subsection image_overview Overview
 *
 * The Image widget renders bitmap data at specified positions. Images must be
 * pre-allocated as arrays, and the widget references this data.
 *
 * @subsection image_init Initialization
 *
 * @code
 * #include "graphic/widget/base_support/image.h"
 *
 * // Create bitmap data (32x32 pixels, 1 byte per pixel)
 * uint8_t logo_bitmap[128] = {
 *     0xFF, 0xFF, ...,  // Row 0
 *     0x00, 0xFF, ...,  // Row 1
 *     // ...
 * };
 *
 * // Initialize image
 * CCGraphic_Image logo;
 * CFBDGraphic_Point pos = {48, 16};      // X=48, Y=16
 * CFBDGraphicSize sz = {32, 32};        // 32x32 pixels
 * CFBDGraphic_InitImage(&logo, &pos, &sz, logo_bitmap);
 * @endcode
 *
 * @subsection image_drawing Drawing
 *
 * @code
 * // Draw image on graphics device
 * CFBDGraphic_DrawImage(graphics_device, &logo);
 *
 * // If in deferred mode, manually update
 * graphics_device->ops->update(graphics_device);
 * @endcode
 *
 * @section widget_menu_guide Menu Widget
 *
 * @subsection menu_overview Overview
 *
 * The Menu widget provides interactive list selection with:
 * - Keyboard navigation (next/previous item)
 * - Visual indicator bar showing current selection
 * - Callback support for item activation
 * - Animated transitions
 * - Configurable dimensions and fonts
 *
 * @subsection menu_init Initialization
 *
 * @code
 * #include "graphic/widget/menu/menu.h"
 * #include "graphic/widget/menu/menu_indicator.h"
 * #include "graphic/widget/animation/animation.h"
 *
 * // Pre-allocate menu items array
 * #define MAX_MENU_ITEMS 8
 * CFBD_MenuItem item_array[MAX_MENU_ITEMS];
 * CFBD_MenuItemGroup items = {
 *     .pItems = item_array,
 *     .capacity = MAX_MENU_ITEMS,
 *     .count = 0
 * };
 *
 * // Initialize menu
 * CFBD_Menu menu;
 * CFBDGraphic_Point menu_pos = {0, 0};
 * CFBD_InitMenu(&menu, graphics_device, &items, 128);
 * menu.tl_point = menu_pos;
 * @endcode
 *
 * @subsection menu_add_items Adding Items
 *
 * @code
 * // Callback when item selected
 * void on_start_game(void* ctx) {
 *     int* state = (int*)ctx;
 *     *state = STATE_RUNNING;
 * }
 *
 * // Configure indicator
 * CFBD_MenuIndicator indicator;
 * CFBD_InitDefaultMenuIndicator(&indicator);
 * indicator.width = 4;
 * menu.operations->set_indicator_property(&menu, &indicator);
 *
 * // Add menu items
 * CFBD_MenuItemCallbackPack cb = {on_start_game, &app_state};
 * menu.operations->add_item(&menu, "Start", ASCII_8x16, &cb);
 * menu.operations->add_item(&menu, "Settings", ASCII_8x16, NULL);
 * menu.operations->add_item(&menu, "About", ASCII_8x16, NULL);
 * @endcode
 *
 * @subsection menu_render Rendering
 *
 * @code
 * // Draw menu on graphics device
 * menu.operations->immediate_draw(&menu);
 * @endcode
 *
 * @subsection menu_nav Navigation
 *
 * @code
 * // Handle keyboard events
 * void on_up_button(CFBD_Menu* menu) {
 *     OLED_Menu_SelectPrev(menu);
 *     menu->operations->immediate_draw(menu);
 * }
 *
 * void on_down_button(CFBD_Menu* menu) {
 *     OLED_Menu_SelectNext(menu);
 *     menu->operations->immediate_draw(menu);
 * }
 *
 * void on_select_button(CFBD_Menu* menu) {
 *     menu->operations->activate_current(menu);
 * }
 * @endcode
 *
 * @subsection menu_animation Menu Animation
 *
 * @code
 * // Enable smooth transitions
 * CFBD_BaseAnimation anim = {
 *     .anim_frames = 8,
 *     .anim_frame_delay_ms = 30
 * };
 * menu.operations->set_animation(&menu, &anim);
 * @endcode
 *
 * @section widget_progressbar_guide ProgressBar Widget
 *
 * @subsection progressbar_overview Overview
 *
 * The ProgressBar widget visualizes numeric progress with:
 * - Configurable min/max value range
 * - Optional border and padding
 * - Animated fill transitions
 * - Custom properties via property map
 *
 * @subsection progressbar_init Initialization
 *
 * @code
 * #include "graphic/widget/progressbar/progressbar.h"
 *
 * // Create progress bar
 * CFBD_ProgressBar progress;
 * CFBDGraphic_Point pos = {10, 50};
 * CFBDGraphicSize sz = {108, 8};
 * CFBD_ProgressBar_Init(&progress, graphics_device, &pos, &sz, 0, 100);
 * @endcode
 *
 * @subsection progressbar_config Configuration
 *
 * @code
 * // Enable border
 * uint8_t border = 1;
 * progress.ops->set_property(&progress, "border", &border);
 *
 * // Set padding (space between border and fill)
 * uint8_t padding = 2;
 * progress.ops->set_property(&progress, "padding", &padding);
 *
 * // Configure animation
 * CFBD_BaseAnimation anim = {4, 50};  // 4 frames, 50ms each
 * progress.ops->set_property(&progress, "animation", &anim);
 * @endcode
 *
 * @subsection progressbar_update Progress Updates
 *
 * @code
 * // Update progress (0-100)
 * for (int value = 0; value <= 100; value += 5) {
 *     progress.ops->set_value(&progress, value);
 *     progress.ops->immediate_draw(&progress);
 *     HAL_Delay(100);
 * }
 * @endcode
 *
 * @section widget_best_practices Widget Best Practices
 *
 * @subsection bp_memory Memory Management
 *
 * - Pre-allocate all widget structures statically or on stack
 * - Pass pointers to graphics device and supporting data
 * - Ensure pointers remain valid for widget lifetime
 * - Use static arrays for menu items and bitmap data
 *
 * @subsection bp_performance Performance
 *
 * - Use deferred mode (request_updates = false) for batch widget updates
 * - Call device->ops->update() once after drawing multiple widgets
 * - Minimize animation frame delay for UI responsiveness (25-50ms recommended)
 * - Disable animations for constrained environments
 *
 * @subsection bp_drawing Drawing Order
 *
 * @code
 * // Recommended drawing order:
 * graphics->ops->clear(graphics);
 * CFBDGraphic_DrawImage(graphics, &bg_image);      // Background
 * menu.operations->immediate_draw(&menu);           // UI elements
 * progress.ops->immediate_draw(&progress);          // Foreground elements
 * graphics->ops->update(graphics);                  // Commit all changes
 * @endcode
 *
 * @subsection bp_error_handling Error Handling
 *
 * @code
 * // Always check return values
 * if (!graphics->ops->setPixel(graphics, x, y)) {
 *     // Handle coordinate out of bounds
 * }
 *
 * if (!menu.operations->add_item(&menu, "Item", size, &cb)) {
 *     // Handle menu full (no more item slots)
 * }
 *
 * if (!progress.ops->set_property(&progress, "unknown", NULL)) {
 *     // Handle unknown property
 * }
 * @endcode
 *
 * @section widget_complete_example Complete Widget Integration
 *
 * @code
 * #include "graphic/device/graphic_device.h"
 * #include "graphic/device/oled/oled_graphic_device.h"
 * #include "graphic/widget/base_support/image.h"
 * #include "graphic/widget/menu/menu.h"
 * #include "graphic/widget/progressbar/progressbar.h"
 *
 * // Global state
 * int app_state = STATE_MENU;
 * int selected_game = 0;
 * int progress_percent = 0;
 *
 * // Callback for menu selection
 * void on_game_selected(void* ctx) {
 *     int* state = (int*)ctx;
 *     *state = STATE_LOADING;
 * }
 *
 * void main(void) {
 *     // Initialize OLED
 *     CFBD_OLED oled;
 *     CFBD_OLED_IICInitsParams iic = {
 *         .device_address = SSD1309_DRIVER_ADDRESS,
 *         .i2c_handle = i2c_interface,
 *     };
 *     CFBD_GetOLEDHandle(&oled, CFBD_OLEDDriverType_IIC, &iic, CFBD_TRUE);
 *     oled.ops->open(&oled);
 *
 *     // Bind graphics device
 *     CFBD_GraphicDevice graphics;
 *     CFBDGraphic_BindOLEDAsDevice(&graphics, &oled);
 *     graphics.ops->open(&graphics);
 *     CFBDGraphic_DeviceSetIfRequestUpdateAtOnce(&graphics, CFBD_FALSE);
 *
 *     // Setup menu
 *     CFBD_MenuItem items[4];
 *     CFBD_MenuItemGroup item_group = {items, 4, 0};
 *     CFBD_Menu menu;
 *     CFBD_InitMenu(&menu, &graphics, &item_group, 128);
 *
 *     CFBD_MenuItemCallbackPack cb = {on_game_selected, &app_state};
 *     menu.operations->add_item(&menu, "Tetris", ASCII_8x16, &cb);
 *     menu.operations->add_item(&menu, "Breakout", ASCII_8x16, &cb);
 *     menu.operations->add_item(&menu, "Settings", ASCII_8x16, NULL);
 *
 *     // Setup progress bar for loading
 *     CFBD_ProgressBar progress;
 *     CFBDGraphic_Point prog_pos = {10, 50};
 *     CFBDGraphicSize prog_sz = {108, 8};
 *     CFBD_ProgressBar_Init(&progress, &graphics, &prog_pos, &prog_sz, 0, 100);
 *
 *     uint8_t border = 1, padding = 1;
 *     progress.ops->set_property(&progress, "border", &border);
 *     progress.ops->set_property(&progress, "padding", &padding);
 *
 *     // Main loop
 *     while (1) {
 *         switch (app_state) {
 *         case STATE_MENU:
 *             menu.operations->immediate_draw(&menu);
 *             handle_menu_input(&menu);
 *             break;
 *
 *         case STATE_LOADING:
 *             graphics.ops->clear(&graphics);
 *             CFBDGraphic_DrawImage(&graphics, &loading_image);
 *             for (int i = 0; i <= 100; i += 10) {
 *                 progress.ops->set_value(&progress, i);
 *                 progress.ops->immediate_draw(&progress);
 *                 graphics.ops->update(&graphics);
 *                 HAL_Delay(100);
 *             }
 *             app_state = STATE_GAME;
 *             break;
 *         }
 *     }
 * }
 * @endcode
 *
 * ---
 *
 * @section References Complete Documentation References
 *
 * - @ref Graphics_Device "Graphics Device Abstraction"
 * - @ref Graphics_Animation "Animation Framework"
 * - @ref Graphics_Helpers "Utility Helpers"
 * - @ref Graphics_Resources "Resource Configuration"
 * - @ref Graphics_Examples "Code Examples"
 * - @ref Graphics_Widget_Examples "Widget Examples"
 * - @ref Graphics_Complete_Examples "Complete Examples"
 */

Updated on 2026-02-03 at 13:21:55 +0000