~nloomans/ft_select

ref: 1e1794e18e668196cc6b0e137316f1903964b06d ft_select/src/derive.c -rw-r--r-- 3.2 KiB
1e1794e1Noah Loomans display message when terminal is too small to display all options 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
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
137
138
#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 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 options)
{
	size_t			row_index;
	size_t			column_index;
	t_list2_item	*curr_option;

	*res = ft_memalloc(dimensions.columns * sizeof(**res));
	if (*res == NULL)
		return errorf("unable to malloc column width array");
	curr_option = options.first;
	column_index = 0;
	while (column_index < dimensions.columns)
	{
		row_index = 0;
		while (row_index < dimensions.rows && curr_option != NULL)
		{
			(*res)[column_index] = max(
				ft_strlen(
					((struct s_state_option *)curr_option->content)->name),
				(*res)[column_index]);
			curr_option = curr_option->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 options)
{
	size_t			row_index;
	size_t			column_index;
	t_list2_item	*curr_option;
	t_error			error;

	error = malloc_rows(res, dimensions);
	if (is_error(error))
		return (error);
	curr_option = options.first;
	column_index = 0;
	while (column_index < dimensions.columns)
	{
		row_index = 0;
		while (row_index < dimensions.rows && curr_option != NULL)
		{
			(*res)[row_index][column_index] =
				(struct s_state_option *)curr_option->content;
			curr_option = curr_option->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);
}