Chapter 163 · XUI 弹出层与反馈

Carousel 轮播

Carousel 轮播控件,支持自动播放、循环切换、指示器、悬停箭头、页面切换回调。

163

概念

Carousel 是图片/内容轮播容器:
• Page:每页一个子控件(图片、面板等)
• AutoPlay:定时自动切换下一页
• Loop:末页→首页循环
• Indicators:底部圆点指示当前页
• Arrows:左右切换箭头(可悬停显示)

API 速查

函数说明
int xuiCarouselCreate(xui_context pCtx, xui_widget* ppW, const xui_carousel_desc_t* pDesc)创建轮播
int xuiCarouselSetPageCount(xui_widget pW, int iPageCount)设置页数
int xuiCarouselSetCurrent(xui_widget pW, int iIndex, int bNotify)跳转指定页
int xuiCarouselNext(xui_widget pW, int bNotify)下一页
int xuiCarouselPrev(xui_widget pW, int bNotify)上一页
int xuiCarouselSetAutoPlay(xui_widget pW, int bEnabled, float fInterval)自动播放
int xuiCarouselSetLoop(xui_widget pW, int bLoop)循环
int xuiCarouselSetIndicatorsVisible(xui_widget pW, int bVisible)指示器
int xuiCarouselSetArrowsOnHover(xui_widget pW, int bEnabled)悬停箭头
int xuiCarouselSetChange(xui_widget pW, xui_carousel_change_proc onChange, void* pUser)切换回调

编译本章示例

gcc -O2 -I. -o ch163.exe ch163_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch163.exe

示例:图片轮播

xui_carousel_desc_t desc = { 0 };

xui_widget pCarousel;
xuiCarouselCreate(pCtx, &pCarousel, &desc);

// 设置 5 页
xuiCarouselSetPageCount(pCarousel, 5);

// 自动播放:每 3 秒切换
xuiCarouselSetAutoPlay(pCarousel, 1, 3.0f);
xuiCarouselSetLoop(pCarousel, 1);

// 指示器 + 悬停箭头
xuiCarouselSetIndicatorsVisible(pCarousel, 1);
xuiCarouselSetArrowsOnHover(pCarousel, 1);

// 页面切换回调
xuiCarouselSetChange(pCarousel, OnPageChange, NULL);

static void OnPageChange(xui_widget pW, int iIndex, void* pUser) {
    xgeLogWrite("当前页: %d", iIndex);
}

xuiWidgetAddChild(pMainPanel, pCarousel);

完整代码

将以下代码保存为 ch163_main.c,编译后运行即可看到 Carousel 轮播效果:

#include "xge.h"
#include "xui.h"

static xui_context g_pCtx;

static void OnPageChange(xui_widget pW, int iIndex, void* pUser) {
    (void)pW; (void)pUser;
    xgeLogWrite("Carousel 当前页: %d", iIndex);
}

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x081114FF);
    xui_vec2_t pos; xgeMouseGet(&pos.x, &pos.y);
    xuiInputPointerMove(g_pCtx, pos.x, pos.y);
    if (xgeMouseDown(XGE_MOUSE_LEFT)) xuiInputPointerDown(g_pCtx, pos.x, pos.y, 0);
    else xuiInputPointerUp(g_pCtx, pos.x, pos.y, 0);
    xuiUpdate(g_pCtx, xgeGetDelta());
    xuiLayout(g_pCtx);
    xuiRender(g_pCtx, NULL, NULL, 0);
    return XGE_OK;
}

int main(void) {
    xge_desc_t d = {0};
    d.iWidth = 800; d.iHeight = 600;
    d.sTitle = "ch163 - Carousel";
    d.iFlags = XGE_INIT_VSYNC;
    xgeInit(&d);
    xuiCreate(&g_pCtx);
    /* XGE 官方代理由 xuiProxyXge() 提供 */
    xui_proxy_t tXgeProxy = xuiProxyXge();
xuiSetProxy(g_pCtx, &tXgeProxy);
    xuiSetViewportSize(g_pCtx, 800, 600);

    xui_widget pRoot;
    xuiPanelCreate(g_pCtx, &pRoot, NULL);
    xuiWidgetSetRect(pRoot, (xui_rect_t){0, 0, 800, 600});

    /* 轮播控件 */
    xui_carousel_desc_t cDesc = {0};
    xui_widget pCarousel;
    xuiCarouselCreate(g_pCtx, &pCarousel, &cDesc);
    xuiWidgetSetRect(pCarousel, (xui_rect_t){0, 0, 600, 300});
    xuiWidgetSetRect(pCarousel, (xui_rect_t){100, 100, 600, 300});
    xuiCarouselSetPageCount(pCarousel, 4);
    xuiCarouselSetAutoPlay(pCarousel, 1, 3.0f);
    xuiCarouselSetLoop(pCarousel, 1);
    xuiCarouselSetIndicatorsVisible(pCarousel, 1);
    xuiCarouselSetArrowsOnHover(pCarousel, 1);
    xuiCarouselSetChange(pCarousel, OnPageChange, NULL);
    xuiWidgetAddChild(pRoot, pCarousel);

    xgeRun(onFrame, NULL);
    xuiDestroy(g_pCtx);
    xgeUnit();
    return 0;
}

代码讲解

  • xuiCarouselCreate:创建轮播容器,设置尺寸和位置。
  • SetPageCount(4):设定 4 页,之后可向其中添加子控件作为页面内容。
  • SetAutoPlay(1, 3.0f):每 3 秒自动切换下一页。
  • SetLoop(1):末页后循环回首页。
  • Indicators + Arrows:显示底部圆点指示器和悬停箭头。

要点与陷阱

  • bNotify:SetCurrent/Next/Prev 的 bNotify 控制是否触发 onChange。
  • Interval:自动播放间隔单位秒,鼠标悬停时暂停。
  • Loop:关闭循环时末页不显示"下一页"箭头。
  • 子控件:通过 SetPageCount 后向 Carousel 添加对应数量子控件。

进阶练习

  1. 广告轮播:5 张 Banner + 自动播放 + 点击跳转链接。
  2. 引导页:首次启动全屏 Carousel + 末页"开始使用"按钮。
Carousel 轮播效果
图:Carousel 轮播渲染效果