/* * Copyright (C) Artsiom D. * Copyright (C) shit-co.de */ #include #include #include #include #include #include #include "box.h" #include "ui.h" #include "util.h" static void draw_rectangle(unsigned int x, unsigned int y, unsigned int width, unsigned int height); static void draw_chart(struct box *, unsigned int x, unsigned int y, unsigned int width, unsigned int height); static void draw_container(struct box *, unsigned int x, unsigned int y, unsigned int width, unsigned int height); static void draw_button(struct box *, unsigned int x, unsigned int y, unsigned int width, unsigned int height); void append_box(struct box *parent, struct box *child) { parent->children[parent->length++] = child; } static void draw_rectangle(unsigned int x, unsigned int y, unsigned int width, unsigned int height) { /* corners */ ui_char(x, y, '+'); ui_char(x, y + height, '+'); ui_char(x + width, y + height, '+'); ui_char(x + width, y, '+'); /* vertical borders */ for (size_t i = 1; i < height; i++) { ui_char(x, y + i, '|'); } for (size_t i = 1; i < height; i++) { ui_char(x + width, y + i, '|'); } /* horizontal borders */ for (size_t i = 1; i < width; i++) { ui_char(x + i, y, '-'); } for (size_t i = 1; i < width; i++) { ui_char(x + i, y + height, '-'); } } static void draw_chart(struct box *chart, unsigned int x, unsigned int y, unsigned int width, unsigned int height) { long int actual_diff; double diff, price; enum ui_color color; draw_rectangle(x, y, width, height); x += 1; y += 1; width -= 2; height -= 2; price = height / 2; actual_diff = 0; for (size_t i = 0; i < width; i++) { price = chart->chart->prices[i]; ui_color_on(UI_BLUE); ui_char(x + i, height + y - price, '@'); ui_color_off(UI_BLUE); } } static void draw_button(struct box *b, unsigned int x, unsigned int y, unsigned int width, unsigned int height) { ui_color_on(b->color); draw_rectangle(x, y, width, height); ui_string(x + width / 2 - strlen(b->name) / 2, y + height / 2, b->name); ui_color_off(b->color); } static void draw_container(struct box *b, unsigned int x, unsigned int y, unsigned int width, unsigned int height) { unsigned int current, i, length, total_fills, pixels_per_fill; struct box *child; switch (b->type) { case BOX_VERTICAL: length = height; current = y; break; case BOX_HORIZONTAL: length = width; current = x; break; } total_fills = 0; for (i = 0; i < b->length; i++) { total_fills += b->children[i]->fills; } pixels_per_fill = length / total_fills; for (i = 0; i < b->length; i++) { child = b->children[i]; length = child->fills * pixels_per_fill; switch (b->type) { case BOX_VERTICAL: draw_box(child, x, current, width, length); break; case BOX_HORIZONTAL: draw_box(child, current, y, length, height); break; } current += length; } } struct box * new_chart_box(struct chart *chart) { struct box *box = malloc(sizeof(struct box)); box->type = BOX_CHART; box->chart = chart; box->fills = 1; box->color = UI_NONE; return box; } struct box * new_button_box(char *name) { struct box *button = malloc(sizeof(struct box)); button->type = BOX_BUTTON; button->name = name; button->fills = 1; button->color = UI_NONE; return button; } struct box * new_container_box(enum box_type type) { struct box *box = emalloc(sizeof(struct box)); box->type = type; box->fills = 1; box->color = UI_NONE; box->children = emalloc(sizeof(struct box *) * 100); box->length = 0; return box; } struct box * new_horizontal_box(void) { return new_container_box(BOX_HORIZONTAL); } struct box * new_vertical_box(void) { return new_container_box(BOX_VERTICAL); } void draw_box(struct box *b, unsigned int x, unsigned int y, unsigned int width, unsigned int height) { switch (b->type) { case BOX_BUTTON: draw_button(b, x, y, width, height); break; case BOX_CHART: draw_chart(b, x, y, width, height); break; case BOX_HORIZONTAL: case BOX_VERTICAL: draw_container(b, x, y, width, height); break; } }