#include <iostream> using namespace std; //提交时记得删掉 #define MAX_ID 100 #define MAX_STR_LENGTH 3000 #define MAX_IMAGE_HEIGHT 50 #define MAX_IMAGE_WIDTH 50 #define MAX_SCREEN_HEIGHT 1000 #define MAX_SCREEN_WIDTH 1000 #define THRESHOLD 0x07FFFFFF enum Command { INIT = 0, CREATE, ADD, SHOW, }; enum Type { VWIDGET = 0, HWIDGET, TEXT, IMAGE, }; typedef struct { int type; int Dimensions[2]; char data[MAX_STR_LENGTH + 1]; } MyElement; typedef struct { int type; union { struct { int width; } vwidget; struct { int height; } hwidget; struct { char *strPtr; } text; struct { int height, width; char *imagePtr; } image; }; } Element; void init(); int create(Element* elementPtr); void add(int parentId, int childId); void show(int elementId, char screen[MAX_SCREEN_HEIGHT][MAX_SCREEN_WIDTH]); int Tree[MAX_ID][MAX_ID]; int fatherID[MAX_ID]; MyElement Elements[MAX_ID]; int elementID; int dimensionIndex[2][2] = {0, 1, 1, 0}; void init(){ for(int i = 0; i < MAX_ID; i++){ for(int j = 0; j < MAX_ID; j++){ Tree[i][j] = 0; } } for(int i = 0; i < MAX_ID; i++){ fatherID[i] = i; } elementID = 0; } int getNewElement(){ return elementID++; } int create(Element* elementPtr){ int newID = getNewElement(); Elements[newID].type = elementPtr->type; //第0维是行数、第1维是列数 if(elementPtr->type == 0){ Elements[newID].Dimensions[1] = elementPtr->vwidget.width; Elements[newID].Dimensions[0] = 2; } if(elementPtr->type == 1){ Elements[newID].Dimensions[0] = elementPtr->hwidget.height; Elements[newID].Dimensions[1] = 2; } if(elementPtr->type == 2){ int i = 0; for( ; elementPtr->text.strPtr[i]; i++) { Elements[newID].data[i] = elementPtr->text.strPtr[i]; } Elements[newID].data[i] = 0; } if(elementPtr->type == 3){ Elements[newID].Dimensions[0] = elementPtr->image.height; Elements[newID].Dimensions[1] = elementPtr->image.width; int h = Elements[newID].Dimensions[0]; int w = Elements[newID].Dimensions[1]; for(int i = 0; i < h; i++){ for(int j = 0; j < w; j++){ Elements[newID].data[i * w + j] = elementPtr->image.imagePtr[i * w + j]; } } } return newID; } int getLen(int ID, char * str){//字串长度不包括结尾的0 int len = 0; for(int i = 0; str[i]; i++){ len++; } return len; } void updateParent(int parentId, int childId){ int DMain, DSub; int faterType = Elements[parentId].type; DMain = dimensionIndex[faterType][0]; DSub = dimensionIndex[faterType][1]; //更新副尺寸 if(Elements[childId].type != 2 && Elements[childId].Dimensions[DSub] + 2 > Elements[parentId].Dimensions[DSub]){ Elements[parentId].Dimensions[DSub] = Elements[childId].Dimensions[DSub] + 2; } //更新所有text for(int i = 1; i <= Tree[parentId][0]; i++){ int curID = Tree[parentId][i]; if(Elements[curID].type == 2){ Elements[curID].Dimensions[DSub] = Elements[parentId].Dimensions[DSub] - 2; int strLen = getLen(curID, Elements[curID].data); Elements[curID].Dimensions[DMain] = strLen / Elements[curID].Dimensions[DSub]; if(strLen % Elements[curID].Dimensions[DSub]) Elements[curID].Dimensions[DMain]++; } } //更新主尺寸 int sumOfChildMain = 0; for(int i = 1; i <= Tree[parentId][0]; i++){ int curID = Tree[parentId][i]; sumOfChildMain += Elements[curID].Dimensions[DMain];//主方向上一直叠加 } Elements[parentId].Dimensions[DMain] = sumOfChildMain + 2; //加上递归逻辑 if(fatherID[parentId] != parentId){ updateParent(fatherID[parentId],parentId); } } void add(int parentId, int childId){ Tree[parentId][0]++; int pos = Tree[parentId][0]; Tree[parentId][pos] = childId; fatherID[childId] = parentId; updateParent(parentId, childId); } void fillBlank(int Id, char screen[MAX_SCREEN_HEIGHT][MAX_SCREEN_WIDTH]){ for(int i = 0; i < Elements[Id].Dimensions[0]; i++){ for(int j = 0; j < Elements[Id].Dimensions[1]; j++){ screen[i][j] = ' '; } } } //显示text void displayText(int Id, char screen[MAX_SCREEN_HEIGHT][MAX_SCREEN_WIDTH], int x, int y, int fatherID){ int h, w; h = Elements[Id].Dimensions[0]; w = Elements[Id].Dimensions[1]; int i, j; if(Elements[fatherID].type == 0) //如果是VWidget,文字是横向排列 for(i = 0; i < h; i++){ for(j = 0; j < w; j++){ if(Elements[Id].data[i * w + j]) screen[x + i][y + j] = Elements[Id].data[i * w + j]; else goto endText; } } if(Elements[fatherID].type == 1) //如果是HWidget,文字是纵向排列 for(i = 0; i < w; i++){ for(j = 0; j < h; j++){ if(Elements[Id].data[i * h + j]) screen[x + j][y + i] = Elements[Id].data[i * h + j]; else goto endText; } } endText: return; } void displayFrame(int Id, char screen[MAX_SCREEN_HEIGHT][MAX_SCREEN_WIDTH], int x, int y){ for(int i = 0; i < Elements[Id].Dimensions[0]; i++){ screen[x + i][y] = '+'; screen[x + i][y + Elements[Id].Dimensions[1] - 1] = '+'; } for(int i = 0; i < Elements[Id].Dimensions[1]; i++){ screen[x][y + i] = '+'; screen[x + Elements[Id].Dimensions[0] - 1][y + i] = '+'; } } void displayImage(int Id, char screen[MAX_SCREEN_HEIGHT][MAX_SCREEN_WIDTH], int x, int y){ int h = Elements[Id].Dimensions[0]; int w = Elements[Id].Dimensions[1]; for(int i = 0; i < h; i++){ for(int j = 0; j < w; j++){ screen[x + i][y + j] = Elements[Id].data[i * w + j]; } } } void showTheWidget(int Id, char screen[MAX_SCREEN_HEIGHT][MAX_SCREEN_WIDTH], int x, int y, int fatherID){ //如果是图片或者文本,直接显示 if(Elements[Id].type == 2){ displayText(Id, screen, x, y, fatherID); return; } if(Elements[Id].type == 3){ displayImage(Id, screen, x, y); return; } //如果是容器,先画外框并填充空格,然后显示里面的内容 if(Elements[Id].type == 0 || Elements[Id].type == 1){ displayFrame(Id, screen, x, y); //逐个显示孩子 for(int i = 1; i <= Tree[Id][0]; i++){ int curID = Tree[Id][i]; if(i == 1){ //第一个孩子偏移1,1 x++; y++; } showTheWidget(curID, screen, x, y, Id); //计算下一个孩子的偏移 if(Elements[Id].type == 0){ x += Elements[curID].Dimensions[0]; }else{ y += Elements[curID].Dimensions[1]; } } } } void show(int elementId, char screen[MAX_SCREEN_HEIGHT][MAX_SCREEN_WIDTH]){ fillBlank(elementId, screen); //先把画布擦干净 showTheWidget(elementId, screen, 0, 0, elementId);//按照组件的长、宽进行显示 }