核心热路径(数学/内存/字符串/性能分析)用MASM汇编(SSE/AVX2) 外围系统(窗口/渲染/ECS/音频/UI/脚本)用C语言 含自研编辑器、VisualScript积木编程、中文渲染(glyph_atlas)
141 lines
4.4 KiB
C
141 lines
4.4 KiB
C
// ============================================================================
|
|
// block_palette.c - 积木面板实现
|
|
// ============================================================================
|
|
|
|
#include "block_palette.h"
|
|
#include "block_renderer.h"
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
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;
|
|
}
|
|
}
|