X-Git-Url: https://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fguicast%2Fbctextbox.C;h=e2af4cbe2a05e5166c3128bc03b994767553a47d;hb=b2eb290b3f6e5c233393017aa152e67c76243130;hp=2a34c18096952024b3c7c5fa9eb1a40a8432843c;hpb=c7fa9dc718ca872dd8068d7ddd9f58a81b696a87;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/guicast/bctextbox.C b/cinelerra-5.1/guicast/bctextbox.C index 2a34c180..e2af4cbe 100644 --- a/cinelerra-5.1/guicast/bctextbox.C +++ b/cinelerra-5.1/guicast/bctextbox.C @@ -51,9 +51,9 @@ BC_TextBox::BC_TextBox(int x, int y, int w, int rows, 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; } @@ -63,12 +63,9 @@ BC_TextBox::BC_TextBox(int x, int y, int w, int rows, { 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, @@ -136,7 +133,7 @@ BC_TextBox::~BC_TextBox() delete suggestions; delete menu; delete [] wtext; - if( size > 0 ) + if( size >= 0 ) delete [] text; } @@ -149,9 +146,11 @@ int BC_TextBox::reset_parameters(int rows, int has_border, int font, int size) 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; @@ -166,6 +165,8 @@ int BC_TextBox::reset_parameters(int rows, int has_border, int font, int size) text_x = 0; enabled = 1; highlighted = 0; + back_color = -1; + high_color = -1; precision = 4; if (!skip_cursor) skip_cursor = new Timer; @@ -185,14 +186,12 @@ int BC_TextBox::reset_parameters(int rows, int has_border, int font, int size) 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); } @@ -200,12 +199,10 @@ char *BC_TextBox::tstrcpy(const char *cp) { 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; } @@ -213,9 +210,8 @@ char *BC_TextBox::tstrcpy(const char *cp) 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; } @@ -224,13 +220,10 @@ int BC_TextBox::wtext_update() 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; } @@ -281,13 +274,13 @@ int BC_TextBox::initialize() BC_Resources *resources = get_resources(); if(has_border) { - back_color = resources->text_background; - high_color = resources->text_background_hi; + if( back_color < 0 ) back_color = resources->text_background; + if( high_color < 0 ) high_color = resources->text_background_hi; } else { - high_color = resources->text_background_noborder_hi; - back_color = bg_color; + if( back_color < 0 ) back_color = bg_color; + if( high_color < 0 ) high_color = resources->text_background_noborder_hi; } draw(0); @@ -456,7 +449,8 @@ int BC_TextBox::update(const char *text) { //printf("BC_TextBox::update 1 %d %s %s\n", tstrcmp(text), text, this->text); // Don't update if contents are the same - if(!tstrcmp(text)) return 0; + int bg_color = has_border || !highlighted ? back_color : high_color; + if( bg_color == background_color && !tstrcmp(text)) return 0; tstrcpy(text); int wtext_len = wtext_update(); if(highlight_letter1 > wtext_len) highlight_letter1 = wtext_len; @@ -469,9 +463,9 @@ int BC_TextBox::update(const char *text) 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; @@ -519,6 +513,8 @@ int BC_TextBox::get_text_x() { return text_x; } int BC_TextBox::get_text_y() { return text_y; } void BC_TextBox::set_text_x(int v) { text_x = v; } void BC_TextBox::set_text_y(int v) { text_y = v; } +int BC_TextBox::get_back_color() { return back_color; } +void BC_TextBox::set_back_color(int v) { back_color = v; } int BC_TextBox::pixels_to_rows(BC_WindowBase *window, int font, int pixels) { @@ -553,13 +549,14 @@ const wchar_t* BC_TextBox::get_wtext() 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() @@ -647,7 +644,7 @@ void BC_TextBox::draw_cursor() 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; @@ -655,12 +652,7 @@ void BC_TextBox::draw(int flush) //printf("BC_TextBox::draw %d %s\n", __LINE__, text); // Background - if(has_border) - background_color = resources->text_background; - else if(highlighted) - background_color = high_color; - else - background_color = back_color; + background_color = has_border || !highlighted ? back_color : high_color; set_color(background_color); draw_box(0, 0, w, h); @@ -669,11 +661,11 @@ void BC_TextBox::draw(int flush) // 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 top_margin-text_height && k < get_h()-bottom_margin) { @@ -1128,15 +1120,28 @@ int BC_TextBox::repeat_event(int64_t duration) void BC_TextBox::default_keypress(int &dispatch_event, int &result) { int key = top_level->get_keypress(), len; - if( (key == RETURN) || ( key >= 32 && key <= 255 ) ) { - wchar_t *wkeys = top_level->get_wkeystring(&len); - if( key == RETURN ) { wkeys[0] = '\n'; wkeys[1] = 0; len = 1; } - 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'; goto kpchr; + default: + if( key < 32 || key > 255 ) return; + kpchr: { + wkeys[0] = key; wkeys[1] = 0; len = 1; + break; } + } + insert_text(wkeys, len); + find_ibeam(1); + draw(1); + dispatch_event = 1; + result = 1; } int BC_TextBox::keypress_event() @@ -1185,6 +1190,10 @@ int BC_TextBox::keypress_event() result = 1; wlen = 0; break; } + case KPINS: last_keypress = KP1-'1'+'0'; // fall thru + case KP1: case KP2: case KP3: case KP4: case KP5: + case KP6: case KP7: case KP8: case KP9: + last_keypress = last_keypress-KP1 + '1'; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': @@ -1618,7 +1627,7 @@ int BC_TextBox::keypress_event() default: { if( ctrl_down() ) { - switch( get_keypress() ) { + switch( last_keypress ) { case 'c': case 'C': { result = copy(0); break; } @@ -1724,10 +1733,34 @@ void BC_TextBox::delete_selection(int letter1, int letter2, int wtext_len) 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; @@ -1735,15 +1768,11 @@ void BC_TextBox::insert_text(const wchar_t *wcp, int len) } 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= 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