~nloomans/ft_select

ref: 1d90313037b5c7d0545be79e58d8f50a102501ff ft_select/src/derive.c -rw-r--r-- 3.0 KiB
1d903130Noah Loomans handle CTRL+Z and fg 2 years 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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <libft.h>
# include <ft_printf.h>
#include "derive.h"

static size_t	max(size_t a, size_t b)
{
	return (a > b ? a : b);
}

t_error			derive_dimensions(
					struct s_derived_dimensions *dimensions,
					struct s_state_terminal terminal,
					t_list2_meta options)
{
	if (DERIVE_PADDING_TOP + DERIVE_PADDING_BOTTOM + 1 > terminal.rows)
		return (errorf("terminal too short to display options"));
	dimensions->rows =
		terminal.rows - DERIVE_PADDING_TOP - DERIVE_PADDING_BOTTOM;
	dimensions->columns =
		(options.len / dimensions->rows) +
		((options.len % dimensions->rows) ? 1 : 0);
	return (ERROR_NULL);
}

t_error			derive_column_width(
					size_t **res,
					struct s_derived_dimensions dimensions,
					t_list2_meta options)
{
	size_t			row_index;
	size_t			column_index;
	t_list2_conn	*conn;

	*res = ft_memalloc(dimensions.columns * sizeof(**res));
	if (*res == NULL)
		return errorf("unable to malloc column width array");
	conn = options.first;
	column_index = 0;
	while (column_index < dimensions.columns)
	{
		row_index = 0;
		while (row_index < dimensions.rows && conn != NULL)
		{
			(*res)[column_index] = max(
				ft_strlen(unpack_option(conn)->name),
				(*res)[column_index]);
			conn = conn->next;
			row_index++;
		}
		column_index++;
	}
	return (ERROR_NULL);
}

static t_error	malloc_rows(
					struct s_state_option ****res,
					struct s_derived_dimensions dimensions)
{
	size_t			row_index;

	*res = ft_memalloc(sizeof(**res) * dimensions.rows);
	if (*res == NULL)
		return errorf("unable to malloc rows array");
	row_index = 0;
	while (row_index < dimensions.rows)
	{
		(*res)[row_index] = ft_memalloc(sizeof(***res) * dimensions.columns);
		if ((*res)[row_index] == NULL)
			return errorf("unable to malloc column in rows array");
		row_index++;
	}
	return (ERROR_NULL);
}

t_error			derive_rows(
					struct s_state_option ****res,
					struct s_derived_dimensions dimensions,
					t_list2_meta options)
{
	size_t			row_index;
	size_t			column_index;
	t_list2_conn	*conn;
	t_error			error;

	error = malloc_rows(res, dimensions);
	if (is_error(error))
		return (error);
	conn = options.first;
	column_index = 0;
	while (column_index < dimensions.columns)
	{
		row_index = 0;
		while (row_index < dimensions.rows && conn != NULL)
		{
			(*res)[row_index][column_index] = unpack_option(conn);
			conn = conn->next;
			row_index++;
		}
		column_index++;
	}
	return (ERROR_NULL);
}

bool			derive_enough_columns(
					struct s_state_terminal terminal,
					struct s_derived_dimensions dimensions,
					size_t *column_width)
{
	size_t	total_width;
	size_t	i;

	total_width = DERIVE_PADDING_LEFT + DERIVE_PADDING_RIGHT;
	i = 0;
	while (i < dimensions.columns)
	{
		total_width += DERIVE_OPTION_PADDING_LEFT
			+ column_width[i] + DERIVE_OPTION_PADDING_RIGHT;
		i++;
	}
	return (total_width <= terminal.columns);
}

void			derive_free_rows(
					struct s_derived_dimensions dimensions,
					struct s_state_option ****rows)
{
	size_t	row_index;

	row_index = 0;
	while (row_index < dimensions.rows)
	{
		ft_memdel((void **)&(*rows)[row_index]);
		row_index++;
	}
	ft_memdel((void **)rows);
}