data-structure-experiments/3/main.c

382 lines
11 KiB
C

#include "key.h"
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_COLUMN 20
#define MAX_ROW 20
#define MAX_COLUMN_WIDTH 10
#define MAX_DATA_LENGTH 100
#define MAX_TICK 200
#define MAX_MESSAGE_LENGTH 100
#define FUNCTION_NUM 7
int tick = 0;
int current_x = 0;
int current_y = 0;
int alive = 1;
char functions[FUNCTION_NUM][100] = {
"Save", "Load", "Sum", "Average", "Max", "Min", "Sort",
};
char *message = "Hi~";
typedef struct {
int current_width;
int current_height;
int column_width[MAX_COLUMN];
char data[MAX_ROW][MAX_COLUMN][MAX_DATA_LENGTH];
} TableInfo;
int max(int a, int b) { return a > b ? a : b; }
int min(int a, int b) { return a < b ? a : b; }
char *int_to_string(int num) {
char *str = (char *)malloc(sizeof(char) * 100);
sprintf(str, "%d", num);
return str;
}
void init_table(int width, int height, int column_width, TableInfo *table) {
table->current_width = width;
table->current_height = height;
for (int i = 0; i < width; i++) {
table->column_width[i] = column_width;
}
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
table->data[i][j][0] = '\0';
}
}
}
void printTable(TableInfo *table) {
system("cls");
printf("Table v0.1 by Luthics\n");
// render table
for (int i = 0; i < table->current_height; i++) {
for (int j = 0; j < table->current_width; j++) {
printf("+");
for (int k = 0; k < table->column_width[j]; k++) {
printf("-");
}
}
printf("+\n");
for (int j = 0; j < table->current_width; j++) {
printf("|");
int data_length =
table->data[i][j] == NULL ? 0 : strlen(table->data[i][j]);
if (data_length == 0) {
if (i == current_y && j == current_x) {
printf("_");
} else {
printf(" ");
}
for (int k = 0; k < table->column_width[j] - 1; k++) {
printf(" ");
}
} else {
int add_ = 0;
if (i == current_y && j == current_x) {
// RED
printf("\033[31m");
// BOLD
printf("\033[1m");
}
for (int k = 0; k < data_length; k++) {
printf("%c", table->data[i][j][k]);
}
if (i == current_y && j == current_x) {
// RESET
printf("\033[0m");
if (table->column_width[j] - data_length > 0) {
printf("_");
add_ = 1;
}
}
for (int k = 0; k < table->column_width[j] - data_length - add_;
k++) {
printf(" ");
}
}
}
printf("|\n");
}
for (int j = 0; j < table->current_width; j++) {
printf("+");
for (int k = 0; k < table->column_width[j]; k++) {
printf("-");
}
}
printf("+\n");
// render functions
for (int i = 0; i < FUNCTION_NUM; i++) {
if (current_y == -1 && i == current_x) {
// RED
printf("\033[31m");
// BOLD
printf("\033[1m");
}
printf("%s", functions[i]);
if (current_y == -1 && i == current_x) {
// RESET
printf("\033[0m");
}
if (i != FUNCTION_NUM - 1) {
printf(" ");
}
}
printf("\n");
printf("%s\n", message);
}
int is_data_file_exist() {
FILE *fp = fopen("table.dat", "r");
if (fp == NULL) {
return 0;
} else {
fclose(fp);
return 1;
}
}
TableInfo load_table_from_file(char *filename) {
TableInfo table;
FILE *fp = fopen(filename, "r");
fread(&table, sizeof(TableInfo), 1, fp);
fclose(fp);
return table;
}
int save_table_to_file(char *filename, TableInfo table) {
FILE *fp = fopen(filename, "w");
fwrite(&table, sizeof(TableInfo), 1, fp);
fclose(fp);
return 0;
}
void setCell(TableInfo *table, int row, int column, char *data) {
if (row >= table->current_height || column >= table->current_width ||
row < 0 || column < 0) {
return;
}
strcpy(table->data[row][column], data);
if (strlen(data) > table->column_width[column]) {
table->column_width[column] = strlen(data);
}
}
int get_max_width_in_a_column(TableInfo *table, int column) {
int max_width = 0;
for (int i = 0; i < table->current_height; i++) {
int data_length =
table->data[i][column] == NULL ? 0 : strlen(table->data[i][column]);
if (data_length > max_width) {
max_width = data_length;
}
}
return max(max_width, table->column_width[column]);
}
void add_char_to_cell(TableInfo *table, int row, int column, char c) {
if (row >= table->current_height || column >= table->current_width ||
row < 0 || column < 0) {
return;
}
int data_length = strlen(table->data[row][column]);
if (data_length < MAX_DATA_LENGTH - 1) {
table->data[row][column][data_length] = c;
table->data[row][column][data_length + 1] = '\0';
table->column_width[column] = get_max_width_in_a_column(table, column);
}
}
void del_char_from_cell(TableInfo *table, int row, int column) {
if (row >= table->current_height || column >= table->current_width ||
row < 0 || column < 0) {
return;
}
int data_length = strlen(table->data[row][column]);
if (data_length > 0) {
table->data[row][column][data_length - 1] = '\0';
table->column_width[column] = get_max_width_in_a_column(table, column);
}
}
// 返回 1 代表响应成功
// 返回 0 代表响应失败
int handleKeyPress(int key, TableInfo *table) {
int status = 0;
if (key == 224) { // 特殊键
key = getch(); // 获取特殊键码
if (key == KEY_LEFT_ARROW) {
if (current_x > 0) {
current_x--;
} else if (current_x == 0) {
if (current_y == -1) {
current_x = FUNCTION_NUM - 1;
} else {
current_x = table->current_width - 1;
}
}
status = 1;
}
if (key == KEY_RIGHT_ARROW) {
if (current_y == -1) {
current_x = (current_x + 1) % FUNCTION_NUM;
} else {
current_x = (current_x + 1) % table->current_width;
}
status = 1;
}
if (key == KEY_UP_ARROW) {
if (current_y > 0) {
current_y--;
} else if (current_y == 0) {
current_y = -1;
current_x = min(FUNCTION_NUM - 1, current_x);
} else if (current_y == -1) {
current_y = table->current_height - 1;
current_x = min(table->current_width - 1, current_x);
}
status = 1;
}
if (key == KEY_DOWN_ARROW) {
if (current_y < table->current_height - 1 && current_y >= 0) {
current_y++;
} else if (current_y == table->current_height - 1) {
// TO FUNCTIONS AREA
current_y = -1;
current_x = min(FUNCTION_NUM - 1, current_x);
} else if (current_y == -1) {
current_y = 0;
current_x = min(table->current_width - 1, current_x);
}
status = 1;
}
} else {
// ctrl + c
if (key == 3) {
alive = 0;
message = "Bye!";
status = 1;
}
// ctrl + s
if (key == 19) {
save_table_to_file("table.dat", *table);
message = "Saved!";
status = 1;
}
// 判断 key 是可打印字符
if (key >= 32 && key <= 126) {
add_char_to_cell(table, current_y, current_x, key);
status = 1;
}
// 退格键
if (key == 8) {
del_char_from_cell(table, current_y, current_x);
status = 1;
}
// ENTER
if (key == KEY_ENTER) {
if (current_y == -1) {
if (current_x == 0) {
save_table_to_file("table.dat", *table);
message = "Saved!";
}
if (current_x == 1) {
*table = load_table_from_file("table.dat");
message = "Loaded!";
}
if (current_x == 2) {
}
if (current_x == 3) {
}
if (current_x == 4) {
}
if (current_x == 5) {
}
if (current_x == 6) {
}
}
}
}
char *tmp_message = (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
sprintf(tmp_message, "x: %d, y: %d", current_x, current_y);
message = tmp_message;
return status;
}
int main() {
TableInfo table;
int load_from_file = 0;
if (is_data_file_exist()) {
char tmp;
printf("Load from file? ([Y]/n): ");
scanf("%c", &tmp);
if (tmp == 'n' || tmp == 'N') {
load_from_file = 0;
} else {
load_from_file = 1;
}
}
if (load_from_file) {
table = load_table_from_file("table.dat");
} else {
printf("Let's create a table!\n");
int width = 0, height = 0;
int column_width = 0;
while (width <= 0 || width > MAX_COLUMN) {
printf("Input width (1-%d): ", MAX_COLUMN);
scanf("%d", &width);
}
while (height <= 0 || height > MAX_ROW) {
printf("Input height (1-%d): ", MAX_ROW);
scanf("%d", &height);
}
while (column_width <= 0 || column_width > MAX_COLUMN_WIDTH) {
printf("Input column width (1-%d): ", MAX_COLUMN_WIDTH);
scanf("%d", &column_width);
}
init_table(width, height, column_width, &table);
}
setCell(&table, 0, 0, "Hello");
while (alive) {
printTable(&table);
// drawGUI(currentSelection);
int keyPressed = getch(); // 获取键盘输入
handleKeyPress(keyPressed, &table);
// tick = (tick + 1) % MAX_TICK;
}
int save_to_file = 0;
char tmp;
printf("Save to file? ([Y]/n): ");
scanf("%c", &tmp);
if (tmp == 'n' || tmp == 'N') {
save_to_file = 0;
} else {
save_to_file = 1;
}
if (save_to_file) {
save_table_to_file("table.dat", table);
}
return 0;
}