// ============================================================================ // block_palette.c - 积木面板实现 // ============================================================================ #include "block_palette.h" #include "block_renderer.h" #include #include #include void palette_init(BlockPalette* palette) { memset(palette, 0, sizeof(BlockPalette)); palette->width = 200; palette->height = 600; // 添加所有积木类型 int count; const BlockTypeInfo* all = block_type_get_all(&count); for (int i = 0; i < count; i++) { palette_add_block(palette, all[i].type); } } void palette_add_block(BlockPalette* palette, BlockType type) { const BlockTypeInfo* info = block_type_get_info(type); if (!info) return; // 查找或创建分类 for (int i = 0; i < palette->category_count; i++) { if (strcmp(palette->categories[i].name, info->category) == 0) { palette->categories[i].blocks[palette->categories[i].block_count++] = type; return; } } // 创建新分类 if (palette->category_count < MAX_PALETTE_CATEGORIES) { PaletteCategory* cat = &palette->categories[palette->category_count++]; strncpy(cat->name, info->category, 63); cat->blocks[cat->block_count++] = type; cat->expanded = 1; } } void palette_render(BlockPalette* palette, BlockRenderer* renderer) { // 绘制背景 block_renderer_add_quad(renderer, palette->x, palette->y, palette->width, palette->height, 0.15f, 0.15f, 0.18f, 1.0f); // 绘制标题 block_renderer_draw_text(renderer, "积木面板", palette->x + 5, palette->y + 5, 1.0f, 1.0f, 1.0f); float y = palette->y + 25 - palette->scroll_y; for (int c = 0; c < palette->category_count; c++) { PaletteCategory* cat = &palette->categories[c]; // 绘制分类标题 block_renderer_add_quad(renderer, palette->x + 2, y, palette->width - 4, 20, 0.25f, 0.25f, 0.3f, 1.0f); const char* arrow = cat->expanded ? "[-]" : "[+]"; char title[128]; snprintf(title, 128, "%s %s (%d)", arrow, cat->name, cat->block_count); block_renderer_draw_text(renderer, title, palette->x + 5, y + 3, 0.9f, 0.9f, 0.9f); y += 22; if (!cat->expanded) continue; // 绘制积木列表 for (int b = 0; b < cat->block_count; b++) { const BlockTypeInfo* info = block_type_get_info(cat->blocks[b]); if (!info) continue; // 搜索过滤 if (palette->search_active && palette->search_text[0]) { if (strstr(info->name, palette->search_text) == NULL && strstr(info->label, palette->search_text) == NULL) { continue; } } // 绘制积木预览 block_renderer_add_quad(renderer, palette->x + 5, y, palette->width - 10, 18, info->color.r, info->color.g, info->color.b, info->color.a); block_renderer_draw_text(renderer, info->label, palette->x + 10, y + 3, 1.0f, 1.0f, 1.0f); y += 20; } y += 5; } } BlockType palette_handle_click(BlockPalette* palette, float mx, float my) { float y = palette->y + 25 - palette->scroll_y; for (int c = 0; c < palette->category_count; c++) { PaletteCategory* cat = &palette->categories[c]; // 检查分类标题点击 if (mx >= palette->x && mx <= palette->x + palette->width && my >= y && my <= y + 20) { cat->expanded = !cat->expanded; return -1; } y += 22; if (!cat->expanded) continue; // 检查积木点击 for (int b = 0; b < cat->block_count; b++) { if (mx >= palette->x + 5 && mx <= palette->x + palette->width - 5 && my >= y && my <= y + 18) { return cat->blocks[b]; } y += 20; } y += 5; } return -1; } void palette_search(BlockPalette* palette, const char* text) { if (text) { strncpy(palette->search_text, text, 127); palette->search_active = 1; } else { palette->search_text[0] = '\0'; palette->search_active = 0; } }