2025-10-17 13:41:37 +02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Copyright (C) Artsiom D.
|
|
|
|
|
* Copyright (C) shit-co.de
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <curses.h>
|
2025-10-17 18:01:57 +02:00
|
|
|
#include <limits.h>
|
|
|
|
|
#include <math.h>
|
2025-10-17 13:41:37 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
2025-10-16 20:22:32 +02:00
|
|
|
#include "box.h"
|
2025-10-17 13:41:37 +02:00
|
|
|
#include "ui.h"
|
|
|
|
|
#include "util.h"
|
|
|
|
|
|
|
|
|
|
|
2025-10-17 18:01:57 +02:00
|
|
|
static void draw_rectangle(double x, double y, double width, double height);
|
2025-10-18 18:22:10 +02:00
|
|
|
static void draw_chart(struct box *, double x, double y, double width,
|
|
|
|
|
double height);
|
|
|
|
|
static void draw_container(struct box *, double x, double y, double width,
|
|
|
|
|
double height);
|
|
|
|
|
static void draw_button(struct box *, double x, double y, double width,
|
|
|
|
|
double height);
|
2025-10-16 20:22:32 +02:00
|
|
|
|
2025-10-17 13:41:37 +02:00
|
|
|
|
2025-10-18 18:18:29 +02:00
|
|
|
void
|
|
|
|
|
append_box(struct box *parent, struct box *child)
|
|
|
|
|
{
|
|
|
|
|
parent->children[parent->length++] = child;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-10-17 13:41:37 +02:00
|
|
|
static void
|
2025-10-17 18:01:57 +02:00
|
|
|
draw_rectangle(double fx, double fy, double fwidth, double fheight)
|
2025-10-16 20:22:32 +02:00
|
|
|
{
|
2025-10-18 18:18:29 +02:00
|
|
|
size_t x = llround(fx);
|
|
|
|
|
size_t y = llround(fy);
|
|
|
|
|
size_t w = llround(fwidth) - 1;
|
|
|
|
|
size_t h = llround(fheight) - 1;
|
2025-10-16 20:22:32 +02:00
|
|
|
|
2025-10-18 18:18:29 +02:00
|
|
|
/* corners */
|
2025-10-16 20:22:32 +02:00
|
|
|
|
2025-10-18 18:18:29 +02:00
|
|
|
ui_char(x, y, '+');
|
|
|
|
|
ui_char(x, y + h, '+');
|
|
|
|
|
ui_char(x + w, y + h, '+');
|
|
|
|
|
ui_char(x + w, y, '+');
|
2025-10-17 13:41:37 +02:00
|
|
|
|
2025-10-18 18:18:29 +02:00
|
|
|
/* vertical borders */
|
2025-10-16 20:22:32 +02:00
|
|
|
|
2025-10-18 18:18:29 +02:00
|
|
|
for (size_t i = 1; i < h; i++) {
|
|
|
|
|
ui_char(x, y + i, '|');
|
|
|
|
|
}
|
2025-10-16 20:22:32 +02:00
|
|
|
|
2025-10-18 18:18:29 +02:00
|
|
|
for (size_t i = 1; i < h; i++) {
|
2025-10-18 18:22:10 +02:00
|
|
|
ui_char(x + w, y + i, '|');
|
2025-10-18 18:18:29 +02:00
|
|
|
}
|
2025-10-16 20:22:32 +02:00
|
|
|
|
2025-10-18 18:18:29 +02:00
|
|
|
/* horizontal borders */
|
2025-10-17 13:41:37 +02:00
|
|
|
|
2025-10-18 18:18:29 +02:00
|
|
|
for (size_t i = 1; i < w; i++) {
|
2025-10-18 18:22:10 +02:00
|
|
|
ui_char(x + i, y, '-');
|
2025-10-18 18:18:29 +02:00
|
|
|
}
|
2025-10-16 20:22:32 +02:00
|
|
|
|
2025-10-18 18:18:29 +02:00
|
|
|
for (size_t i = 1; i < w; i++) {
|
2025-10-18 18:22:10 +02:00
|
|
|
ui_char(x + i, y + h, '-');
|
2025-10-18 18:18:29 +02:00
|
|
|
}
|
|
|
|
|
}
|
2025-10-16 20:22:32 +02:00
|
|
|
|
|
|
|
|
|
2025-10-17 13:41:37 +02:00
|
|
|
static void
|
2025-10-17 18:01:57 +02:00
|
|
|
draw_chart(struct box *chart, double x, double y, double width, double height)
|
2025-10-16 20:22:32 +02:00
|
|
|
{
|
2025-10-18 18:18:29 +02:00
|
|
|
char c = '@';
|
|
|
|
|
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++) {
|
2025-10-18 18:22:10 +02:00
|
|
|
diff = (double)rand() / RAND_MAX - 0.6;
|
|
|
|
|
actual_diff = (size_t)(height + y - price)
|
|
|
|
|
- (size_t)(height + y - (price + diff));
|
|
|
|
|
|
|
|
|
|
if (actual_diff > 0) {
|
|
|
|
|
color = UI_GREEN;
|
|
|
|
|
} else if (actual_diff == 0) {
|
|
|
|
|
color = UI_NONE;
|
|
|
|
|
} else if (actual_diff < 0) {
|
|
|
|
|
color = UI_RED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ui_color_on(color);
|
|
|
|
|
ui_char(x + i, height + y - price, c);
|
|
|
|
|
ui_color_off(color);
|
|
|
|
|
|
|
|
|
|
price += diff;
|
2025-10-18 18:18:29 +02:00
|
|
|
}
|
2025-10-17 13:41:37 +02:00
|
|
|
}
|
2025-10-16 20:22:32 +02:00
|
|
|
|
|
|
|
|
|
2025-10-17 13:41:37 +02:00
|
|
|
static void
|
2025-10-17 18:01:57 +02:00
|
|
|
draw_button(struct box *b, double x, double y, double width, double height)
|
2025-10-17 13:41:37 +02:00
|
|
|
{
|
2025-10-18 18:18:29 +02:00
|
|
|
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);
|
2025-10-16 20:22:32 +02:00
|
|
|
}
|
|
|
|
|
|
2025-10-17 13:41:37 +02:00
|
|
|
|
|
|
|
|
static void
|
2025-10-17 18:01:57 +02:00
|
|
|
draw_container(struct box *b, double x, double y, double width, double height)
|
2025-10-16 20:22:32 +02:00
|
|
|
{
|
2025-10-18 18:18:29 +02:00
|
|
|
double current, length, total_fills, pixels_per_fill;
|
|
|
|
|
struct box *child;
|
|
|
|
|
|
|
|
|
|
switch (b->type) {
|
|
|
|
|
case BOX_VERTICAL:
|
2025-10-18 18:22:10 +02:00
|
|
|
length = height;
|
|
|
|
|
current = y;
|
|
|
|
|
break;
|
2025-10-18 18:18:29 +02:00
|
|
|
case BOX_HORIZONTAL:
|
2025-10-18 18:22:10 +02:00
|
|
|
length = width;
|
|
|
|
|
current = x;
|
|
|
|
|
break;
|
2025-10-18 18:18:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
total_fills = 0;
|
|
|
|
|
for (size_t i = 0; i < b->length; i++) {
|
2025-10-18 18:22:10 +02:00
|
|
|
total_fills += b->children[i]->fills;
|
2025-10-18 18:18:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pixels_per_fill = length / total_fills;
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < b->length; i++) {
|
2025-10-18 18:22:10 +02:00
|
|
|
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;
|
2025-10-18 18:18:29 +02:00
|
|
|
}
|
2025-10-17 13:41:37 +02:00
|
|
|
}
|
2025-10-16 20:22:32 +02:00
|
|
|
|
|
|
|
|
|
2025-10-17 18:01:57 +02:00
|
|
|
struct box *
|
|
|
|
|
new_chart_box(void)
|
|
|
|
|
{
|
2025-10-18 18:18:29 +02:00
|
|
|
struct box *chart = malloc(sizeof(struct box));
|
2025-10-17 18:01:57 +02:00
|
|
|
|
2025-10-18 18:18:29 +02:00
|
|
|
chart->type = BOX_CHART;
|
|
|
|
|
chart->prices = emalloc(sizeof(double) * 100);
|
|
|
|
|
chart->fills = 1;
|
|
|
|
|
chart->color = UI_NONE;
|
2025-10-17 18:01:57 +02:00
|
|
|
|
2025-10-18 18:18:29 +02:00
|
|
|
return chart;
|
2025-10-17 18:01:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-10-17 13:41:37 +02:00
|
|
|
struct box *
|
|
|
|
|
new_button_box(char *name)
|
|
|
|
|
{
|
2025-10-18 18:18:29 +02:00
|
|
|
struct box *button = malloc(sizeof(struct box));
|
2025-10-17 13:41:37 +02:00
|
|
|
|
2025-10-18 18:18:29 +02:00
|
|
|
button->type = BOX_BUTTON;
|
|
|
|
|
button->name = name;
|
|
|
|
|
button->fills = 1;
|
|
|
|
|
button->color = UI_NONE;
|
2025-10-17 13:41:37 +02:00
|
|
|
|
2025-10-18 18:18:29 +02:00
|
|
|
return button;
|
2025-10-16 20:22:32 +02:00
|
|
|
}
|
|
|
|
|
|
2025-10-17 13:41:37 +02:00
|
|
|
|
|
|
|
|
struct box *
|
2025-10-17 18:01:57 +02:00
|
|
|
new_container_box(enum box_type type)
|
2025-10-17 13:41:37 +02:00
|
|
|
{
|
2025-10-18 18:18:29 +02:00
|
|
|
struct box *box = emalloc(sizeof(struct box));
|
2025-10-17 13:41:37 +02:00
|
|
|
|
2025-10-18 18:18:29 +02:00
|
|
|
box->type = type;
|
|
|
|
|
box->fills = 1;
|
|
|
|
|
box->color = UI_NONE;
|
|
|
|
|
box->children = emalloc(sizeof(struct box *) * 100);
|
|
|
|
|
box->length = 0;
|
2025-10-17 13:41:37 +02:00
|
|
|
|
2025-10-18 18:18:29 +02:00
|
|
|
return box;
|
2025-10-17 13:41:37 +02:00
|
|
|
}
|
|
|
|
|
|
2025-10-17 18:01:57 +02:00
|
|
|
struct box *
|
|
|
|
|
new_horizontal_box(void)
|
|
|
|
|
{
|
2025-10-18 18:18:29 +02:00
|
|
|
return new_container_box(BOX_HORIZONTAL);
|
2025-10-17 18:01:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct box *
|
|
|
|
|
new_vertical_box(void)
|
|
|
|
|
{
|
2025-10-18 18:18:29 +02:00
|
|
|
return new_container_box(BOX_VERTICAL);
|
2025-10-17 18:01:57 +02:00
|
|
|
}
|
|
|
|
|
|
2025-10-17 13:41:37 +02:00
|
|
|
|
|
|
|
|
void
|
2025-10-17 18:01:57 +02:00
|
|
|
draw_box(struct box *b, double x, double y, double width, double height)
|
2025-10-16 20:22:32 +02:00
|
|
|
{
|
2025-10-18 18:18:29 +02:00
|
|
|
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;
|
|
|
|
|
}
|
2025-10-16 20:22:32 +02:00
|
|
|
}
|