~nloomans/ft_select

ref: 9783305a370e42cdcc43c542a2172cc8b95e8b9b ft_select/src/render.c -rw-r--r-- 2.7 KiB
9783305aNoah Loomans confirm selection by pressing return 1 year, 10 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <stdbool.h>
#include <unistd.h>
#include <ft_printf.h>
#include <libft.h>
#include "state.h"
#include "derive.h"
#include "terminal.h"
#include "render.h"

static void	box_top(const struct s_state_terminal terminal)
{
	size_t	i;

	ft_dprintf(STDERR_FILENO, "%*s\n", terminal.columns, "");
	ft_dprintf(STDERR_FILENO, "  ┏");
	i = 1;
	while (i < terminal.columns - 5)
	{
		ft_dprintf(STDERR_FILENO, "━");
		i++;
	}
	ft_dprintf(STDERR_FILENO, "┓  \n");
}

static void	box_bottom(const struct s_state_terminal terminal)
{
	size_t	i;

	ft_dprintf(STDERR_FILENO, "  ┗");
	i = 1;
	while (i < terminal.columns - 5)
	{
		ft_dprintf(STDERR_FILENO, "━");
		i++;
	}
	ft_dprintf(STDERR_FILENO, "┛  \n");
}

static void	box_option(char *option, bool selected, bool focus, size_t width)
{
	ft_dprintf(STDERR_FILENO, "%c%c", focus ? '[' : ' ', selected ? '*' : ' ');
	if (focus)
		terminal_send(TERMINAL_FMT_BEGIN_UNDERLINE);
	if (selected)
		terminal_send(TERMINAL_FMT_BEGIN_REVERSE_VIDEO);
	ft_dprintf(STDERR_FILENO, "%-*s", (int)width, option);
	terminal_send(TERMINAL_FMT_EXIT);
	ft_dprintf(STDERR_FILENO, "%c", focus ? ']' : ' ');
}

void		render(const struct s_state state)
{
	struct s_derived_dimensions	dimensions;
	size_t						*column_width;
	struct s_state_option		***rows;
	size_t						column_index;
	size_t						row_index;
	size_t						total_column_width;
	t_error						error;

	terminal_send(TERMINAL_CURSOR_HOME);
	error = derive_dimensions(&dimensions, state.terminal, state.options);
	if (is_error(error))
	{
		ft_dprintf(STDERR_FILENO, "%s", error.msg);
		return ;
	}
	error = derive_column_width(&column_width, dimensions, state.options);
	if (is_error(error))
	{
		ft_dprintf(STDERR_FILENO, "%s", error.msg);
		return ;
	}
	error = derive_rows(&rows, dimensions, state.options);
	if (is_error(error))
	{
		ft_dprintf(STDERR_FILENO, "%s", error.msg);
		return ;
	}
	box_top(state.terminal);
	row_index = 0;
	while (row_index < dimensions.rows)
	{
		ft_dprintf(STDERR_FILENO, "  ┃ ");
		column_index = 0;
		total_column_width = 0;
		while (column_index < dimensions.columns &&
			rows[row_index][column_index] != NULL)
		{
			box_option(
				rows[row_index][column_index]->name,
				rows[row_index][column_index]->selected,
				state.cursor->content == rows[row_index][column_index],
				column_width[column_index]);
			total_column_width += column_width[column_index]
				+ DERIVE_OPTION_PADDING_LEFT + DERIVE_OPTION_PADDING_RIGHT;
			column_index++;
		}
		ft_dprintf(STDERR_FILENO, "%*s ┃  \n",
			state.terminal.columns - total_column_width
			- DERIVE_PADDING_LEFT - DERIVE_PADDING_RIGHT, "");
		row_index++;
	}
	box_bottom(state.terminal);
	ft_memdel((void **)&column_width);
	derive_free_rows(dimensions, &rows);
}