Clone in a terminal:
Commit ab12c49
Johan Mattsson - 2014-11-22T12:45:52+00:00
ab12c495e950bee4d2800c4169081c96a6ebbfe9johan.mattsson.m@gmail.com

Delete selected text int text area

Changed files (2)

Diff

diff --git a/libbirdfont/DescriptionDisplay.vala b/libbirdfont/DescriptionDisplay.valaindex d386523..034bca2 100644--- a/libbirdfont/DescriptionDisplay.vala+++ b/libbirdfont/DescriptionDisplay.vala@@ -251,7 +251,7 @@ public class DescriptionDisplay : FontDisplay { 				focus.move_carret_previous_row (); 				break; 			case Key.BACK_SPACE:-				if (focus.has_selection () && focus.show_selection) {+				if (focus.has_selection ()) { 					focus.delete_selected_text (); 				} else { 					focus.remove_last_character ();@@ -261,7 +261,7 @@ public class DescriptionDisplay : FontDisplay { 				focus.insert_text ("\n"); 				break; 			case Key.DEL:-				if (focus.has_selection () && focus.show_selection) {+				if (focus.has_selection ()) { 					focus.delete_selected_text (); 				} else { 					focus.remove_next_character ();diff --git a/libbirdfont/Renderer/TextArea.vala b/libbirdfont/Renderer/TextArea.valaindex 611f339..690c109 100644--- a/libbirdfont/Renderer/TextArea.vala+++ b/libbirdfont/Renderer/TextArea.vala@@ -125,7 +125,7 @@ public class TextArea : Widget { 	} 	 	public string get_selected_text () {-		if (!has_selection () && show_selection) {+		if (!has_selection ()) { 			return "".dup (); 		} 		@@ -134,11 +134,11 @@ public class TextArea : Widget { 	} 	 	public void select_all () {-		if (paragraphs.size > 0) {-			while (last_paragraph != DONE) {-				generate_paragraphs ();-			}+		while (last_paragraph != DONE) {+			generate_paragraphs ();+		} 			+		if (paragraphs.size > 0) { 			carret.paragraph = 0; 			carret.character_index = 0; 			selection_end.paragraph = paragraphs.size - 1;@@ -150,10 +150,15 @@ public class TextArea : Widget { 	public void delete_selected_text () { 		Carret selection_start, selection_stop; 		int i;-		Paragraph pg;+		Paragraph pg, pge; 		string e, s, n;+		bool same; 		-		if (show_selection) {+		e = "";+		s = "";+		n = "";+		+		if (has_selection ()) { 			if (carret.paragraph == selection_end.paragraph) { 				selection_start = carret.character_index < selection_end.character_index ? carret : selection_end; 				selection_stop = carret.character_index > selection_end.character_index ? carret : selection_end;@@ -161,29 +166,53 @@ public class TextArea : Widget { 				selection_start = carret.paragraph < selection_end.paragraph ? carret : selection_end; 				selection_stop = carret.paragraph > selection_end.paragraph ? carret : selection_end;	 			}--			if (selection_start.paragraph != selection_stop.paragraph) {+			+			same = selection_start.paragraph == selection_stop.paragraph;+			+			if (!same) { 				pg = paragraphs.get (selection_start.paragraph); 				s = pg.text.substring (0, selection_start.character_index); 				pg.set_text (s);-				-				pg = paragraphs.get (selection_stop.paragraph);-				e = pg.text.substring (selection_start.character_index);-				pg.set_text (e);++				pge = paragraphs.get (selection_stop.paragraph);+				e = pge.text.substring (selection_stop.character_index);+								+				if (!s.has_suffix ("\n")) {+					pg.set_text (s + e);+					pge.set_text ("");+				} else {+					pge.set_text (e);+				} 			} else { 				pg = paragraphs.get (selection_start.paragraph); 				n = pg.text.substring (0, selection_start.character_index); 				n += pg.text.substring (selection_stop.character_index);-				pg.set_text (n);	+				pg.set_text (n);+				+				if (n == "") {+					paragraphs.remove_at (selection_start.paragraph);+				} 			}-						+			+			if (e == "" && !same) {+				paragraphs.remove_at (selection_stop.paragraph);+			}+			 			for (i = selection_stop.paragraph - 1; i > selection_start.paragraph; i--) {-				return_if_fail (0 <= i <= paragraphs.size);+				return_if_fail (0 <= i < paragraphs.size); 				paragraphs.remove_at (i); 			}+			+			if (s == "" && !same) {+				paragraphs.remove_at (selection_start.paragraph);+			}+			+			carret = selection_start;+			selection_end = carret.copy ();+					+			show_selection = false;+			layout (); 		}-		-		show_selection = false; 	} 	 	public void remove_last_character () {@@ -308,8 +337,12 @@ public class TextArea : Widget { 			carret = get_carret_at (carret.desired_x, carret.desired_y + nr); 		} 	}-		+	 	public bool has_selection () {+		return show_selection && selection_is_visible ();+	}+	+	private bool selection_is_visible () { 		return carret.paragraph != selection_end.paragraph || carret.character_index != selection_end.character_index; 	} 		@@ -378,6 +411,7 @@ public class TextArea : Widget { 		int ch_index; 		double min_d = double.MAX; 		Carret c = new Carret ();+		double dt;  		c.paragraph = -1; 		c.desired_x = click_x;@@ -397,26 +431,46 @@ public class TextArea : Widget { 					 					p = next_word.get_sidebearing_extent (); -					if (ty - next_word.font_size + next_word.get_baseline_to_bottom () <= click_y <= ty + next_word.get_baseline_to_bottom ()) {+					if ((ty - next_word.font_size + next_word.get_baseline_to_bottom () <= click_y <= ty + next_word.get_baseline_to_bottom ())+						&& (next_word.widget_x + widget_x + padding <= click_x <= next_word.widget_x + widget_x + padding + next_word.get_sidebearing_extent ())) {+						 						next_word.iterate ((glyph, kerning, last) => { 							double cw; 							int ci; 							double d;-							-							cw = (glyph.get_width ()) * next_word.get_scale () + kerning;-							ci = ((!) glyph.get_unichar ().to_string ()).length;-							-							d = Math.fabs (click_x - (tx + widget_x + cw + padding));++							d = Math.fabs (click_x - (tx + widget_x + padding)); 							if (d < min_d) { 								min_d = d;-								c.character_index = ch_index + ci;+								c.character_index = ch_index; 								c.paragraph = i; 							} 							+							cw = (glyph.get_width ()) * next_word.get_scale () + kerning;+							ci = ((!) glyph.get_unichar ().to_string ()).length;+							 							tx += cw; 							ch_index += ci; 						});++						+						dt = Math.fabs (click_x - (tx + widget_x + padding));+						if (dt < min_d) {+							min_d = dt;+							c.character_index = ch_index;+							c.paragraph = i;+						} 					} else {+					+						if (ty - next_word.font_size + next_word.get_baseline_to_bottom () <= click_y <= ty + next_word.get_baseline_to_bottom ()) {+							dt = Math.fabs (click_x - (tx + widget_x + padding));+							if (dt < min_d) {+								min_d = dt;+								c.character_index = ch_index;+								c.paragraph = i;+							}+						}+						 						if (tx + p > width || w == "\n") { 							tx = 0; 							ty += next_word.font_size;@@ -448,20 +502,25 @@ public class TextArea : Widget { 		string w; 		double xmax = 0; 		double width = this.width - 2 * padding;-		int carret_paragraph = 0;-		int carret_position = 0; 		int i = 0; 		double dd; 		-		if (paragraphs.size > 0) {-			carret_position = paragraphs.get (carret_paragraph).text.length;-			carret_paragraph = paragraphs.size - 1;-		}-		 		tx = 0; 		ty = font_size; +		for (i = paragraphs.size - 1; i >= 0; i--) {+			if (paragraphs.get (i).is_empty ()) {+				paragraphs.remove_at (i);+			}+		}++		i = 0; 		foreach (Paragraph paragraph in paragraphs) {+			+			if (unlikely (paragraph.is_empty ())) {+				warning ("Empty.");+			}+			 			if (paragraph.need_layout) {  				paragraph.start_y = ty;@@ -536,6 +595,9 @@ public class TextArea : Widget { 			if (dd != 0) { 				paragraph.start_y += dd; 				paragraph.end_y += dd;+				foreach (Text word in paragraph.words) {+					word.widget_y += dd;+				} 			} 						 			ty = paragraph.end_y;@@ -552,12 +614,13 @@ public class TextArea : Widget {  	public void button_release (uint button, double x, double y) { 		update_selection = false;+		show_selection = selection_is_visible (); 	} 	 	public bool motion (double x, double y) { 		if (update_selection) { 			selection_end = get_carret_at (x, y);-			show_selection = has_selection ();+			show_selection = selection_is_visible (); 		} 		 		return update_selection;@@ -607,7 +670,7 @@ public class TextArea : Widget { 		y += font_size; 		 		// draw selection background-		if (has_selection () && show_selection) {+		if (has_selection ()) { 			tx = 0; 			ty = 0; 			@@ -623,22 +686,21 @@ public class TextArea : Widget { 			cr.set_source_rgba (234 / 255.0, 77 / 255.0, 26 / 255.0, 1);  			for (int i = selection_start.paragraph; i <= selection_end.paragraph; i++) {-				return_if_fail (0 <= i <= paragraphs.size);+				return_if_fail (0 <= i < paragraphs.size); 				Paragraph pg = paragraphs.get (i);  				if (pg.text_is_on_screen (allocation, widget_y)) { 					int char_index = 0;--					tx = pg.start_x + widget_x + padding;-					ty = pg.start_y; 					 					foreach (Text next_word in pg.words) { 						double cw = next_word.get_sidebearing_extent (); 						bool paint_background = false; 						bool partial_start = false; 						bool partial_stop = false;+						int wl; 						 						w = next_word.text;+						wl = w.length; 						scale = next_word.get_scale (); 												 						if (selection_start.paragraph == selection_end.paragraph) {@@ -650,8 +712,8 @@ public class TextArea : Widget { 							paint_background = true; 							partial_start = true; 						} else if (selection_end.paragraph == i) {-							paint_background = true;-							partial_stop = true;+							paint_background = char_index + wl < selection_end.character_index;+							partial_stop = !paint_background; 						} 						 						if (paint_background && !(partial_start || partial_stop)) {	@@ -667,8 +729,8 @@ public class TextArea : Widget { 							next_word.iterate ((glyph, kerning, last) => { 								double cwi; 								int ci;-								bool draw = (index > selection_start.character_index && partial_start && !partial_stop)-									|| (index < selection_start.character_index && !partial_start && partial_stop)+								bool draw = (index >= selection_start.character_index && partial_start && !partial_stop)+									|| (index < selection_stop.character_index && !partial_start && partial_stop) 									|| (selection_start.character_index <= index < selection_stop.character_index && partial_start && partial_stop); 								 								cwi = (glyph.get_width ()) * next_word.get_scale () + kerning;@@ -683,7 +745,7 @@ public class TextArea : Widget { 								ci = ((!) glyph.get_unichar ().to_string ()).length; 								index += ci; 							});-						}				+						}	 					 						char_index += w.length;	 					}@@ -760,17 +822,36 @@ public class TextArea : Widget { 			} 		} 		-		get_carret_position (out carret_x, out carret_y);-		draw_carret_at (cr, carret_x, carret_y);+		+		+		if (carret_is_visible) {+			get_carret_position (carret, out carret_x, out carret_y);+			+			if (carret_y < 0) {+				draw_carret_at (cr, widget_x + padding, widget_y + font_size + padding);+			} else {+				draw_carret_at (cr, carret_x, carret_y);+			}+		}+		+		if (has_selection ()) {+			get_carret_position (selection_end, out carret_x, out carret_y);+			+			if (carret_y < 0) {+				draw_carret_at (cr, widget_x + padding, widget_y + font_size + padding);+			} else {+				draw_carret_at (cr, carret_x, carret_y);+			}+		} 	} 	-	void get_carret_position (out double carret_x, out double carret_y) {+	void get_carret_position (Carret carret, out double carret_x, out double carret_y) { 		Paragraph paragraph; 		-		carret_x = 0;-		carret_y = 0;+		carret_x = -1;+		carret_y = -1; 		-		return_if_fail (0 <= carret.paragraph <= paragraphs.size);+		return_if_fail (0 <= carret.paragraph < paragraphs.size); 		paragraph = paragraphs.get (carret.paragraph);  		double tx = paragraph.start_x;@@ -870,6 +951,10 @@ public class TextArea : Widget { 			set_text (text); 		} +		public bool is_empty () {+			return text == "";+		}+ 		public void set_text (string t) { 			this.text = t; 			text_length = t.length;@@ -990,11 +1075,11 @@ public class TextArea : Widget { 		public Carret copy () { 			Carret c = new Carret (); 			-			c.paragraph = c.paragraph;-			c.character_index = c.character_index;+			c.paragraph = paragraph;+			c.character_index = character_index; 			-			c.desired_x = c.desired_x;-			c.desired_y = c.desired_y;+			c.desired_x = desired_x;+			c.desired_y = desired_y; 			 			return c; 		}

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112