跳转至

Graphics Framework - Complete Code Examples

        • Comprehensive code examples demonstrating all graphics subsystem features,
  • organized by functional area: device setup, drawing operations, text widgets,
  • and complex UI compositions.

PART 1: Graphics Device Foundation

Basic Graphics Device Setup

    • The simplest example showing graphics device initialization:
* #include "graphic_device.h"
* #include "oled_graphic_device.h"
* #include "oled.h"
*
* void example_basic_graphics_setup(void) {
*     // Initialize OLED display
*     CFBD_OLED oled;
*     CFBD_OLED_IICInitsParams iic_params = {
*         .device_address = SSD1309_DRIVER_ADDRESS,
*         .i2c_handle = get_i2c_interface(),
*     };
*
*     CFBD_GetOLEDHandle(&oled, CFBD_OLEDDriverType_IIC, &iic_params, CFBD_TRUE);
*     oled.ops->open(&oled);
*
*     // Create graphics device and bind to OLED
*     CFBD_GraphicDevice graphics;
*     CFBDGraphic_BindOLEDAsDevice(&graphics, &oled);
*     graphics.ops->open(&graphics);
*
*     // Graphics device is now ready to use
* }
* 

Immediate Drawing Mode

    • Drawing with immediate updates after each operation:
* void example_immediate_drawing(CFBD_GraphicDevice* graphics) {
*     // Enable immediate draw mode
*     CFBDGraphic_DeviceSetIfRequestUpdateAtOnce(graphics, CFBD_TRUE);
*
*     // Clear display (immediate update)
*     graphics->ops->clear(graphics);
*
*     // Each pixel is visible immediately
*     for (uint16_t x = 0; x < 128; x += 2) {
*         graphics->ops->setPixel(graphics, x, 32);
*         // Display updates automatically
*     }
* }
* 

Deferred Drawing Mode

    • Batch drawing operations for better performance:
* void example_deferred_drawing(CFBD_GraphicDevice* graphics) {
*     // Enable deferred mode (batch operations)
*     CFBDGraphic_DeviceSetIfRequestUpdateAtOnce(graphics, CFBD_FALSE);
*
*     // Clear display (buffered)
*     graphics->ops->clear(graphics);
*
*     // Draw multiple pixels without updating display
*     for (uint16_t y = 0; y < 64; y += 4) {
*         for (uint16_t x = 0; x < 128; x += 4) {
*             graphics->ops->setPixel(graphics, x, y);
*         }
*     }
*
*     // Update display once with all changes
*     graphics->ops->update(graphics);
* }
* 

Area-Based Drawing

    • Efficient rectangular area operations:
* void example_area_operations(CFBD_GraphicDevice* graphics) {
*     uint8_t bitmap[32] = {0};  // 16x16 pixel bitmap
*
*     // Draw bitmap to area
*     graphics->ops->setArea(graphics, 56, 24, 16, 16, bitmap);
*
*     // Update only affected area
*     graphics->ops->update_area(graphics, 56, 24, 16, 16);
* }
* 

Query Device Properties

    • Getting display capabilities:
* void example_query_device(CFBD_GraphicDevice* graphics) {
*     uint16_t width = 0, height = 0;
*     CFBD_bool is_rgb = CFBD_FALSE;
*
*     // Query display dimensions
*     graphics->ops->self_consult(graphics, "width", NULL, &width);
*     graphics->ops->self_consult(graphics, "height", NULL, &height);
*
*     // Query color capability
*     graphics->ops->self_consult(graphics, "rgb", NULL, &is_rgb);
*
*     printf("Display: %u x %u %s\n",
*            width, height,
*            is_rgb ? "RGB" : "Monochrome");
* }
* 

Dynamic Mode Switching

    • Switching between immediate and deferred modes:
* void example_mode_switching(CFBD_GraphicDevice* graphics) {
*     // Check current mode
*     if (CFBDGraphic_DeviceRequestUpdateAtOnce(graphics)) {
*         printf("Currently in immediate mode\n");
*     } else {
*         printf("Currently in deferred mode\n");
*     }
*
*     // Switch to deferred mode
*     CFBDGraphic_DeviceSetIfRequestUpdateAtOnce(graphics, CFBD_FALSE);
*
*     // Perform batch operations
*     for (int i = 0; i < 100; i++) {
*         graphics->ops->setPixel(graphics, i, 32);
*     }
*     graphics->ops->update(graphics);
*
*     // Switch back to immediate
*     CFBDGraphic_DeviceSetIfRequestUpdateAtOnce(graphics, CFBD_TRUE);
* }
* 

Clear Display Utility

    • Using the clear immediate convenience function:
* void example_clear_immediate(CFBD_GraphicDevice* graphics) {
*     // Clear entire display with single operation
*     CFBDGraphic_DeviceClearImmediate(graphics);
*
*     // Equivalent to:
*     // graphics->ops->clear(graphics);
*     // graphics->ops->update(graphics);
* }
* 

PART 2: Animation and Rendering

Animated Frame Rendering

    • Smooth animation with frame-based timing:
* void example_animated_frames(CFBD_GraphicDevice* graphics) {
*     CFBD_BaseAnimation anim;
*     CFBD_InitBaseAnimation(&anim);
*     anim.anim_frames = 16;
*     anim.anim_frame_delay_ms = 50;
*
*     // Disable immediate mode for batch updates
*     CFBDGraphic_DeviceSetIfRequestUpdateAtOnce(graphics, CFBD_FALSE);
*
*     for (uint8_t frame = 0; frame < anim.anim_frames; frame++) {
*         graphics->ops->clear(graphics);
*
*         // Draw frame-dependent content
*         uint16_t y = 16 + (frame * 3);  // Animate Y position
*         graphics->ops->setPixel(graphics, 64, y);
*
*         graphics->ops->update(graphics);
*
*         if (anim.anim_frame_delay_ms > 0) {
*             HAL_Delay(anim.anim_frame_delay_ms);
*         }
*     }
* }
* 

Complete Animated Scene

    • Full example combining multiple concepts:
* #include "graphic_device.h"
* #include "oled_graphic_device.h"
* #include "oled.h"
* #include "widget/animation/animation.h"
* #include "widget/base_support/common/helpers.h"
*
* void example_complete_animation(void) {
*     // Initialize OLED
*     CFBD_OLED oled;
*     CFBD_OLED_IICInitsParams iic_params = {
*         .device_address = SSD1309_DRIVER_ADDRESS,
*         .i2c_handle = get_i2c_interface(),
*     };
*     CFBD_GetOLEDHandle(&oled, CFBD_OLEDDriverType_IIC, &iic_params, 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;
*
*     // Animate bouncing ball
*     for (uint8_t frame = 0; frame < anim.anim_frames; frame++) {
*         graphics.ops->clear(&graphics);
*
*         // Calculate position
*         int16_t x = 64 + 30 * (frame % 4) - 45;
*         int16_t y = 32 + (frame * 2);
*
*         // Clamp to display bounds
*         x = clamp_i32(x, 0, 127);
*         y = clamp_i32(y, 0, 63);
*
*         // Draw ball
*         graphics.ops->setPixel(&graphics, x, y);
*         graphics.ops->update(&graphics);
*
*         HAL_Delay(anim.anim_frame_delay_ms);
*     }
*
*     // Cleanup
*     graphics.ops->close(&graphics);
*     oled.ops->close(&oled);
* }
* 

Using Utility Functions

    • Applying helper utilities in graphics code:
* #include "widget/base_support/common/helpers.h"
*
* void example_utility_functions(CFBD_GraphicDevice* graphics) {
*     int width = 128, height = 64;
*
*     // Clamp coordinate to valid range
*     int user_x = get_user_input();
*     int x = clamp_i32(user_x, 0, width - 1);
*
*     // Find center
*     int center_x = MAX(0, width / 2);
*     int center_y = MIN(64, height / 2);
*
*     // Draw centered point
*     graphics->ops->setPixel(graphics, center_x, center_y);
*     graphics->ops->update(graphics);
* }
* 

Resource Configuration

    • Configuring graphics resources:
* // In your project, before including graphics headers:
*
* // Option 1: Keep all defaults
* #include "graphic/resource/config.h"
*
* // Option 2: Disable all, then enable selectively
* #define _USE_NO_DEFAULT_SOURCES
* #include "graphic/resource/config.h"
*
* // Option 3: Disable specific resources
* #define DISABLE_ASCII_6X8_SOURCES
* #include "graphic/resource/config.h"
* // Now only 8x16 font is available
* 

PART 3: Text Widget Examples

Basic Text Rendering

    • Simple text display on graphics device:
* void example_basic_text(CFBD_GraphicDevice* dev) {
*     CFBDGraphic_Text text;
*     CFBDGraphic_Point pos = {0, 0};
*     CFBDGraphicSize area = {128, 16};
*     CFBDGraphic_InitText(&text, pos, area, ASCII_8x16);
*
*     CFBDGraphic_SetText(&text, "Hello!");
*     CFBDGraphic_DrawText(dev, &text, CCGraphic_AsciiTextItem_AppendContinously);
*
*     dev->ops->update(dev);
* }
* 

Multiple Text Elements

    • Rendering multiple independent text widgets:
* void example_multiple_texts(CFBD_GraphicDevice* dev) {
*     CFBDGraphic_Text title, status;
*
*     // Title at top
*     CFBDGraphic_Point title_pos = {0, 0};
*     CFBDGraphicSize title_area = {128, 16};
*     CFBDGraphic_InitText(&title, title_pos, title_area, ASCII_8x16);
*     CFBDGraphic_SetText(&title, "Game Status");
*     CFBDGraphic_DrawText(dev, &title, CCGraphic_AsciiTextItem_AppendContinously);
*
*     // Status at bottom
*     CFBDGraphic_Point status_pos = {0, 50};
*     CFBDGraphicSize status_area = {128, 14};
*     CFBDGraphic_InitText(&status, status_pos, status_area, ASCII_6x8);
*     CFBDGraphic_SetText(&status, "Running... 60FPS");
*     CFBDGraphic_DrawText(dev, &status, CCGraphic_AsciiTextItem_AppendContinously);
*
*     dev->ops->update(dev);
* }
* 

Multiline Text with Breaks

    • Multiple lines with explicit line breaks:
* void example_multiline_text(CFBD_GraphicDevice* dev) {
*     CFBDGraphic_Text text;
*     CFBDGraphic_Point pos = {0, 0};
*     CFBDGraphicSize area = {128, 64};
*     CFBDGraphic_InitText(&text, pos, area, ASCII_8x16);
*
*     // First line
*     CFBDGraphic_SetText(&text, "Line 1");
*     CFBDGraphic_DrawText(dev, &text, CCGraphic_AsciiTextItem_AppendContinously);
*
*     // Second line
*     CFBDGraphic_SetText(&text, "Line 2");
*     CFBDGraphic_DrawText(dev, &text, CCGraphic_AsciiTextItem_AppendNextLine);
*
*     // Third line
*     CFBDGraphic_SetText(&text, "Line 3");
*     CFBDGraphic_DrawText(dev, &text, CCGraphic_AsciiTextItem_AppendNextLine);
*
*     dev->ops->update(dev);
* }
* 

Continuous Text with Auto-Wrap

    • Text that wraps automatically:
* void example_continuous_text(CFBD_GraphicDevice* dev) {
*     CFBDGraphic_Text text;
*     CFBDGraphic_Point pos = {0, 0};
*     CFBDGraphicSize area = {128, 64};
*     CFBDGraphic_InitText(&text, pos, area, ASCII_6x8);
*
*     // Long text automatically wraps
*     CFBDGraphic_SetText(&text, "This is a long text that will wrap");
*     CFBDGraphic_DrawText(dev, &text, CCGraphic_AsciiTextItem_AppendContinously);
*
*     dev->ops->update(dev);
* }
* 

Dynamic Text with sprintf

    • Formatted text with variables:
* void example_dynamic_text(CFBD_GraphicDevice* dev, int score, int lives) {
*     CFBDGraphic_Text text;
*     CFBDGraphic_Point pos = {0, 55};
*     CFBDGraphicSize area = {128, 8};
*     CFBDGraphic_InitText(&text, pos, area, ASCII_6x8);
*
*     char buffer[32];
*     sprintf(buffer, "Score:%d Lives:%d", score, lives);
*     CFBDGraphic_SetText(&text, buffer);
*     CFBDGraphic_DrawText(dev, &text, CCGraphic_AsciiTextItem_AppendContinously);
*
*     dev->ops->update(dev);
* }
* 

Font Selection with Config

    • Conditional font usage based on compile-time configuration:
* void example_font_selection(CFBD_GraphicDevice* dev) {
*     CFBDGraphic_Text text;
*     CFBDGraphic_Point pos = {0, 0};
*     CFBDGraphicSize area = {128, 20};
*
* #if ENABLE_ASCII_8x16_SOURCES
*     CFBDGraphic_InitText(&text, pos, area, ASCII_8x16);
*     CFBDGraphic_SetText(&text, "Large Text");
* #elif ENABLE_ASCII_6x8_SOURCES
*     CFBDGraphic_InitText(&text, pos, area, ASCII_6x8);
*     CFBDGraphic_SetText(&text, "Small Text");
* #else
*     printf("No ASCII fonts available\n");
*     return;
* #endif
*
*     CFBDGraphic_DrawText(dev, &text, CCGraphic_AsciiTextItem_AppendContinously);
*     dev->ops->update(dev);
* }
* 

Querying Text Metrics

    • Get text size without rendering:
* void example_text_metrics(CFBD_GraphicDevice* dev) {
*     CFBDGraphic_Text text;
*     CFBDGraphic_Point pos = {0, 0};
*     CFBDGraphicSize area = {128, 64};
*     CFBDGraphic_InitText(&text, pos, area, ASCII_8x16);
*
*     // Query text size
*     CFBDGraphicSize font_size = __fetch_font_size(ASCII_8x16);
*     printf("Font size: %u x %u pixels\n", font_size.width, font_size.height);
*
*     // Query next position without drawing
*     CFBDGraphic_SetText(&text, "Sample");
*     CFBDGraphic_Point end_pos = CFBDGraphic_DrawText(
*         dev, &text,
*         CCGraphic_AsciiTextItem_RequestOldPoint
*     );
*     printf("Text would end at (%u, %u)\n", end_pos.x, end_pos.y);
* }
* 

Repositioning Text

    • Dynamic repositioning of text elements:
* void example_reposition_text(CFBD_GraphicDevice* dev) {
*     CFBDGraphic_Text text;
*     CFBDGraphic_Point pos = {0, 0};
*     CFBDGraphicSize area = {128, 32};
*     CFBDGraphic_InitText(&text, pos, area, ASCII_8x16);
*
*     CFBDGraphic_SetText(&text, "Hello");
*
*     // Draw at original position
*     CFBDGraphic_DrawText(dev, &text, CCGraphic_AsciiTextItem_AppendContinously);
*     dev->ops->update(dev);
*     HAL_Delay(500);
*
*     // Move to new position
*     CFBDGraphic_Point new_pos = {30, 25};
*     CFBDGraphic_SetTextTLPointPoint(&text, &new_pos);
*
*     dev->ops->clear(dev);
*     CFBDGraphic_DrawText(dev, &text, CCGraphic_AsciiTextItem_AppendContinously);
*     dev->ops->update(dev);
* }
* 

Centered Text

    • Centering text horizontally:
* void example_centered_text(CFBD_GraphicDevice* dev, const char* text_str) {
*     CFBDGraphicSize font_size = __fetch_font_size(ASCII_8x16);
*
*     // Calculate text width
*     size_t text_len = strlen(text_str);
*     int text_width = text_len * (font_size.width + CFBDGraphic_TEXT_PADDING_WIDTH);
*
*     // Center horizontally (128 pixel display)
*     int center_x = (128 - text_width) / 2;
*     CFBDGraphic_Point pos = {center_x, 25};
*
*     CFBDGraphic_Text text;
*     CFBDGraphicSize area = {text_width + 5, 16};
*     CFBDGraphic_InitText(&text, pos, area, ASCII_8x16);
*     CFBDGraphic_SetText(&text, (char*)text_str);
*     CFBDGraphic_DrawText(dev, &text, CCGraphic_AsciiTextItem_AppendContinously);
*
*     dev->ops->update(dev);
* }
* 

Scrolling Text Effect

    • Horizontal text scrolling:
* void example_scrolling_text(CFBD_GraphicDevice* dev) {
*     const char* text_str = "Scrolling Text Example";
*     CFBDGraphicSize font_size = __fetch_font_size(ASCII_8x16);
*     int text_width = strlen(text_str) * (font_size.width + 1);
*
*     // Scroll from right to left
*     for (int x = 128; x > -text_width; x -= 2) {
*         CFBDGraphic_Text text;
*         CFBDGraphic_Point pos = {x, 25};
*         CFBDGraphicSize area = {text_width + 5, 16};
*         CFBDGraphic_InitText(&text, pos, area, ASCII_8x16);
*         CFBDGraphic_SetText(&text, (char*)text_str);
*
*         dev->ops->clear(dev);
*         CFBDGraphic_DrawText(dev, &text, CCGraphic_AsciiTextItem_AppendContinously);
*         dev->ops->update(dev);
*
*         HAL_Delay(50);
*     }
* }
* 

PART 4: Graphics Widget Examples (Image, Menu, Progress Bar)

Basic Image Drawing

    • Simple bitmap rendering:
* void example_draw_bitmap(CFBD_GraphicDevice* dev) {
*     uint8_t heart_bitmap[64] = {
*         0x00, 0x00, 0x00, 0x00,
*         0x66, 0x99, 0x99, 0x66,
*         0xFF, 0xFF, 0xFF, 0xFF,
*         0xFF, 0xFF, 0xFF, 0xFF,
*         // ... (16x16 bitmap)
*     };
*
*     CCGraphic_Image heart;
*     CFBDGraphic_Point pos = {56, 24};
*     CFBDGraphicSize size = {16, 16};
*     CFBDGraphic_InitImage(&heart, &pos, &size, heart_bitmap);
*
*     dev->ops->clear(dev);
*     CFBDGraphic_DrawImage(dev, &heart);
*     dev->ops->update(dev);
* }
* 

Animated Image Transitions

    • Multiple images with frame-based animation:
* void example_animated_image(CFBD_GraphicDevice* dev) {
*     CCGraphic_Image frames[4];
*     uint8_t frame_data[4][64] = {...};  // 4 animation frames
*     CFBDGraphic_Point pos = {48, 24};
*     CFBDGraphicSize size = {32, 16};
*
*     // Initialize all frames
*     for (int i = 0; i < 4; i++) {
*         CFBDGraphic_InitImage(&frames[i], &pos, &size, frame_data[i]);
*     }
*
*     // Animate through frames
*     CFBD_BaseAnimation anim = {4, 100};  // 4 frames, 100ms each
*     for (uint8_t frame = 0; frame < anim.anim_frames; frame++) {
*         dev->ops->clear(dev);
*         CFBDGraphic_DrawImage(dev, &frames[frame % 4]);
*         dev->ops->update(dev);
*         HAL_Delay(anim.anim_frame_delay_ms);
*     }
* }
* 

Basic Menu

    • Minimal menu with 3 items:
* void on_item_selected(void* ctx) {
*     printf("Item selected!\n");
* }
*
* void example_simple_menu(CFBD_GraphicDevice* dev) {
*     // Allocate item array
*     CFBD_MenuItem items[3];
*     CFBD_MenuItemGroup item_group = {items, 3, 0};
*
*     // Initialize menu
*     CFBD_Menu menu;
*     CFBD_InitMenu(&menu, dev, &item_group, 128);
*
*     // Add items
*     CFBD_MenuItemCallbackPack cb = {on_item_selected, NULL};
*     menu.operations->add_item(&menu, "Start", ASCII_8x16, &cb);
*     menu.operations->add_item(&menu, "Options", ASCII_8x16, NULL);
*     menu.operations->add_item(&menu, "Exit", ASCII_8x16, NULL);
*
*     // Draw menu
*     menu.operations->immediate_draw(&menu);
* }
* 

Interactive Menu Navigation

    • Simulated keyboard input and menu selection:
* void example_menu_navigation(CFBD_GraphicDevice* dev) {
*     // Setup menu (from previous example)
*     CFBD_MenuItem items[5];
*     CFBD_MenuItemGroup item_group = {items, 5, 0};
*     CFBD_Menu menu;
*     CFBD_InitMenu(&menu, dev, &item_group, 128);
*
*     for (int i = 0; i < 5; i++) {
*         char label[16];
*         sprintf(label, "Item %d", i + 1);
*         menu.operations->add_item(&menu, label, ASCII_6x8, NULL);
*     }
*
*     // Simulate navigation
*     menu.operations->immediate_draw(&menu);
*
*     // Down arrow - move to next item
*     OLED_Menu_SelectNext(&menu);
*     menu.operations->immediate_draw(&menu);
*     HAL_Delay(300);
*
*     // Down arrow again
*     OLED_Menu_SelectNext(&menu);
*     menu.operations->immediate_draw(&menu);
*     HAL_Delay(300);
*
*     // Up arrow - move to previous
*     OLED_Menu_SelectPrev(&menu);
*     menu.operations->immediate_draw(&menu);
*     HAL_Delay(300);
*
*     // Enter - activate current item
*     menu.operations->activate_current(&menu);
* }
* 
    • Menu with styled selection indicator:
* void example_menu_with_indicator(CFBD_GraphicDevice* dev) {
*     CFBD_MenuItem items[4];
*     CFBD_MenuItemGroup item_group = {items, 4, 0};
*     CFBD_Menu menu;
*     CFBD_InitMenu(&menu, dev, &item_group, 120);
*
*     // Configure indicator
*     CFBD_MenuIndicator indicator;
*     CFBD_InitDefaultMenuIndicator(&indicator);
*     indicator.width = 6;      // 6-pixel wide indicator
*     indicator.x = 2;          // 2 pixels from left edge
*     menu.operations->set_indicator_property(&menu, &indicator);
*
*     // Add items with callbacks
*     CFBD_MenuItemCallbackPack cb1 = {on_item_selected, (void*)1};
*     CFBD_MenuItemCallbackPack cb2 = {on_item_selected, (void*)2};
*     menu.operations->add_item(&menu, "Play", ASCII_8x16, &cb1);
*     menu.operations->add_item(&menu, "Settings", ASCII_8x16, &cb2);
*     menu.operations->add_item(&menu, "About", ASCII_8x16, NULL);
*     menu.operations->add_item(&menu, "Exit", ASCII_8x16, NULL);
*
*     // Draw
*     menu.operations->immediate_draw(&menu);
* }
* 
    • Menu with animated selection changes:
* void example_animated_menu(CFBD_GraphicDevice* dev) {
*     CFBD_MenuItem items[3];
*     CFBD_MenuItemGroup item_group = {items, 3, 0};
*     CFBD_Menu menu;
*     CFBD_InitMenu(&menu, dev, &item_group, 128);
*
*     menu.operations->add_item(&menu, "One", ASCII_8x16, NULL);
*     menu.operations->add_item(&menu, "Two", ASCII_8x16, NULL);
*     menu.operations->add_item(&menu, "Three", ASCII_8x16, NULL);
*
*     // Enable animation
*     CFBD_BaseAnimation anim = {6, 40};  // 6 frames, 40ms per frame
*     menu.operations->set_animation(&menu, &anim);
*
*     // Navigate with visual feedback
*     for (int i = 0; i < 3; i++) {
*         OLED_Menu_SelectNext(&menu);
*         for (int f = 0; f < anim.anim_frames; f++) {
*             menu.operations->immediate_draw(&menu);
*             HAL_Delay(anim.anim_frame_delay_ms);
*         }
*     }
* }
* 

Simple Progress Bar

    • Basic progress bar with fill animation:
* void example_progress_bar(CFBD_GraphicDevice* dev) {
*     CFBD_ProgressBar progress;
*     CFBDGraphic_Point pos = {10, 32};
*     CFBDGraphicSize size = {108, 8};
*     CFBD_ProgressBar_Init(&progress, dev, &pos, &size, 0, 100);
*
*     // Draw at different values
*     for (int val = 0; val <= 100; val += 10) {
*         dev->ops->clear(dev);
*         progress.ops->set_value(&progress, val);
*         progress.ops->immediate_draw(&progress);
*         dev->ops->update(dev);
*         HAL_Delay(100);
*     }
* }
* 

Progress Bar with Border

    • Styled progress bar with border and padding:
* void example_styled_progress(CFBD_GraphicDevice* dev) {
*     CFBD_ProgressBar progress;
*     CFBDGraphic_Point pos = {10, 32};
*     CFBDGraphicSize size = {108, 10};
*     CFBD_ProgressBar_Init(&progress, dev, &pos, &size, 0, 100);
*
*     // Enable border and padding
*     uint8_t border = 1;
*     progress.ops->set_property(&progress, "border", &border);
*     uint8_t padding = 1;
*     progress.ops->set_property(&progress, "padding", &padding);
*
*     // Animate from 0 to 100
*     for (int val = 0; val <= 100; val += 5) {
*         dev->ops->clear(dev);
*         progress.ops->set_value(&progress, val);
*         progress.ops->immediate_draw(&progress);
*         dev->ops->update(dev);
*         HAL_Delay(50);
*     }
* }
* 

Progress Bar with Transitions

    • Progress bar with frame-based animation:
* void example_animated_progress(CFBD_GraphicDevice* dev) {
*     CFBD_ProgressBar progress;
*     CFBDGraphic_Point pos = {10, 32};
*     CFBDGraphicSize size = {108, 8};
*     CFBD_ProgressBar_Init(&progress, dev, &pos, &size, 0, 100);
*
*     // Configure animation
*     CFBD_BaseAnimation anim = {4, 50};  // 4-frame, 50ms transitions
*     progress.ops->set_property(&progress, "animation", &anim);
*
*     // Smooth progress animation
*     for (int target = 10; target <= 100; target += 10) {
*         for (int frame = 0; frame < anim.anim_frames; frame++) {
*             int current = (progress.value * (anim.anim_frames - frame) +
*                           target * frame) / anim.anim_frames;
*             dev->ops->clear(dev);
*             progress.ops->set_value(&progress, current);
*             progress.ops->immediate_draw(&progress);
*             dev->ops->update(dev);
*             HAL_Delay(anim.anim_frame_delay_ms);
*         }
*     }
* }
* 

PART 5: Complex UI Compositions

    • Text-based menu display:
* void example_menu_text(CFBD_GraphicDevice* dev) {
*     CFBDGraphic_Text menu;
*     CFBDGraphic_Point pos = {10, 10};
*     CFBDGraphicSize area = {108, 54};
*     CFBDGraphic_InitText(&menu, pos, area, ASCII_8x16);
*
*     dev->ops->clear(dev);
*
*     // Title
*     CFBDGraphic_SetText(&menu, "MENU");
*     CFBDGraphic_DrawText(dev, &menu, CCGraphic_AsciiTextItem_AppendContinously);
*
*     // Menu items
*     const char* items[] = {"Start", "Settings", "Exit"};
*     for (int i = 0; i < 3; i++) {
*         char item_text[16];
*         sprintf(item_text, "%d. %s", i + 1, items[i]);
*         CFBDGraphic_SetText(&menu, item_text);
*         CFBDGraphic_DrawText(dev, &menu, CCGraphic_AsciiTextItem_AppendNextLine);
*     }
*
*     dev->ops->update(dev);
* }
* 

Complete UI with Mixed Text

    • Complex interface combining multiple text elements:
* void example_complete_ui(CFBD_GraphicDevice* dev, int score, int level) {
*     CFBDGraphic_Text title, body, footer;
*
*     // Title
*     CFBDGraphic_Point title_pos = {0, 0};
*     CFBDGraphicSize title_size = {128, 16};
*     CFBDGraphic_InitText(&title, title_pos, title_size, ASCII_8x16);
*     CFBDGraphic_SetText(&title, "Game Screen");
*     CFBDGraphic_DrawText(dev, &title, CCGraphic_AsciiTextItem_AppendContinously);
*
*     // Body text
*     CFBDGraphic_Point body_pos = {0, 20};
*     CFBDGraphicSize body_size = {128, 36};
*     CFBDGraphic_InitText(&body, body_pos, body_size, ASCII_6x8);
*     CFBDGraphic_SetText(&body, "Level in progress...");
*     CFBDGraphic_DrawText(dev, &body, CCGraphic_AsciiTextItem_AppendContinously);
*
*     // Footer with stats
*     CFBDGraphic_Point footer_pos = {0, 55};
*     CFBDGraphicSize footer_size = {128, 8};
*     CFBDGraphic_InitText(&footer, footer_pos, footer_size, ASCII_6x8);
*     char footer_text[32];
*     sprintf(footer_text, "Score:%d Level:%d", score, level);
*     CFBDGraphic_SetText(&footer, footer_text);
*     CFBDGraphic_DrawText(dev, &footer, CCGraphic_AsciiTextItem_AppendContinously);
*
*     dev->ops->update(dev);
* }
* 

Multiple Widgets Together

    • Complex UI with image, menu, and progress bar:
* // Global state
* typedef enum {
*     SCREEN_MENU,
*     SCREEN_LOADING,
*     SCREEN_GAME
* } ScreenState;
*
* void example_multi_widget_ui(CFBD_GraphicDevice* dev) {
*     ScreenState screen = SCREEN_MENU;
*
*     // Setup menu
*     CFBD_MenuItem items[3];
*     CFBD_MenuItemGroup item_group = {items, 3, 0};
*     CFBD_Menu menu;
*     CFBD_InitMenu(&menu, dev, &item_group, 128);
*     menu.operations->add_item(&menu, "Start Game", ASCII_8x16, NULL);
*     menu.operations->add_item(&menu, "Settings", ASCII_8x16, NULL);
*     menu.operations->add_item(&menu, "Exit", ASCII_8x16, NULL);
*
*     // Setup progress bar for loading screen
*     CFBD_ProgressBar progress;
*     CFBDGraphic_Point prog_pos = {10, 50};
*     CFBDGraphicSize prog_sz = {108, 8};
*     CFBD_ProgressBar_Init(&progress, dev, &prog_pos, &prog_sz, 0, 100);
*     uint8_t border = 1;
*     progress.ops->set_property(&progress, "border", &border);
*
*     // Setup image for loading screen
*     uint8_t logo_bitmap[128] = {...};  // 32x32 logo
*     CCGraphic_Image logo;
*     CFBDGraphic_Point logo_pos = {48, 8};
*     CFBDGraphicSize logo_sz = {32, 32};
*     CFBDGraphic_InitImage(&logo, &logo_pos, &logo_sz, logo_bitmap);
*
*     while (1) {
*         switch (screen) {
*         case SCREEN_MENU:
*             dev->ops->clear(dev);
*             menu.operations->immediate_draw(&menu);
*             // Handle input to change screen
*             break;
*
*         case SCREEN_LOADING:
*             CFBDGraphic_DrawImage(dev, &logo);
*             for (int i = 0; i <= 100; i += 10) {
*                 progress.ops->set_value(&progress, i);
*                 progress.ops->immediate_draw(&progress);
*                 dev->ops->update(dev);
*                 HAL_Delay(100);
*             }
*             screen = SCREEN_GAME;
*             break;
*         }
*     }
* }
* 

Batch Drawing for Performance

    • Multiple widgets with deferred updates:
* void example_batch_widgets(CFBD_GraphicDevice* dev) {
*     // Enable deferred mode
*     CFBDGraphic_DeviceSetIfRequestUpdateAtOnce(dev, CFBD_FALSE);
*
*     // Setup widgets
*     CCGraphic_Image bg;
*     CFBDGraphic_InitImage(&bg, &(CFBDGraphic_Point){0, 0},
*                          &(CFBDGraphicSize){128, 64}, background_data);
*
*     CFBD_MenuItem items[2];
*     CFBD_MenuItemGroup item_group = {items, 2, 0};
*     CFBD_Menu menu;
*     CFBD_InitMenu(&menu, dev, &item_group, 128);
*     menu.operations->add_item(&menu, "Option 1", ASCII_6x8, NULL);
*     menu.operations->add_item(&menu, "Option 2", ASCII_6x8, NULL);
*
*     CFBD_ProgressBar progress;
*     CFBDGraphic_Point p = {20, 55};
*     CFBDGraphicSize s = {88, 6};
*     CFBD_ProgressBar_Init(&progress, dev, &p, &s, 0, 100);
*
*     // Draw all widgets, update only once
*     dev->ops->clear(dev);
*     CFBDGraphic_DrawImage(dev, &bg);
*     menu.operations->immediate_draw(&menu);
*     progress.ops->set_value(&progress, 75);
*     progress.ops->immediate_draw(&progress);
*     dev->ops->update(dev);  // Single update for all widgets
* }
* 

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