changeset 20718:9b39704a6cd8 draft

-Add: Replacement of a part of the edit box text with a new string.
author Michael Lutz <michi@icosahedron.de>
date Sun, 28 Jul 2013 23:25:00 +0200
parents 19b7ec9e442d
children 78eaf05c8c37
files src/console_gui.cpp src/gfx_func.h src/textbuf.cpp src/textbuf_type.h src/window.cpp src/window_gui.h
diffstat 6 files changed, 47 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/console_gui.cpp
+++ b/src/console_gui.cpp
@@ -311,9 +311,9 @@
 		return ES_HANDLED;
 	}
 
-	virtual void InsertTextString(int wid, const char *str, bool marked, const char *caret)
+	virtual void InsertTextString(int wid, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end)
 	{
-		if (_iconsole_cmdline.InsertString(str, marked, caret)) {
+		if (_iconsole_cmdline.InsertString(str, marked, caret, insert_location, replacement_end)) {
 			IConsoleWindow::scroll = 0;
 			IConsoleResetHistoryPos();
 			this->SetDirty();
--- a/src/gfx_func.h
+++ b/src/gfx_func.h
@@ -71,7 +71,7 @@
 extern Palette _cur_palette; ///< Current palette
 
 void HandleKeypress(uint keycode, WChar key);
-void HandleTextInput(const char *str, bool marked = false, const char *caret = NULL);
+void HandleTextInput(const char *str, bool marked = false, const char *caret = NULL, const char *insert_location = NULL, const char *replacement_end = NULL);
 void HandleCtrlChanged();
 void HandleMouseEvents();
 void CSleep(int milliseconds);
--- a/src/textbuf.cpp
+++ b/src/textbuf.cpp
@@ -153,13 +153,23 @@
  * @param str String to insert.
  * @param marked Replace the currently marked text with the new text.
  * @param caret Move the caret to this point in the insertion string.
+ * @param insert_location Position at which to insert the string.
+ * @param replacement_end Replace all characters from #insert_location up to this location with the new string.
  * @return True on successful change of Textbuf, or false otherwise.
  */
-bool Textbuf::InsertString(const char *str, bool marked, const char *caret)
+bool Textbuf::InsertString(const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end)
 {
 	uint16 insertpos = (marked && this->marklength != 0) ? this->markpos : this->caretpos;
+	if (insert_location != NULL) {
+		insertpos = insert_location - this->buf;
+		if (insertpos > this->bytes) return NULL;
 
-	if (marked) this->DiscardMarkedText(str == NULL);
+		if (replacement_end != NULL) {
+			this->DeleteText(insertpos, replacement_end - this->buf, str == NULL);
+		}
+	} else {
+		if (marked) this->DiscardMarkedText(str == NULL);
+	}
 
 	if (str == NULL) return false;
 
@@ -219,35 +229,35 @@
 	return this->InsertString(utf8_buf, false);
 }
 
-/** Discard any marked text. */
-void Textbuf::DiscardMarkedText(bool update)
+/**
+ * Delete a part of the text.
+ * @param from Start of the text to delete.
+ * @param to End of the text to delete.
+ * @param update Set to true if the internal state should be updated.
+ */
+void Textbuf::DeleteText(uint16 from, uint16 to, 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) {
+	const char *s = this->buf + from;
+	while (s < this->buf + to) {
 		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;
+	memmove(this->buf + from, this->buf + to, this->bytes - to);
+	this->bytes -= to - from;
 	this->chars -= c;
 
 	/* Fixup caret if needed. */
-	if (this->caretpos > this->markpos) {
-		if (this->caretpos <= this->markend) {
-			this->caretpos = this->markpos;
+	if (this->caretpos > from) {
+		if (this->caretpos <= to) {
+			this->caretpos = from;
 		} else {
-			this->caretpos -= this->markend - this->markpos;
+			this->caretpos -= to - from;
 		}
 	}
 
-	this->markpos = this->markend = 0;
-
 	if (update) {
 		this->UpdateStringIter();
 		this->UpdateCaretPosition();
@@ -255,6 +265,15 @@
 	}
 }
 
+/** Discard any marked text. */
+void Textbuf::DiscardMarkedText(bool update)
+{
+	if (this->markend == 0) return;
+
+	this->DeleteText(this->markpos, this->markend, update);
+	this->markpos = this->markend = 0;
+}
+
 /** Update the character iter after the text has changed. */
 void Textbuf::UpdateStringIter()
 {
--- a/src/textbuf_type.h
+++ b/src/textbuf_type.h
@@ -56,7 +56,7 @@
 	bool InsertClipboard();
 
 	bool InsertChar(uint32 key);
-	bool InsertString(const char *str, bool marked, const char *caret = NULL);
+	bool InsertString(const char *str, bool marked, const char *caret = NULL, const char *insert_location = NULL, const char *replacement_end = NULL);
 
 	bool DeleteChar(uint16 keycode);
 	bool MovePos(uint16 keycode);
@@ -73,6 +73,8 @@
 
 	bool CanDelChar(bool backspace);
 
+	void DeleteText(uint16 from, uint16 to, bool update);
+
 	void UpdateStringIter();
 	void UpdateWidth();
 	void UpdateCaretPosition();
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -2615,12 +2615,12 @@
  * @param wid Edit box widget.
  * @param str Text string to insert.
  */
-/* virtual */ void Window::InsertTextString(int wid, const char *str, bool marked, const char *caret)
+/* virtual */ void Window::InsertTextString(int wid, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end)
 {
 	QueryString *query = this->GetQueryString(wid);
 	if (query == NULL) return;
 
-	if (query->text.InsertString(str, marked, caret) || marked) {
+	if (query->text.InsertString(str, marked, caret, insert_location, replacement_end) || marked) {
 		this->SetWidgetDirty(wid);
 		this->OnEditboxChanged(wid);
 	}
@@ -2632,11 +2632,11 @@
  * @param marked Is the input a marked composition string from an IME?
  * @param caret Move the caret to this point in the insertion string.
  */
-void HandleTextInput(const char *str, bool marked, const char *caret)
+void HandleTextInput(const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end)
 {
 	if (!EditBoxInGlobalFocus()) return;
 
-	_focused_window->InsertTextString(_focused_window->window_class == WC_CONSOLE ? 0 : _focused_window->nested_focus->index, str, marked, caret);
+	_focused_window->InsertTextString(_focused_window->window_class == WC_CONSOLE ? 0 : _focused_window->nested_focus->index, str, marked, caret, insert_location, replacement_end);
 }
 
 /**
--- a/src/window_gui.h
+++ b/src/window_gui.h
@@ -496,7 +496,7 @@
 	bool SetFocusedWidget(int widget_index);
 
 	EventState HandleEditBoxKey(int wid, WChar key, uint16 keycode);
-	virtual void InsertTextString(int wid, const char *str, bool marked, const char *caret);
+	virtual void InsertTextString(int wid, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end);
 
 	void HandleButtonClick(byte widget);
 	int GetRowFromWidget(int clickpos, int widget, int padding, int line_height = -1) const;