is_utf8 = 1;
skip_cursor = 0;
reset_parameters(rows, has_border, font, size);
- if( size > 0 )
+ if( size >= 0 )
tstrcpy(text);
- else // text referenced directly
+ else // reference shared directly
this->text = text;
}
{
is_utf8 = 1;
skip_cursor = 0;
- wsize = size > 0 ? size : wcslen(wtext);
- if( size <= 0 ) size = 2*wsize;
reset_parameters(rows, has_border, font, size);
- this->wtext = new wchar_t[wsize+1];
+ wdemand(wcslen(wtext));
wcsncpy(this->wtext, wtext, wsize);
- this->wtext[wsize] = 0;
}
BC_TextBox::BC_TextBox(int x, int y, int w, int rows,
delete suggestions;
delete menu;
delete [] wtext;
- if( size > 0 )
+ if( size >= 0 )
delete [] text;
}
this->rows = rows;
this->has_border = has_border;
this->font = font;
+// size > 0: fixed buffer, size == 0: dynamic buffer
+// size < 0: fixed shared buffer via set_text
this->size = size;
this->tsize = size >= 0 ? size : -size;
- this->text = size > 0 ? new char[size+1] : 0;
+ this->text = size > 0 ? new char[this->tsize+1] : 0;
if( this->text ) this->text[0] = 0;
text_start = 0;
text_end = 0;
int BC_TextBox::tstrlen()
{
- if( !tsize ) return strlen(text);
- return strnlen(text, tsize);
+ return !text ? 0 : strnlen(text, tsize);
}
int BC_TextBox::tstrcmp(const char *cp)
{
const char *tp = get_text();
- if( !tsize ) return strcmp(tp, cp);
return strncmp(tp, cp, tsize);
}
{
dirty = 1;
if( cp ) {
- if( !tsize )
- return strcpy(text, cp);
+ if( !size ) tdemand(strlen(cp));
strncpy(text, cp, tsize);
- text[tsize-1] = 0;
}
- else
+ else if( text )
text[0] = 0;
return text;
}
char *BC_TextBox::tstrcat(const char *cp)
{
dirty = 1;
- if( !tsize ) return strcat(text, cp);
+ if( !size ) tdemand(tstrlen() + strlen(cp));
char *result = strncat(text, cp, tsize);
- text[tsize-1] = 0;
return result;
}
if( dirty ) {
const char *src_enc = is_utf8 ? "UTF8" : BC_Resources::encoding;
const char *dst_enc = BC_Resources::wide_encoding;
- int nsize = tsize > 0 ? tsize : strlen(text) + BCTEXTLEN;
- if( nsize > wsize || !wtext ) {
- wchar_t *ntext = new wchar_t[nsize+1];
- memcpy(ntext, wtext, wsize*sizeof(wtext[0]));
- delete [] wtext; wtext = ntext; wsize = nsize;
- }
- wlen = BC_Resources::encode(src_enc, dst_enc, text, strlen(text),
+ int tlen = tstrlen();
+ int nsize = tsize > 0 ? tsize : tlen + BCTEXTLEN;
+ wdemand(nsize);
+ wlen = BC_Resources::encode(src_enc, dst_enc, text, tlen,
(char*)wtext, wsize*sizeof(wchar_t)) / sizeof(wchar_t);
dirty = 0;
}
int BC_TextBox::update(const wchar_t *wtext)
{
int wtext_len = wcslen(wtext);
- if( wtext_len >= wsize ) wtext_len = wsize;
- wcsncpy(this->wtext, wtext, wtext_len);
- wlen = wtext_len;
+ wdemand(wtext_len);
+ wcsncpy(this->wtext, wtext, wsize);
+ this->wlen = wtext_len;
if(highlight_letter1 > wtext_len) highlight_letter1 = wtext_len;
if(highlight_letter2 > wtext_len) highlight_letter2 = wtext_len;
if(ibeam_letter > wtext_len) ibeam_letter = wtext_len;
void BC_TextBox::set_text(char *text, int isz)
{
- if( size > 0 || isz < 0 ) return;
- this->text = text;
- tsize = isz;
- size = -isz;
- dirty = 1;
- wtext_update();
- draw(1);
+ if( size < 0 && isz > 0 ) {
+ this->text = text;
+ tsize = isz;
+ size = -isz;
+ dirty = 1;
+ wtext_update();
+ draw(1);
+ }
}
int BC_TextBox::get_text_rows()
void BC_TextBox::draw(int flush)
{
- int i, j, k;
+ int i, k;
int row_begin, row_end;
int highlight_x1, highlight_x2;
int need_ibeam = 1;
// Draw text with selection
set_font(font);
- for(i=0, j=0, k=text_y; i < wtext_len && k < get_h(); k += text_height) {
+ for(i=0, k=text_y; i < wtext_len && k < get_h(); k += text_height) {
// Draw row of text
row_begin = i;
wchar_t *wtext_row = &wtext[i];
- for(j=0; j<BCTEXTLEN-1 && i<wtext_len && wtext[i]!='\n'; ++i, ++j);
+ for( ; i<wtext_len && wtext[i]!='\n'; ++i );
if( (row_end=i) < wtext_len ) ++i;
if(k > top_margin-text_height && k < get_h()-bottom_margin) {
void BC_TextBox::default_keypress(int &dispatch_event, int &result)
{
int key = top_level->get_keypress(), len;
- if( (key == RETURN) || ( key >= 32 && key <= 255 ) ||
- (key >= KP1 && key <= KP9) || key == KPINS ) {
- wchar_t *wkeys = top_level->get_wkeystring(&len);
- switch( key ) {
- case RETURN: key = '\n'; goto kpchr;
- case KPINS: key = '0'; goto kpchr;
- case KP1: case KP2: case KP3: case KP4: case KP5:
- case KP6: case KP7: case KP8: case KP9:
- key = key - KP1 + '1';
- kpchr:
- wkeys[0] = key; wkeys[1] = 0; len = 1;
- break;
- }
- insert_text(wkeys, len);
- find_ibeam(1);
- draw(1);
- dispatch_event = 1;
- result = 1;
- }
+ wchar_t *wkeys = top_level->get_wkeystring(&len);
+ switch( key ) {
+ case KPENTER: key = '\n'; goto kpchr;
+ case KPMINUS: key = '-'; goto kpchr;
+ case KPPLUS: key = '+'; goto kpchr;
+ case KPDEL: key = '.'; goto kpchr;
+ case RETURN: key = '\n'; goto kpchr;
+ case KPINS: key = '0'; goto kpchr;
+ case KP1: case KP2: case KP3: case KP4: case KP5:
+ case KP6: case KP7: case KP8: case KP9:
+ key = key - KP1 + '1';
+ kpchr: {
+ wkeys[0] = key; wkeys[1] = 0; len = 1;
+ break; }
+ default:
+ if( key < 32 || key > 255 ) return;
+ }
+ insert_text(wkeys, len);
+ find_ibeam(1);
+ draw(1);
+ dispatch_event = 1;
+ result = 1;
}
int BC_TextBox::keypress_event()
do_separators(1);
}
+int BC_TextBox::wdemand(int len)
+{
+ if( wtext && wsize >= len ) return 0;
+ int nsize = len + wlen/2 + BCTEXTLEN;
+ wchar_t *ntext = new wchar_t[nsize+1];
+ ntext[nsize] = 0;
+ memcpy(ntext, wtext, wsize*sizeof(wtext[0]));
+ delete [] wtext; wtext = ntext; wsize = nsize;
+ return 1;
+}
+
+int BC_TextBox::tdemand(int len)
+{
+ if( text && tsize >= len ) return 0;
+ int tlen = !text ? 0 : strlen(text);
+ int nsize = len + tlen/2 + BCTEXTLEN;
+ char *ntext = new char[nsize+1];
+ ntext[nsize] = 0;
+ memcpy(ntext, text, tsize*sizeof(text[0]));
+ delete [] text; text = ntext; tsize = nsize;
+ return 1;
+}
+
void BC_TextBox::insert_text(const wchar_t *wcp, int len)
{
if( len < 0 ) len = wcslen(wcp);
int wtext_len = wtext_update();
+ wdemand(wtext_len + len + 1);
if( unicode_active < 0 && highlight_letter1 < highlight_letter2 ) {
delete_selection(highlight_letter1, highlight_letter2, wtext_len);
highlight_letter2 = ibeam_letter = highlight_letter1;
}
int i, j;
- for(i=wtext_len-1, j=wtext_len+len-1; i>=ibeam_letter; i--, j--) {
- if( j >= wsize ) continue;
- wtext[j] = wtext[i];
- }
+ for( i=wtext_len, j=wtext_len+len; --i>=ibeam_letter; )
+ if( --j < wsize ) wtext[j] = wtext[i];
+ for( i=ibeam_letter,j=0; j<len; ++i, ++j )
+ if( i < wsize ) wtext[i] = wcp[j];
- for(i = ibeam_letter, j = 0; j < len; j++, i++) {
- if( i >= wsize ) break;
- wtext[i] = wcp[j];
- }
if( (wlen+=len) > wsize ) wlen = wsize;
if( (ibeam_letter+=len) > wsize ) ibeam_letter = wsize;
wtext[wlen] = 0; // wtext allocated wsize+1