shithub: fc

Download patch

ref: 8e2c4db83ac84ceb86c60e50db20e8aca55ec5e9
parent: f0fae9432d1f553165d7d03412055b7e41ad57fd
author: glenda <glenda@krsna>
date: Sun Aug 17 10:48:53 EDT 2025

paragraphs!

--- a/fc.c
+++ b/fc.c
@@ -34,6 +34,8 @@
 #define BOXHEIGHT 32
 #define MAXFORMULA 256
 #define MAXCONTENT 256
+#define PARAGRAPH_BOX_WIDTH 256
+#define PARAGRAPH_BOX_HEIGHT 128
 
 enum {
 	T_TEXT = 0,
@@ -40,6 +42,7 @@
 	T_NUMBER,
 	T_FORMULA,
 	T_LABEL,
+	T_PARAGRAPH,
 	MAXBOXTYPES,
 };
 
@@ -269,6 +272,9 @@
 Image	*boxediting;
 Image	*gridcolor;
 
+void parse_paragraph(Box*);
+void eval_paragraph(Box*);
+void draw_box_paragraph(Box*, Image*);
 void load_config(char *path);
 void save_config(char *path);
 void apply_config(void);
@@ -388,6 +394,7 @@
 	[T_NUMBER]  = {"number",  parse_number,  eval_number,  draw_box_generic},
 	[T_FORMULA] = {"formula", parse_formula, eval_formula, draw_box_generic},
 	[T_LABEL]   = {"label",   parse_text,    eval_text,    draw_box_generic},
+	[T_PARAGRAPH] = {"paragraph", parse_paragraph, eval_paragraph, draw_box_paragraph},
 };
 
 Function functions[MAXFUNCS] = {
@@ -2018,12 +2025,15 @@
 
 		if(sheet.editbuf[0] == '=') {
 			b->type = T_FORMULA;
+		} else if(sheet.editbuf[0] == '"') {
+			b->type = T_PARAGRAPH;
+			/* Add this line to resize the box */
+			b->r = Rect(b->pos.x, b->pos.y, b->pos.x + PARAGRAPH_BOX_WIDTH, b->pos.y + PARAGRAPH_BOX_HEIGHT);
 		} else {
 			char *endp;
 			strtod(sheet.editbuf, &endp);
 			b->type = (*endp == '\0') ? T_NUMBER : T_TEXT;
 		}
-
 		if (b->type >= 0 && b->type < MAXBOXTYPES) {
 			BoxType *bt = &boxtypes[b->type];
 			if (bt->parse) bt->parse(b);
@@ -2426,6 +2436,106 @@
 	if(fd >= 0) close(fd);
 }
 
+void
+parse_paragraph(Box *b)
+{
+	if(b->formula[0] == '"'){
+		strncpy(b->content, b->formula + 1, MAXCONTENT - 1);
+	} else {
+		strncpy(b->content, b->formula, MAXCONTENT - 1);
+	}
+	b->content[MAXCONTENT-1] = '\0';
+}
+
+void
+eval_paragraph(Box *b)
+{
+	USED(b);
+}
+
+void
+draw_box_paragraph(Box *b, Image *dst)
+{
+	Image *bg = boxbg;
+	int idx = b - sheet.boxes;
+
+	/* Determine background color based on state (editing, selected) */
+	if(sheet.editing == idx)
+		bg = boxediting;
+	else if(sheet.editing_label == idx)
+		bg = colors[5];
+	else if(b->selected)
+		bg = boxselected;
+
+	/* Draw box background and border */
+	draw(dst, b->r, bg, nil, ZP);
+	border(dst, b->r, 1, colors[0], ZP);
+
+	/* Draw the cell's label or default name */
+	char cellname[32];
+	if(sheet.editing_label == idx){
+		snprint(cellname, sizeof(cellname), "%s", sheet.labelbuf);
+		string(dst, Pt(b->r.min.x + 2, b->r.min.y + 2), colors[4], ZP, font, cellname);
+	} else if(b->label[0]) {
+		snprint(cellname, sizeof(cellname), "%s", b->label);
+		string(dst, Pt(b->r.min.x + 2, b->r.min.y + 2), colors[4], ZP, font, cellname);
+	} else {
+		if(idx < 26) {
+			snprint(cellname, sizeof(cellname), "%c", 'A' + idx);
+		} else {
+			snprint(cellname, sizeof(cellname), "%c%c", 'A' + (idx/26)-1, 'A' + (idx%26));
+		}
+		string(dst, Pt(b->r.min.x + 2, b->r.min.y + 2), colors[3], ZP, font, cellname);
+	}
+
+	/* Text wrapping logic */
+	Point p = addpt(b->r.min, Pt(config.box_text_margin, config.box_label_offset_y));
+	char *text_to_draw = (sheet.editing == idx) ? sheet.editbuf : b->content;
+	int max_width = Dx(b->r) - (2 * config.box_text_margin);
+	int line_height = font->height;
+
+	char *text = text_to_draw;
+	char *line_start = text;
+	char line_buffer[MAXCONTENT];
+
+	while (*line_start) {
+		char *word_ptr = line_start;
+		char *line_end = line_start;
+		
+		while (*word_ptr) {
+			char *word_start = word_ptr;
+			while(*word_ptr && !isspace(*word_ptr))
+				word_ptr++;
+			
+			int word_len = word_ptr - line_start;
+			if(word_len >= MAXCONTENT) break;
+
+			strncpy(line_buffer, line_start, word_len);
+			line_buffer[word_len] = '\0';
+
+			if(stringwidth(font, line_buffer) > max_width) {
+				if(line_end == line_start)
+					line_end = word_start;
+				break;
+			}
+			line_end = word_ptr;
+
+			while(*word_ptr && isspace(*word_ptr))
+				word_ptr++;
+		}
+		
+		int len = line_end - line_start;
+		stringn(dst, p, colors[0], ZP, font, line_start, len);
+		p.y += line_height;
+		
+		if (p.y > b->r.max.y - config.box_text_margin - line_height)
+			break;
+
+		line_start = line_end;
+		while(*line_start && isspace(*line_start))
+			line_start++;
+	}
+}
 void
 eresized(int new)
 {
--