changeset 20708:bd8f5e4c1617 draft

-Add: Support for a marked/selected range to the textbuf.
author Michael Lutz <michi@icosahedron.de>
date Mon, 22 Jul 2013 22:53:00 +0200
parents 59932ff02821
children 55b7d139bae4
files src/console_gui.cpp src/misc_gui.cpp src/textbuf.cpp src/textbuf_type.h
diffstat 4 files changed, 65 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/console_gui.cpp
+++ b/src/console_gui.cpp
@@ -216,6 +216,9 @@
 			delta = 0;
 		}
 
+		/* If we have a marked area, draw a background highlight. */
+		if (_iconsole_cmdline.marklength != 0) GfxFillRect(this->line_offset + delta + _iconsole_cmdline.markxoffs, this->height - this->line_height, this->line_offset + delta + _iconsole_cmdline.markxoffs + _iconsole_cmdline.marklength, this->height - 1, PC_DARK_RED);
+
 		DrawString(this->line_offset + delta, right, this->height - this->line_height, _iconsole_cmdline.buf, (TextColour)CC_COMMAND, SA_LEFT | SA_FORCE);
 
 		if (_focused_window == this && _iconsole_cmdline.caret) {
--- a/src/misc_gui.cpp
+++ b/src/misc_gui.cpp
@@ -775,6 +775,9 @@
 
 	if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs;
 
+	/* If we have a marked area, draw a background highlight. */
+	if (tb->marklength != 0) GfxFillRect(delta + tb->markxoffs, 0, delta + tb->markxoffs + tb->marklength - 1, bottom - top, PC_GREY);
+
 	DrawString(delta, tb->pixels, 0, tb->buf, TC_YELLOW);
 	bool focussed = w->IsWidgetGloballyFocused(wid) || IsOSKOpenedFor(w, wid);
 	if (focussed && tb->caret) {
--- a/src/textbuf.cpp
+++ b/src/textbuf.cpp
@@ -103,6 +103,7 @@
 	this->UpdateStringIter();
 	this->UpdateWidth();
 	this->UpdateCaretPosition();
+	this->UpdateMarkedText();
 
 	return true;
 }
@@ -115,6 +116,7 @@
 	memset(this->buf, 0, this->max_bytes);
 	this->bytes = this->chars = 1;
 	this->pixels = this->caretpos = this->caretxoffs = 0;
+	this->markpos = this->markend = this->markxoffs = this->marklength = 0;
 	this->UpdateStringIter();
 }
 
@@ -138,6 +140,7 @@
 		this->UpdateStringIter();
 		this->UpdateWidth();
 		this->UpdateCaretPosition();
+		this->UpdateMarkedText();
 		return true;
 	}
 	return false;
@@ -181,6 +184,7 @@
 	this->UpdateStringIter();
 	this->UpdateWidth();
 	this->UpdateCaretPosition();
+	this->UpdateMarkedText();
 
 	return true;
 }
@@ -200,6 +204,42 @@
 	return this->InsertString(utf8_buf);
 }
 
+/** Discard any marked text. */
+void Textbuf::DiscardMarkedText(bool update)
+{
+	if (this->markend == 0) return;
+
+	/* Count marked characters. */
+	uint c = 0;
+	const char *s = this->buf + this->markpos;
+	while (s < this->buf + this->markend) {
+		Utf8Consume(&s);
+		c++;
+	}
+
+	/* Strip marked characters from buffer. */
+	memmove(this->buf + this->markpos, this->buf + this->markend, this->bytes - this->markend);
+	this->bytes -= this->markend - this->markpos;
+	this->chars -= c;
+
+	/* Fixup caret if needed. */
+	if (this->caretpos > this->markpos) {
+		if (this->caretpos <= this->markend) {
+			this->caretpos = this->markpos;
+		} else {
+			this->caretpos -= this->markend - this->markpos;
+		}
+	}
+
+	this->markpos = this->markend = 0;
+
+	if (update) {
+		this->UpdateStringIter();
+		this->UpdateCaretPosition();
+		this->UpdateMarkedText();
+	}
+}
+
 /** Update the character iter after the text has changed. */
 void Textbuf::UpdateStringIter()
 {
@@ -220,6 +260,17 @@
 	this->caretxoffs = this->chars > 1 ? GetCharPosInString(this->buf, this->buf + this->caretpos, FS_NORMAL).x : 0;
 }
 
+/** Update pixel positions of the marked text area. */
+void Textbuf::UpdateMarkedText()
+{
+	if (this->markend != 0) {
+		this->markxoffs  = GetCharPosInString(this->buf, this->buf + this->markpos, FS_NORMAL).x;
+		this->marklength = GetCharPosInString(this->buf, this->buf + this->markend, FS_NORMAL).x - this->markxoffs;
+	} else {
+		this->markxoffs = this->marklength = 0;
+	}
+}
+
 /**
  * Handle text navigation with arrow keys left/right.
  * This defines where the caret will blink and the next character interaction will occur
@@ -355,6 +406,7 @@
 	this->caretpos = this->bytes - 1;
 	this->UpdateStringIter();
 	this->UpdateWidth();
+	this->UpdateMarkedText();
 
 	this->UpdateCaretPosition();
 }
--- a/src/textbuf_type.h
+++ b/src/textbuf_type.h
@@ -40,6 +40,10 @@
 	bool caret;               ///< is the caret ("_") visible or not
 	uint16 caretpos;          ///< the current position of the caret in the buffer, in bytes
 	uint16 caretxoffs;        ///< the current position of the caret in pixels
+	uint16 markpos;           ///< the start position of the marked area in the buffer, in bytes
+	uint16 markend;           ///< the end position of the marked area in the buffer, in bytes
+	uint16 markxoffs;         ///< the start position of the marked area in pixels
+	uint16 marklength;        ///< the length of the marked area in pixels
 
 	explicit Textbuf(uint16 max_bytes, uint16 max_chars = UINT16_MAX);
 	~Textbuf();
@@ -62,6 +66,8 @@
 	bool HandleCaret();
 	void UpdateSize();
 
+	void DiscardMarkedText(bool update = true);
+
 private:
 	StringIterator *char_iter;
 
@@ -70,6 +76,7 @@
 	void UpdateStringIter();
 	void UpdateWidth();
 	void UpdateCaretPosition();
+	void UpdateMarkedText();
 };
 
 #endif /* TEXTBUF_TYPE_H */