summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormichi_cc <michi_cc@openttd.org>2013-08-05 20:37:22 +0000
committermichi_cc <michi_cc@openttd.org>2013-08-05 20:37:22 +0000
commit64d2fc4d1e4124a55ccee8c4a4c6e43d1c2ae9fe (patch)
tree90f51bd4c12f00dbd8daac0075d25a1972f85329 /src
parentcbdfd31a3c4607501d3869af87695b524b51a911 (diff)
downloadopenttd-64d2fc4d1e4124a55ccee8c4a4c6e43d1c2ae9fe.tar.xz
(svn r25683) -Add: Support for a marked/selected range to the textbuf.
Diffstat (limited to 'src')
-rw-r--r--src/console_gui.cpp3
-rw-r--r--src/misc_gui.cpp3
-rw-r--r--src/textbuf.cpp55
-rw-r--r--src/textbuf_type.h7
4 files changed, 68 insertions, 0 deletions
diff --git a/src/console_gui.cpp b/src/console_gui.cpp
index 772ead610..9a48f72a6 100644
--- a/src/console_gui.cpp
+++ b/src/console_gui.cpp
@@ -216,6 +216,9 @@ struct IConsoleWindow : Window
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) {
diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp
index 37a317733..cd1f034a8 100644
--- a/src/misc_gui.cpp
+++ b/src/misc_gui.cpp
@@ -775,6 +775,9 @@ void QueryString::DrawEditBox(const Window *w, int wid) const
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) {
diff --git a/src/textbuf.cpp b/src/textbuf.cpp
index 2278be572..aea7c4918 100644
--- a/src/textbuf.cpp
+++ b/src/textbuf.cpp
@@ -103,6 +103,7 @@ bool Textbuf::DeleteChar(uint16 keycode)
this->UpdateStringIter();
this->UpdateWidth();
this->UpdateCaretPosition();
+ this->UpdateMarkedText();
return true;
}
@@ -115,6 +116,7 @@ void Textbuf::DeleteAll()
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 @@ bool Textbuf::InsertChar(WChar key)
this->UpdateStringIter();
this->UpdateWidth();
this->UpdateCaretPosition();
+ this->UpdateMarkedText();
return true;
}
return false;
@@ -181,6 +184,7 @@ bool Textbuf::InsertString(const char *str)
this->UpdateStringIter();
this->UpdateWidth();
this->UpdateCaretPosition();
+ this->UpdateMarkedText();
return true;
}
@@ -200,6 +204,45 @@ bool Textbuf::InsertClipboard()
return this->InsertString(utf8_buf);
}
+/**
+ * Discard any marked text.
+ * @param update Set to true if the internal state should be updated.
+ */
+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 +263,17 @@ void Textbuf::UpdateCaretPosition()
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 +409,7 @@ void Textbuf::UpdateSize()
this->caretpos = this->bytes - 1;
this->UpdateStringIter();
this->UpdateWidth();
+ this->UpdateMarkedText();
this->UpdateCaretPosition();
}
diff --git a/src/textbuf_type.h b/src/textbuf_type.h
index 7f3673623..910e7fa5f 100644
--- a/src/textbuf_type.h
+++ b/src/textbuf_type.h
@@ -40,6 +40,10 @@ struct Textbuf {
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 @@ struct Textbuf {
bool HandleCaret();
void UpdateSize();
+ void DiscardMarkedText(bool update = true);
+
private:
StringIterator *char_iter;
@@ -70,6 +76,7 @@ private:
void UpdateStringIter();
void UpdateWidth();
void UpdateCaretPosition();
+ void UpdateMarkedText();
};
#endif /* TEXTBUF_TYPE_H */