Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "textbuf_type.h"
00014 #include "string_func.h"
00015 #include "gfx_type.h"
00016 #include "gfx_func.h"
00017 #include "window_func.h"
00018
00025 bool GetClipboardContents(char *buffer, size_t buff_len);
00026
00027 int _caret_timer;
00028
00029
00030
00031
00032
00033 void Textbuf::DelChar(bool backspace)
00034 {
00035 WChar c;
00036 char *s = this->buf + this->caretpos;
00037
00038 if (backspace) s = Utf8PrevChar(s);
00039
00040 uint16 len = (uint16)Utf8Decode(&c, s);
00041 uint width = GetCharacterWidth(FS_NORMAL, c);
00042
00043 this->pixels -= width;
00044 if (backspace) {
00045 this->caretpos -= len;
00046 this->caretxoffs -= width;
00047 }
00048
00049
00050 memmove(s, s + len, this->bytes - (s - this->buf) - len);
00051 this->bytes -= len;
00052 this->chars--;
00053 }
00054
00061 bool Textbuf::DeleteChar(int delmode)
00062 {
00063 if (delmode == WKC_BACKSPACE && this->caretpos != 0) {
00064 this->DelChar(true);
00065 return true;
00066 } else if (delmode == WKC_DELETE && this->caretpos < this->bytes - 1) {
00067 this->DelChar(false);
00068 return true;
00069 }
00070
00071 return false;
00072 }
00073
00077 void Textbuf::DeleteAll()
00078 {
00079 memset(this->buf, 0, this->max_bytes);
00080 this->bytes = this->chars = 1;
00081 this->pixels = this->caretpos = this->caretxoffs = 0;
00082 }
00083
00091 bool Textbuf::InsertChar(WChar key)
00092 {
00093 const byte charwidth = GetCharacterWidth(FS_NORMAL, key);
00094 uint16 len = (uint16)Utf8CharLen(key);
00095 if (this->bytes + len <= this->max_bytes && this->chars + 1 <= this->max_chars) {
00096 memmove(this->buf + this->caretpos + len, this->buf + this->caretpos, this->bytes - this->caretpos);
00097 Utf8Encode(this->buf + this->caretpos, key);
00098 this->chars++;
00099 this->bytes += len;
00100 this->pixels += charwidth;
00101
00102 this->caretpos += len;
00103 this->caretxoffs += charwidth;
00104 return true;
00105 }
00106 return false;
00107 }
00108
00115 bool Textbuf::InsertClipboard()
00116 {
00117 char utf8_buf[512];
00118
00119 if (!GetClipboardContents(utf8_buf, lengthof(utf8_buf))) return false;
00120
00121 uint16 pixels = 0, bytes = 0, chars = 0;
00122 WChar c;
00123 for (const char *ptr = utf8_buf; (c = Utf8Consume(&ptr)) != '\0';) {
00124 if (!IsPrintable(c)) break;
00125
00126 byte len = Utf8CharLen(c);
00127 if (this->bytes + bytes + len > this->max_bytes) break;
00128 if (this->chars + chars + 1 > this->max_chars) break;
00129
00130 byte char_pixels = GetCharacterWidth(FS_NORMAL, c);
00131
00132 pixels += char_pixels;
00133 bytes += len;
00134 chars++;
00135 }
00136
00137 if (bytes == 0) return false;
00138
00139 memmove(this->buf + this->caretpos + bytes, this->buf + this->caretpos, this->bytes - this->caretpos);
00140 memcpy(this->buf + this->caretpos, utf8_buf, bytes);
00141 this->pixels += pixels;
00142 this->caretxoffs += pixels;
00143
00144 this->bytes += bytes;
00145 this->chars += chars;
00146 this->caretpos += bytes;
00147 assert(this->bytes <= this->max_bytes);
00148 assert(this->chars <= this->max_chars);
00149 this->buf[this->bytes - 1] = '\0';
00150
00151 return true;
00152 }
00153
00160 bool Textbuf::MovePos(int navmode)
00161 {
00162 switch (navmode) {
00163 case WKC_LEFT:
00164 if (this->caretpos != 0) {
00165 WChar c;
00166 const char *s = Utf8PrevChar(this->buf + this->caretpos);
00167 Utf8Decode(&c, s);
00168 this->caretpos = s - this->buf;
00169 this->caretxoffs -= GetCharacterWidth(FS_NORMAL, c);
00170
00171 return true;
00172 }
00173 break;
00174
00175 case WKC_RIGHT:
00176 if (this->caretpos < this->bytes - 1) {
00177 WChar c;
00178
00179 this->caretpos += (uint16)Utf8Decode(&c, this->buf + this->caretpos);
00180 this->caretxoffs += GetCharacterWidth(FS_NORMAL, c);
00181
00182 return true;
00183 }
00184 break;
00185
00186 case WKC_HOME:
00187 this->caretpos = 0;
00188 this->caretxoffs = 0;
00189 return true;
00190
00191 case WKC_END:
00192 this->caretpos = this->bytes - 1;
00193 this->caretxoffs = this->pixels;
00194 return true;
00195
00196 default:
00197 break;
00198 }
00199
00200 return false;
00201 }
00202
00209 void Textbuf::Initialize(char *buf, uint16 max_bytes)
00210 {
00211 this->Initialize(buf, max_bytes, max_bytes);
00212 }
00213
00221 void Textbuf::Initialize(char *buf, uint16 max_bytes, uint16 max_chars)
00222 {
00223 assert(max_bytes != 0);
00224 assert(max_chars != 0);
00225
00226 this->buf = buf;
00227 this->max_bytes = max_bytes;
00228 this->max_chars = max_chars;
00229 this->caret = true;
00230 this->UpdateSize();
00231 }
00232
00238 void Textbuf::UpdateSize()
00239 {
00240 const char *buf = this->buf;
00241
00242 this->pixels = 0;
00243 this->chars = this->bytes = 1;
00244
00245 WChar c;
00246 while ((c = Utf8Consume(&buf)) != '\0') {
00247 this->pixels += GetCharacterWidth(FS_NORMAL, c);
00248 this->bytes += Utf8CharLen(c);
00249 this->chars++;
00250 }
00251
00252 assert(this->bytes <= this->max_bytes);
00253 assert(this->chars <= this->max_chars);
00254
00255 this->caretpos = this->bytes - 1;
00256 this->caretxoffs = this->pixels;
00257 }
00258
00263 bool Textbuf::HandleCaret()
00264 {
00265
00266 bool b = !!(_caret_timer & 0x20);
00267
00268 if (b != this->caret) {
00269 this->caret = b;
00270 return true;
00271 }
00272 return false;
00273 }