UI: automatically indent lines in dialogues
This commit is contained in:
@@ -8,10 +8,12 @@
|
||||
#include "widget_core.h"
|
||||
#include "../main.h"
|
||||
#include <ncursesw/ncurses.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <utils.h>
|
||||
#include <wchar.h>
|
||||
|
||||
extern int32_t m_id;
|
||||
|
||||
@@ -59,6 +61,49 @@ int32_t w_get_max_line_len(const char *text, int32_t *line_count) {
|
||||
}
|
||||
}
|
||||
|
||||
/* returns number of lines */
|
||||
int32_t w_text_divide_by_lines(wchar_t *restrict text, size_t src_len,
|
||||
int max_x, int *max_len) {
|
||||
int cl_pos = 0;
|
||||
int last_space = -1; /* space position in the current line */
|
||||
int lines_num = 1;
|
||||
|
||||
for (int i = 0; text[i] != '\0'; i++, cl_pos++) {
|
||||
switch (text[i]) {
|
||||
case ' ': /* space symbol */
|
||||
last_space = i;
|
||||
break;
|
||||
case '\n':
|
||||
if (cl_pos > *max_len) {
|
||||
*max_len = cl_pos;
|
||||
}
|
||||
last_space = -1;
|
||||
cl_pos = 0;
|
||||
lines_num++;
|
||||
break;
|
||||
default:
|
||||
if (cl_pos > max_x) {
|
||||
if (last_space > 0) {
|
||||
int line_size = last_space - (i - cl_pos);
|
||||
if (line_size > *max_len) {
|
||||
*max_len = line_size;
|
||||
}
|
||||
text[last_space] = '\n';
|
||||
i = last_space;
|
||||
last_space = -1;
|
||||
cl_pos = 0;
|
||||
lines_num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cl_pos--;
|
||||
if (cl_pos > *max_len) { /* for the last line */
|
||||
*max_len = cl_pos;
|
||||
}
|
||||
return lines_num;
|
||||
}
|
||||
|
||||
/* #define PRINT_TEXT(win, l_buf, text, i, c_line_len, win_width, line_v_pos, \
|
||||
attrs) \
|
||||
strncpy(l_buf, text + i - c_line_len, c_line_len); \
|
||||
@@ -72,7 +117,7 @@ int32_t w_get_max_line_len(const char *text, int32_t *line_count) {
|
||||
}
|
||||
*/
|
||||
|
||||
void PRINT_TEXT(WINDOW *win, char *l_buf, char *text, int32_t i,
|
||||
void line_print(WINDOW *win, char *l_buf, char *text, int32_t i,
|
||||
int32_t c_line_len, int32_t win_width, int32_t line_v_pos,
|
||||
int32_t attrs, int32_t x, int32_t max_line_len) {
|
||||
int32_t utf8len = 0;
|
||||
@@ -90,9 +135,27 @@ void PRINT_TEXT(WINDOW *win, char *l_buf, char *text, int32_t i,
|
||||
}
|
||||
}
|
||||
|
||||
void wline_print(WINDOW *win, wchar_t *w_text, int32_t i, int32_t c_line_len,
|
||||
int32_t win_width, int32_t y, int32_t attrs, int32_t x,
|
||||
int32_t max_line_len) {
|
||||
wchar_t l_buf[DIALOGUE_TEXT];
|
||||
int32_t b_len = c_line_len * sizeof(wchar_t);
|
||||
memcpy(l_buf, w_text + i - c_line_len, b_len);
|
||||
l_buf[c_line_len] = '\0';
|
||||
if ((attrs & PMT_ALIGN_CENTER) == PMT_ALIGN_CENTER) {
|
||||
int32_t _x = x + (win_width - c_line_len) / 2;
|
||||
mvwaddnwstr(win, y, _x, l_buf, c_line_len);
|
||||
} else if (attrs & PMT_POS_CENTER) {
|
||||
int32_t _x = x + (win_width - max_line_len) / 2;
|
||||
mvwaddnwstr(win, y, _x, l_buf, c_line_len);
|
||||
} else {
|
||||
mvwaddnwstr(win, y, x, l_buf, c_line_len);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t w_print_multiline_text(WINDOW *win, const char *_text,
|
||||
const int32_t win_width, const int32_t y,
|
||||
const int32_t x, const int16_t attrs) {
|
||||
const int32_t win_width, const int32_t y,
|
||||
const int32_t x, const int16_t attrs) {
|
||||
|
||||
int16_t line_v_pos = y;
|
||||
int32_t c_line_len = 0;
|
||||
@@ -126,17 +189,64 @@ int32_t w_print_multiline_text(WINDOW *win, const char *_text,
|
||||
|
||||
for (; text[i]; i++, c_line_len++) {
|
||||
if (text[i] == '\n') {
|
||||
PRINT_TEXT(win, l_buf, text, i, c_line_len, win_width, line_v_pos, attrs,
|
||||
line_print(win, l_buf, text, i, c_line_len, win_width, line_v_pos, attrs,
|
||||
x, m_line_len);
|
||||
c_line_len = -1;
|
||||
line_v_pos++;
|
||||
}
|
||||
}
|
||||
|
||||
PRINT_TEXT(win, l_buf, text, i, c_line_len, win_width, line_v_pos, attrs, x,
|
||||
line_print(win, l_buf, text, i, c_line_len, win_width, line_v_pos, attrs, x,
|
||||
m_line_len);
|
||||
|
||||
free(text);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t w_print_multiline_text_wide(WINDOW *win, const wchar_t *_text,
|
||||
size_t text_len, int32_t max_line_size,
|
||||
const int32_t win_width, const int32_t y,
|
||||
const int32_t x, const int16_t attrs) {
|
||||
|
||||
int16_t line_v_pos = y;
|
||||
int32_t c_line_len = 0;
|
||||
int32_t i = 0;
|
||||
int text_bytes_size = sizeof(wchar_t) * (text_len + 1);
|
||||
wchar_t *text = malloc(text_bytes_size);
|
||||
mempcpy(text, _text, text_bytes_size);
|
||||
|
||||
int l_size = 0;
|
||||
for (int m = 0; text[m] != '\0'; m++) {
|
||||
if (text[m] != '\n') {
|
||||
if (l_size >= win_width) {
|
||||
int j = m;
|
||||
while (text[j] != ' ') {
|
||||
j--;
|
||||
}
|
||||
text[j] = '\n';
|
||||
l_size = 0;
|
||||
} else {
|
||||
l_size++;
|
||||
}
|
||||
} else {
|
||||
l_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (; text[i]; i++, c_line_len++) {
|
||||
if (text[i] == '\n') {
|
||||
wline_print(win, text, i, c_line_len, win_width, line_v_pos, attrs, x,
|
||||
max_line_size);
|
||||
c_line_len = -1;
|
||||
line_v_pos++;
|
||||
}
|
||||
}
|
||||
|
||||
wline_print(win, text, i, c_line_len, win_width, line_v_pos, attrs, x,
|
||||
max_line_size);
|
||||
|
||||
free(text);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -59,8 +59,8 @@ enum w_cbrp_code {
|
||||
|
||||
/* widget callback response data */
|
||||
typedef struct {
|
||||
enum w_cbrp_code code;
|
||||
struct w_val_t val;
|
||||
enum w_cbrp_code code;
|
||||
struct w_val_t val;
|
||||
} w_cbrp_data;
|
||||
|
||||
typedef struct {
|
||||
@@ -103,10 +103,16 @@ enum w_pmt_attrs {
|
||||
PMT_ALIGN_CENTER = 03,
|
||||
};
|
||||
|
||||
void w_init(w_t *w, w_t *w_parent, WINDOW **win, char *title);
|
||||
int32_t w_get_max_line_len(const char *text, int32_t *line_count);
|
||||
int32_t w_print_multiline_text(WINDOW *win, const char *text,
|
||||
const int32_t win_width, const int32_t y,
|
||||
const int32_t x, const int16_t attrs);
|
||||
void w_init(w_t *w, w_t *w_parent, WINDOW **win, char *title);
|
||||
int32_t w_get_max_line_len(const char *text, int32_t *line_count);
|
||||
int32_t w_print_multiline_text(WINDOW *win, const char *text,
|
||||
const int32_t win_width, const int32_t y,
|
||||
const int32_t x, const int16_t attrs);
|
||||
int32_t w_print_multiline_text_wide(WINDOW *win, const wchar_t *_text,
|
||||
size_t text_len, int32_t max_line_size, const int32_t win_width,
|
||||
const int32_t y, const int32_t x,
|
||||
const int16_t attrs);
|
||||
int32_t w_text_divide_by_lines(wchar_t *restrict text, size_t src_len,
|
||||
int max_x, int *max_len);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user