X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fguicast%2Fbctextbox.C;h=da7afa0f42e8b701228ad73d0cf3beeedf652d50;hp=f8777993c500f35a95096f8156b62392b06ff638;hb=214bd0ba9e21635e03d0c0e2b2ae1a7e9170583c;hpb=b77dbd97d927405c86a2a8ca0dd927bca3c70175 diff --git a/cinelerra-5.1/guicast/bctextbox.C b/cinelerra-5.1/guicast/bctextbox.C index f8777993..da7afa0f 100644 --- a/cinelerra-5.1/guicast/bctextbox.C +++ b/cinelerra-5.1/guicast/bctextbox.C @@ -24,11 +24,12 @@ #include "bcsignals.h" #include "bctextbox.h" #include "clip.h" -#include "colors.h" +#include "bccolors.h" #include #include "cursors.h" #include "filesystem.h" #include "keys.h" +#include "language.h" #include #include "bctimer.h" #include "vframe.h" @@ -133,7 +134,7 @@ BC_TextBox::~BC_TextBox() delete suggestions_popup; suggestions->remove_all_objects(); delete suggestions; - delete [] positions; + delete menu; delete [] wtext; if( size > 0 ) delete [] text; @@ -165,19 +166,22 @@ 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; wtext = 0; wsize = 0; wlen = 0; - positions = 0; - plen = 0; keypress_draw = 1; last_keypress = 0; separators = 0; + xscroll = 0; yscroll = 0; + menu = 0; dirty = 1; + selection_active = 0; return 0; } @@ -189,8 +193,9 @@ int BC_TextBox::tstrlen() int BC_TextBox::tstrcmp(const char *cp) { - if( !tsize ) return strcmp(text, cp); - return strncmp(text, cp, tsize); + const char *tp = get_text(); + if( !tsize ) return strcmp(tp, cp); + return strncmp(tp, cp, tsize); } char *BC_TextBox::tstrcpy(const char *cp) @@ -226,12 +231,6 @@ int BC_TextBox::wtext_update() wchar_t *ntext = new wchar_t[nsize+1]; memcpy(ntext, wtext, wsize*sizeof(wtext[0])); delete [] wtext; wtext = ntext; wsize = nsize; - int *npositions = new int[nsize+1]; - if( plen > 0 ) - memcpy(npositions, positions, (plen+1)*sizeof(positions[0])); - else - npositions[0] = 0; - delete [] positions; positions = npositions; plen = nsize; } wlen = BC_Resources::encode(src_enc, dst_enc, text, strlen(text), (char*)wtext, wsize*sizeof(wchar_t)) / sizeof(wchar_t); @@ -254,6 +253,7 @@ int BC_TextBox::text_update(const wchar_t *wcp, int wsz, char *tcp, int tsz) int BC_TextBox::initialize() { + if (!skip_cursor) skip_cursor = new Timer; skip_cursor->update(); @@ -283,18 +283,22 @@ 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); set_cursor(IBEAM_CURSOR, 0, 0); show_window(0); + + add_subwindow(menu = new BC_TextMenu(this)); + menu->create_objects(); + return 0; } @@ -314,147 +318,95 @@ void BC_TextBox::set_precision(int precision) } // Compute suggestions for a path -int BC_TextBox::calculate_suggestions(ArrayList *entries) +int BC_TextBox::calculate_suggestions(ArrayList *entries, const char *filter) { // Let user delete suggestion - if(get_last_keypress() != BACKSPACE) - { - + if(get_last_keypress() != BACKSPACE) { // Compute suggestions FileSystem fs; ArrayList suggestions; const char *current_text = get_text(); - + int suggestion_column = 0; + char dirname[BCTEXTLEN]; dirname[0] = 0; + if( current_text[0] == '/' || current_text[0] == '~' ) + strncpy(dirname, current_text, sizeof(dirname)); + else if( !entries ) + getcwd(dirname, sizeof(dirname)); // If directory, tabulate it - if(current_text[0] == '/' || - current_text[0] == '~') - { -//printf("BC_TextBox::calculate_suggestions %d\n", __LINE__); - char string[BCTEXTLEN]; - strncpy(string, current_text, sizeof(string)); - char *ptr = strrchr(string, '/'); - if(!ptr) ptr = strrchr(string, '~'); - -//printf("BC_TextBox::calculate_suggestions %d\n", __LINE__); - *(ptr + 1) = 0; - int suggestion_column = ptr + 1 - string; - - fs.set_filter(get_resources()->filebox_filter); -// fs.set_sort_order(filebox->sort_order); -// fs.set_sort_field(filebox->column_type[filebox->sort_column]); - - -//printf("BC_TextBox::calculate_suggestions %d %c %s\n", __LINE__, *ptr, string); - if(current_text[0] == '~' && *ptr != '/') - { - fs.update("/home"); - } - else - { - fs.parse_tildas(string); - fs.update(string); + if( dirname[0] ) { + if( filter ) fs.set_filter(filter); + char *prefix, *cp; + strncpy(dirname, current_text, sizeof(dirname)); + if( (cp=strrchr(dirname, '/')) || + (cp=strrchr(dirname, '~')) ) *++cp = 0; + fs.parse_tildas(dirname); + fs.update(dirname); + cp = (char *)current_text; + if( (prefix=strrchr(cp, '/')) || + (prefix=strrchr(cp, '~')) ) ++prefix; + suggestion_column = !prefix ? 0 : prefix - cp; + int prefix_len = prefix ? strlen(prefix) : 0; +// only include items where the filename matches the basename prefix + for(int i = 0; i < fs.total_files(); i++) { + char *current_name = fs.get_entry(i)->name; + if( prefix_len>0 && strncmp(prefix, current_name, prefix_len) ) continue; + suggestions.append(current_name); } -//printf("BC_TextBox::calculate_suggestions %d %d\n", __LINE__, fs.total_files()); - - -// Accept only entries with matching trailing characters - ptr = strrchr((char*)current_text, '/'); - if(!ptr) ptr = strrchr((char*)current_text, '~'); - if(ptr) ptr++; -//printf("BC_TextBox::calculate_suggestions %d %s %p\n", __LINE__, current_text, ptr); - - - if(ptr && *ptr) - { - for(int i = 0; i < fs.total_files(); i++) - { - char *current_name = fs.get_entry(i)->name; - if(!strncmp(ptr, current_name, strlen(ptr))) - { - suggestions.append(current_name); - //printf("BC_TextBox::calculate_suggestions %d %s\n", __LINE__, current_name); - } - } - } - else - // Accept all entries - for(int i = 0; i < fs.total_files(); i++) - { - //printf("BC_TextBox::calculate_suggestions %d %s\n", __LINE__, fs.get_entry(i)->name); - suggestions.append(fs.get_entry(i)->name); - } -//printf("BC_TextBox::calculate_suggestions %d\n", __LINE__); - -// Add 1 to column to keep / - set_suggestions(&suggestions, suggestion_column); -//printf("BC_TextBox::calculate_suggestions %d\n", __LINE__); } - else -// Get entries from current listbox with matching trailing characters - if(entries) - { -// printf("BC_TextBox::calculate_suggestions %d %d\n", -// __LINE__, -// entries->size()); - for(int i = 0; i < entries->size(); i++) - { + else if(entries) { + char *prefix = (char *)current_text; + int prefix_len = strlen(prefix); + for(int i = 0; i < entries->size(); i++) { char *current_name = entries->get(i)->get_text(); - -//printf("BC_TextBox::calculate_suggestions %d %s %s\n", __LINE__, current_text, current_name); - if(!strncmp(current_text, current_name, strlen(current_text))) - { - suggestions.append(current_name); - } + if( prefix_len>0 && strncmp(prefix, current_name, prefix_len) ) continue; + suggestions.append(current_name); } - - set_suggestions(&suggestions, 0); } + set_suggestions(&suggestions, suggestion_column); } return 1; } +void BC_TextBox::no_suggestions() +{ + if( suggestions_popup ) { + delete suggestions_popup; + suggestions_popup = 0; + activate(); + } +} + void BC_TextBox::set_suggestions(ArrayList *suggestions, int column) { // Copy the array this->suggestions->remove_all_objects(); this->suggestion_column = column; - if(suggestions) - { - for(int i = 0; i < suggestions->size(); i++) - { + if(suggestions) { + for(int i = 0; i < suggestions->size(); i++) { this->suggestions->append(new BC_ListBoxItem(suggestions->get(i))); } // Show the popup without taking focus - if(suggestions->size() > 1) - { - if(!suggestions_popup) - { - - get_parent()->add_subwindow(suggestions_popup = - new BC_TextBoxSuggestions(this, x, y)); + if( suggestions->size() > 1 ) { + if( !suggestions_popup ) { + suggestions_popup = new BC_TextBoxSuggestions(this, x, y); + get_parent()->add_subwindow(suggestions_popup); suggestions_popup->set_is_suggestions(1); - suggestions_popup->activate(0); } - else - { - suggestions_popup->update(this->suggestions, - 0, - 0, - 1); - suggestions_popup->activate(0); + else { + suggestions_popup->update(this->suggestions, 0, 0, 1); } + suggestions_popup->activate(0); } else // Show the highlighted text - if(suggestions->size() == 1) - { + if( suggestions->size() == 1 ) { highlight_letter1 = wtext_update(); - text_update(wtext,wlen, text,tsize); + int len = text_update(wtext,wlen, text,tsize); char *current_suggestion = suggestions->get(0); - int col = highlight_letter1 - suggestion_column; + int col = len - suggestion_column; if( col < 0 ) col = 0; char *cur = current_suggestion + col; tstrcat(cur); @@ -462,18 +414,13 @@ void BC_TextBox::set_suggestions(ArrayList *suggestions, int column) //printf("BC_TextBox::set_suggestions %d %d\n", __LINE__, suggestion_column); draw(1); - - delete suggestions_popup; - suggestions_popup = 0; + no_suggestions(); } } // Clear the popup - if(!suggestions || !this->suggestions->size()) - { - delete suggestions_popup; - suggestions_popup = 0; - } + if( !suggestions || !this->suggestions->size() ) + no_suggestions(); } void BC_TextBox::wset_selection(int char1, int char2, int ibeam) @@ -511,7 +458,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; @@ -554,10 +502,8 @@ void BC_TextBox::disable() { if(enabled) { enabled = 0; - if(top_level) { - if(active) top_level->deactivate(); - draw(1); - } + deactivate(); + draw(1); } } @@ -571,10 +517,13 @@ void BC_TextBox::enable() } } -int BC_TextBox::get_enabled() -{ - return enabled; -} +int BC_TextBox::get_enabled() { return enabled; } +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) { @@ -711,12 +660,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); @@ -739,19 +683,21 @@ void BC_TextBox::draw(int flush) highlight_letter1 <= row_end ) { int color = active && enabled && get_has_focus() ? resources->text_highlight : + selection_active ? + resources->text_selected_highlight : resources->text_inactive_highlight; if( unicode_active >= 0 ) color ^= LTBLUE; set_color(color); if(highlight_letter1 >= row_begin && highlight_letter1 <= row_end) - highlight_x1 = positions[highlight_letter1]; + highlight_x1 = get_x_position(highlight_letter1, row_begin); else highlight_x1 = 0; if(highlight_letter2 > row_begin && highlight_letter2 <= row_end) - highlight_x2 = positions[highlight_letter2]; + highlight_x2 = get_x_position(highlight_letter2, row_begin); else highlight_x2 = get_w(); @@ -763,29 +709,22 @@ void BC_TextBox::draw(int flush) int len = row_end - row_begin; if( len > 0 ) { set_color(enabled ? resources->text_default : DMGREY); - draw_wtext(text_x, k + text_ascent, wtext_row, len, - 0, &positions[wtext_row - wtext]); + draw_single_text(1, font, text_x, k + text_ascent, wtext_row, len); } // Get ibeam location if(ibeam_letter >= row_begin && ibeam_letter <= row_end) { need_ibeam = 0; ibeam_y = k - text_y; - ibeam_x = positions[ibeam_letter]; + ibeam_x = get_x_position(ibeam_letter, row_begin); } } } //printf("BC_TextBox::draw 3 %d\n", ibeam_y); if(need_ibeam) { - if( wtext_len == 0 ) { - ibeam_x = 0; - ibeam_y = 0; - } - else { - ibeam_x = -1; - ibeam_y = -1; - } +// ibeam_x = ibeam_y = !wtext_len ? 0 : -1; + ibeam_x = 0; ibeam_y = k - text_y; } //printf("BC_TextBox::draw 4 %d\n", ibeam_y); @@ -812,10 +751,13 @@ int BC_TextBox::focus_out_event() int BC_TextBox::cursor_enter_event() { - if(top_level->event_win == win && enabled) + if( top_level->event_win == win && enabled && + !(top_level->get_resources()->textbox_focus_policy & CLICK_ACTIVATE) ) { - tooltip_done = 0; - + if( !active ) { + top_level->deactivate(); + activate(); + } if(!highlighted) { highlighted = 1; @@ -831,10 +773,13 @@ int BC_TextBox::cursor_leave_event() if(highlighted) { highlighted = 0; - draw_border(); hide_tooltip(); + draw_border(); flash(1); } + if( !suggestions_popup && !get_button_down() && + !(top_level->get_resources()->textbox_focus_policy & CLICK_DEACTIVATE) ) + deactivate(); return 0; } @@ -843,12 +788,10 @@ int BC_TextBox::button_press_event() const int debug = 0; if(!enabled) return 0; - if(get_buttonpress() != WHEEL_UP && - get_buttonpress() != WHEEL_DOWN && - get_buttonpress() != LEFT_BUTTON && - get_buttonpress() != MIDDLE_BUTTON) return 0; - - +// if(get_buttonpress() != WHEEL_UP && +// get_buttonpress() != WHEEL_DOWN && +// get_buttonpress() != LEFT_BUTTON && +// get_buttonpress() != MIDDLE_BUTTON) return 0; if(debug) printf("BC_TextBox::button_press_event %d\n", __LINE__); @@ -886,6 +829,11 @@ int BC_TextBox::button_press_event() update_scroll = 1; } else + if(get_buttonpress() == RIGHT_BUTTON) + { + menu->activate_menu(); + } + else { cursor_letter = get_cursor_letter(top_level->cursor_x, top_level->cursor_y); @@ -952,28 +900,15 @@ int BC_TextBox::button_press_event() return 1; } else - if(active && (!yscroll || !yscroll->is_event_win())) - { -//printf("BC_TextBox::button_press_event %d\n", __LINE__); -// Suggestion popup is not active but must be deactivated. - if(suggestions_popup) - { - return 0; -// printf("BC_TextBox::button_press_event %d\n", __LINE__); -// // Pass event to suggestions popup -// if(!suggestions_popup->button_press_event()) -// { -// printf("BC_TextBox::button_press_event %d\n", __LINE__); -// top_level->deactivate(); -// } - } - else - { - top_level->deactivate(); + if( active ) { + if( suggestions_popup && (!yscroll || !yscroll->is_event_win())) { + if( suggestions_popup->button_press_event() ) + return suggestions_popup->handle_event(); } + else if( (top_level->get_resources()->textbox_focus_policy & CLICK_DEACTIVATE) ) + deactivate(); } - return 0; } @@ -1051,27 +986,23 @@ int BC_TextBox::cursor_motion_event() int BC_TextBox::activate() { - top_level->active_subwindow = this; - active = 1; + if( !active ) { + active = 1; + top_level->set_active_subwindow(this); + top_level->set_repeat(top_level->get_resources()->blink_rate); + } draw(1); - top_level->set_repeat(top_level->get_resources()->blink_rate); return 0; } int BC_TextBox::deactivate() { -//printf("BC_TextBox::deactivate %d suggestions_popup=%p\n", __LINE__, suggestions_popup); - active = 0; - top_level->unset_repeat(top_level->get_resources()->blink_rate); - if(suggestions_popup) - { -// Must deactivate instead of delete since this is called from BC_ListBox::button_press_event -// suggestions_popup->deactivate(); - - delete suggestions_popup; - suggestions_popup = 0; + if( active ) { + active = 0; + text_selected = word_selected = line_selected = 0; + top_level->set_active_subwindow(0); + top_level->unset_repeat(top_level->get_resources()->blink_rate); } - draw(1); return 0; } @@ -1086,7 +1017,6 @@ int BC_TextBox::repeat_event(int64_t duration) tooltip_text && tooltip_text[0] != 0 && highlighted) { show_tooltip(); - tooltip_done = 1; result = 1; } @@ -1197,15 +1127,11 @@ int BC_TextBox::repeat_event(int64_t duration) void BC_TextBox::default_keypress(int &dispatch_event, int &result) { - if( (top_level->get_keypress() == RETURN) || - (top_level->get_keypress() > 30 && top_level->get_keypress() <= 255)) { - int len; - wchar_t *temp_string = top_level->get_wkeystring(&len); - if(top_level->get_keypress() == RETURN) { - temp_string[0] = '\n'; temp_string[1] = 0; - len = 1; - } - insert_text(temp_string, len); + 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; @@ -1231,21 +1157,23 @@ int BC_TextBox::keypress_event() int wlen = -1; switch( last_keypress ) { //unicode active acitons - case ESC: { - unicode_active = -1; - result = 1; - wlen = 0; - break; } case RETURN: { for( int i=highlight_letter1+1; i 0) { @@ -1291,9 +1219,8 @@ int BC_TextBox::keypress_event() switch(last_keypress) { case ESC: { // Deactivate the suggestions - if(suggestions && suggestions_popup) { - delete suggestions_popup; - suggestions_popup = 0; + if( suggestions_popup ) { + no_suggestions(); result = 1; } else { @@ -1304,6 +1231,8 @@ int BC_TextBox::keypress_event() case RETURN: { if( rows == 1 ) { + highlight_letter1 = highlight_letter2 = 0; + ibeam_letter = wtext_update(); top_level->deactivate(); dispatch_event = 1; result = 0; @@ -1407,7 +1336,7 @@ int BC_TextBox::keypress_event() break; } case UP: { - if(suggestions && suggestions_popup) { + if( suggestions && suggestions_popup ) { // Pass to suggestions popup //printf("BC_TextBox::keypress_event %d\n", __LINE__); suggestions_popup->activate(1); @@ -1494,7 +1423,7 @@ int BC_TextBox::keypress_event() // __LINE__, // suggestions, // suggestions_popup); - if(suggestions && suggestions_popup) { + if( suggestions && suggestions_popup ) { // Pass to suggestions popup suggestions_popup->activate(1); suggestions_popup->keypress_event(); @@ -1580,8 +1509,7 @@ int BC_TextBox::keypress_event() break; } case END: { - delete suggestions_popup; - suggestions_popup = 0; + no_suggestions(); int old_ibeam_letter = ibeam_letter; @@ -1613,8 +1541,7 @@ int BC_TextBox::keypress_event() break; } case HOME: { - delete suggestions_popup; - suggestions_popup = 0; + no_suggestions(); int old_ibeam_letter = ibeam_letter; @@ -1652,10 +1579,7 @@ int BC_TextBox::keypress_event() break; } case BACKSPACE: { - if(suggestions_popup) { - delete suggestions_popup; - suggestions_popup = 0; - } + no_suggestions(); if(highlight_letter1 == highlight_letter2) { if(ibeam_letter > 0) { @@ -1696,29 +1620,15 @@ int BC_TextBox::keypress_event() if( ctrl_down() ) { switch( get_keypress() ) { case 'c': case 'C': { - if(highlight_letter1 != highlight_letter2) { - copy_selection(SECONDARY_SELECTION); - result = 1; - } + result = copy(0); break; } case 'v': case 'V': { - paste_selection(SECONDARY_SELECTION); - find_ibeam(1); - if(keypress_draw) draw(1); + result = paste(0); dispatch_event = 1; - result = 1; break; } case 'x': case 'X': { - if(highlight_letter1 != highlight_letter2) { - copy_selection(SECONDARY_SELECTION); - delete_selection(highlight_letter1, highlight_letter2, wtext_len); - highlight_letter2 = ibeam_letter = highlight_letter1; - } - - find_ibeam(1); - if(keypress_draw) draw(1); + result = cut(0); dispatch_event = 1; - result = 1; break; } case 'u': case 'U': { if( shift_down() ) { @@ -1749,6 +1659,53 @@ int BC_TextBox::keypress_event() } +int BC_TextBox::cut(int do_update) +{ + if( highlight_letter1 != highlight_letter2 ) { + int wtext_len = wtext_update(); + copy_selection(SECONDARY_SELECTION); + delete_selection(highlight_letter1, highlight_letter2, wtext_len); + highlight_letter2 = ibeam_letter = highlight_letter1; + } + + find_ibeam(1); + if( keypress_draw ) + draw(1); + + if( do_update ) { + skip_cursor->update(); + handle_event(); + } + return 1; +} + +int BC_TextBox::copy(int do_update) +{ + int result = 0; + if( highlight_letter1 != highlight_letter2 ) { + copy_selection(SECONDARY_SELECTION); + result = 1; + if( do_update ) { + skip_cursor->update(); + } + } + return result; +} + +int BC_TextBox::paste(int do_update) +{ + paste_selection(SECONDARY_SELECTION); + find_ibeam(1); + if( keypress_draw ) + draw(1); + if( do_update ) { + skip_cursor->update(); + handle_event(); + } + return 1; +} + + int BC_TextBox::uses_text() { return 1; @@ -1847,20 +1804,24 @@ void BC_TextBox::do_separators(int ibeam_left) } } +int BC_TextBox::get_x_position(int i, int start) +{ + return get_text_width(font, &wtext[start], i - start); +} + void BC_TextBox::get_ibeam_position(int &x, int &y) { int i, row_begin, row_end; int wtext_len = wtext_update(); + x = y = 0; - y = 0; - x = 0; for( i=0; i= row_begin && ibeam_letter <= row_end ) { - x = get_text_width(font, &wtext[row_begin], ibeam_letter - row_begin); + x = get_x_position(ibeam_letter, row_begin); //printf("BC_TextBox::get_ibeam_position %d %d %d %d %d\n", ibeam_letter, row_begin, row_end, x, y); return; } @@ -2094,21 +2055,30 @@ void BC_TextBox::copy_selection(int clipboard_num) //printf(" BC_TextBox::copy_selection %d %d %d\n",highlight_letter1, highlight_letter2, clip_len); char ctext[4*clip_len+4]; clip_len = text_update(&wtext[highlight_letter1],clip_len, ctext,4*clip_len+4); - get_clipboard()->to_clipboard(ctext, clip_len, clipboard_num); + to_clipboard(ctext, clip_len, clipboard_num); + selection_active = 1; } +int BC_TextBox::selection_clear_event() +{ + if( !is_event_win() ) return 0; + selection_active = 0; + draw(1); + return 1; +} void BC_TextBox::paste_selection(int clipboard_num) { - int len = get_clipboard()->clipboard_len(clipboard_num); + int len = clipboard_len(clipboard_num); if( len > 0 ) { char cstring[len]; wchar_t wstring[len]; - get_clipboard()->from_clipboard(cstring, len, clipboard_num); --len; + from_clipboard(cstring, len, clipboard_num); --len; //printf("BC_TextBox::paste_selection %d '%*.*s'\n",len,len,len,cstring); len = BC_Resources::encode(BC_Resources::encoding, BC_Resources::wide_encoding, cstring,len, (char *)wstring,(len+1)*sizeof(wchar_t)) / sizeof(wchar_t); insert_text(wstring, len); + last_keypress = 0; } } @@ -2152,20 +2122,9 @@ int BC_TextBox::get_rows() -BC_TextBoxSuggestions::BC_TextBoxSuggestions(BC_TextBox *text_box, - int x, - int y) - : BC_ListBox(x, - y, - text_box->get_w(), - 200, - LISTBOX_TEXT, - text_box->suggestions, - 0, - 0, - 1, - 0, - 1) +BC_TextBoxSuggestions::BC_TextBoxSuggestions(BC_TextBox *text_box, int x, int y) + : BC_ListBox(x, y, text_box->get_w(), 200, LISTBOX_TEXT, + text_box->suggestions, 0, 0, 1, 0, 1) { this->text_box = text_box; set_use_button(0); @@ -2176,35 +2135,6 @@ BC_TextBoxSuggestions::~BC_TextBoxSuggestions() { } -int BC_TextBoxSuggestions::selection_changed() -{ -#if 0 -//printf("BC_TextBoxSuggestions::selection_changed %d\n", __LINE__); - BC_ListBoxItem *item = get_selection(0, 0); -//printf("BC_TextBoxSuggestions::selection_changed %d\n", __LINE__); - - if(item) - { - char *current_suggestion = item->get_text(); -//printf("BC_TextBoxSuggestions::selection_changed %d\n", __LINE__); -// int text_box_len = strlen(text_box->text); -//printf("BC_TextBoxSuggestions::selection_changed %d\n", __LINE__); - strcpy(text_box->text + text_box->suggestion_column, current_suggestion); -//printf("BC_TextBoxSuggestions::selection_changed %d\n", __LINE__); - *(text_box->text + text_box->suggestion_column + strlen(current_suggestion)) = 0; - -//printf("BC_TextBoxSuggestions::selection_changed %d\n", __LINE__); - text_box->draw(1); - text_box->handle_event(); - } - - return 1; -#else - return 0; -#endif -} - - int BC_TextBoxSuggestions::handle_event() { char *current_suggestion = 0; @@ -2245,6 +2175,7 @@ BC_ScrollTextBox::BC_ScrollTextBox(BC_WindowBase *parent_window, this->y = y; this->w = w; this->rows = rows; + xscroll = 0; yscroll = 0; this->default_text = default_text; this->default_wtext = 0; this->default_size = default_size; @@ -2259,6 +2190,7 @@ BC_ScrollTextBox::BC_ScrollTextBox(BC_WindowBase *parent_window, this->y = y; this->w = w; this->rows = rows; + xscroll = 0; yscroll = 0; this->default_text = 0; this->default_wtext = default_wtext; this->default_size = default_size; @@ -2266,6 +2198,7 @@ BC_ScrollTextBox::BC_ScrollTextBox(BC_WindowBase *parent_window, BC_ScrollTextBox::~BC_ScrollTextBox() { + delete xscroll; delete yscroll; if(text) { text->gui = 0; @@ -2279,85 +2212,32 @@ void BC_ScrollTextBox::create_objects() parent_window->add_subwindow(text = default_wtext ? new BC_ScrollTextBoxText(this, default_wtext) : new BC_ScrollTextBoxText(this, default_text)); - parent_window->add_subwindow(yscroll = new BC_ScrollTextBoxYScroll(this)); - text->yscroll = yscroll; - yscroll->bound_to = text; - -} - -int BC_ScrollTextBox::handle_event() -{ - return 1; -} - -int BC_ScrollTextBox::get_x() -{ - return x; -} - -int BC_ScrollTextBox::get_y() -{ - return y; -} - -int BC_ScrollTextBox::get_w() -{ - return w; -} - -int BC_ScrollTextBox::get_h() -{ - return this->text->get_h(); -} - -int BC_ScrollTextBox::get_rows() -{ - return rows; -} - - -const char* BC_ScrollTextBox::get_text() -{ - return text->get_text(); -} - -const wchar_t* BC_ScrollTextBox::get_wtext() -{ - return text->get_wtext(); + set_text_row(0); } void BC_ScrollTextBox::set_text(char *text, int isz) { this->text->set_text(text, isz); - yscroll->update_length(this->text->get_text_rows(), - this->text->get_text_row(), - yscroll->get_handlelength(), - 1); + update_scrollbars(); } int BC_ScrollTextBox::set_text_row(int n) { text->set_text_row(n); - yscroll->update_value(n); + update_scrollbars(); return 1; } void BC_ScrollTextBox::update(const char *text) { this->text->update(text); - yscroll->update_length(this->text->get_text_rows(), - this->text->get_text_row(), - yscroll->get_handlelength(), - 1); + update_scrollbars(); } void BC_ScrollTextBox::update(const wchar_t *wtext) { this->text->update(wtext); - yscroll->update_length(this->text->get_text_rows(), - this->text->get_text_row(), - yscroll->get_handlelength(), - 1); + update_scrollbars(); } void BC_ScrollTextBox::reposition_window(int x, int y, int w, int rows) @@ -2366,41 +2246,47 @@ void BC_ScrollTextBox::reposition_window(int x, int y, int w, int rows) this->y = y; this->w = w; this->rows = rows; - - text->reposition_window(x, - y, - w - yscroll->get_span(), - rows); - yscroll->reposition_window(x + w - yscroll->get_span(), - y, - BC_TextBox::calculate_row_h(rows, - parent_window)); - yscroll->update_length(text->get_text_rows(), - text->get_text_row(), - rows, - 0); + update_scrollbars(); } -void BC_ScrollTextBox::set_selection(int char1, int char2, int ibeam) +int BC_ScrollTextBox::button_press_event() { - this->text->set_selection(char1, char2, ibeam); + return text->BC_TextBox::button_press_event(); } +int BC_ScrollTextBox::button_release_event() +{ + return text->BC_TextBox::button_release_event(); +} + +int BC_ScrollTextBox::get_h() { return text->get_h(); } +const char *BC_ScrollTextBox::get_text() { return text->get_text(); } +const wchar_t *BC_ScrollTextBox::get_wtext() { return text->get_wtext(); } +int BC_ScrollTextBox::get_buttonpress() +{ + return text->BC_TextBox::get_buttonpress(); +} void BC_ScrollTextBox::wset_selection(int char1, int char2, int ibeam) { - this->text->wset_selection(char1, char2, ibeam); + text->wset_selection(char1, char2, ibeam); +} +void BC_ScrollTextBox::set_selection(int char1, int char2, int ibeam) +{ + text->set_selection(char1, char2, ibeam); } - int BC_ScrollTextBox::get_ibeam_letter() { - return this->text->get_ibeam_letter(); + return text->get_ibeam_letter(); +} +int BC_ScrollTextBox::get_x_pos() +{ + return text->left_margin - text->get_text_x(); +} +void BC_ScrollTextBox::set_x_pos(int x) +{ + text->set_text_x(text->left_margin - x); + text->draw(1); } - - - - - - BC_ScrollTextBoxText::BC_ScrollTextBoxText(BC_ScrollTextBox *gui, const char *text) : BC_TextBox(gui->x, gui->y, @@ -2427,36 +2313,111 @@ BC_ScrollTextBoxText::~BC_ScrollTextBoxText() } } +void BC_ScrollTextBox::update_scrollbars() +{ + int view_w = w, view_rows = rows; + int view_h = BC_TextBox::calculate_row_h(view_rows, parent_window); + int text_rows = text->get_text_rows(); + int text_width = parent_window->get_text_width(text->font, text->get_wtext()); + BC_Resources *resources = parent_window->get_resources(); + int need_xscroll = 0, need_yscroll = 0; + +// Create scrollbars as needed + int resize = 1; + while( resize ) { + resize = 0; + if( !need_xscroll && (text->get_text_x() != text->left_margin || + text_width >= view_w - text->left_margin - text->right_margin) ) { + resize = need_xscroll = 1; + view_h -= resources->hscroll_data[SCROLL_HANDLE_UP]->get_h(); + view_rows = BC_TextBox::pixels_to_rows(parent_window, text->font, view_h); + } + if( !need_yscroll && (text->get_text_y() != text->top_margin || + text_rows > view_rows) ) { + resize = need_yscroll = 1; + view_w -= resources->vscroll_data[SCROLL_HANDLE_UP]->get_w(); + } + } + + if( !need_xscroll && xscroll ) { + text->yscroll = 0; + delete xscroll; xscroll = 0; + } + if( !need_yscroll && yscroll ) { + text->yscroll = 0; + delete yscroll; yscroll = 0; + } + + if( view_rows != text->get_rows() || view_w != text->get_w() ) { + text->reposition_window(x, y, view_w, view_rows); + } + if( need_xscroll && !xscroll ) { + xscroll = new BC_ScrollTextBoxXScroll(this); + parent_window->add_subwindow(xscroll); + text->xscroll = xscroll; + xscroll->bound_to = text; + xscroll->show_window(); + } + if( need_yscroll && !yscroll ) { + yscroll = new BC_ScrollTextBoxYScroll(this); + parent_window->add_subwindow(yscroll); + text->yscroll = yscroll; + yscroll->bound_to = text; + yscroll->show_window(); + } + if( xscroll ) { + xscroll->reposition_window(x, y + text->get_h(), view_w); + int xpos = get_x_pos(); + if( xpos != xscroll->get_value() ) + xscroll->update_value(xpos); + if( text_width != xscroll->get_length() || + view_w != xscroll->get_handlelength() ) + xscroll->update_length(text_width, xpos, view_w, 0); + } + if( yscroll ) { + yscroll->reposition_window(x + w - yscroll->get_span(), y, text->get_h()); + int text_row = text->get_text_row(); + if( text_row != yscroll->get_value() ) + yscroll->update_value(text_row); + if( text_rows != yscroll->get_length() || + view_rows != yscroll->get_handlelength() ) + yscroll->update_length(text_rows, text_row, view_rows, 0); + } +} + int BC_ScrollTextBoxText::handle_event() { - gui->yscroll->update_length(get_text_rows(), - get_text_row(), - gui->yscroll->get_handlelength(), - 1); + gui->update_scrollbars(); return gui->handle_event(); } int BC_ScrollTextBoxText::motion_event() { - gui->yscroll->update_length(get_text_rows(), - get_text_row(), - gui->yscroll->get_handlelength(), - 1); + gui->update_scrollbars(); return 1; } +BC_ScrollTextBoxXScroll::BC_ScrollTextBoxXScroll(BC_ScrollTextBox *gui) + : BC_ScrollBar(gui->x, gui->y + gui->text->get_h(), SCROLL_HORIZ + SCROLL_STRETCH, + gui->text->get_w(), gui->text->get_text_width(MEDIUMFONT, gui->get_wtext()), + 0, gui->w) +{ + this->gui = gui; +} + +BC_ScrollTextBoxXScroll::~BC_ScrollTextBoxXScroll() +{ +} + +int BC_ScrollTextBoxXScroll::handle_event() +{ + gui->set_x_pos(get_position()); + return 1; +} BC_ScrollTextBoxYScroll::BC_ScrollTextBoxYScroll(BC_ScrollTextBox *gui) - : BC_ScrollBar(gui->x + - gui->w - - get_resources()->vscroll_data[SCROLL_HANDLE_UP]->get_w(), - gui->y, - SCROLL_VERT, - BC_TextBox::calculate_row_h(gui->rows, - gui->parent_window), - gui->text->get_text_rows(), - 0, - gui->rows) + : BC_ScrollBar(gui->x + gui->text->get_w(), gui->y, SCROLL_VERT, + gui->text->get_h(), gui->text->get_text_rows(), 0, gui->rows) { this->gui = gui; } @@ -2473,13 +2434,6 @@ int BC_ScrollTextBoxYScroll::handle_event() - - - - - - - BC_PopupTextBoxText::BC_PopupTextBoxText(BC_PopupTextBox *popup, int x, int y, const char *text) : BC_TextBox(x, y, popup->text_w, 1, text, BCTEXTLEN) { @@ -2521,6 +2475,7 @@ int BC_PopupTextBoxList::handle_event() if(item) { popup->textbox->update(item->get_text()); + popup->textbox->set_text_row(0); popup->handle_event(); } return 1; @@ -2569,14 +2524,12 @@ int BC_PopupTextBox::create_objects() void BC_PopupTextBox::update(const char *text) { textbox->update(text); + textbox->set_text_row(0); } void BC_PopupTextBox::update_list(ArrayList *data) { - listbox->update(data, - 0, - 0, - 1); + listbox->update(data, 0, 0, 1); } @@ -2615,6 +2568,16 @@ int BC_PopupTextBox::get_h() return textbox->get_h(); } +int BC_PopupTextBox::get_show_query() +{ + return listbox->get_show_query(); +} + +void BC_PopupTextBox::set_show_query(int v) +{ + listbox->set_show_query(v); +} + int BC_PopupTextBox::handle_event() { return 1; @@ -2648,23 +2611,15 @@ void BC_PopupTextBox::reposition_window(int x, int y) BC_TumbleTextBoxText::BC_TumbleTextBoxText(BC_TumbleTextBox *popup, - int64_t default_value, - int64_t min, - int64_t max, - int x, - int y) + int64_t default_value, int x, int y) : BC_TextBox(x, y, popup->text_w, 1, default_value) { this->popup = popup; } BC_TumbleTextBoxText::BC_TumbleTextBoxText(BC_TumbleTextBox *popup, - float default_value, - float min, - float max, - int x, - int y) - : BC_TextBox(x, y, popup->text_w, 1, default_value) + float default_value, int x, int y, int precision) + : BC_TextBox(x, y, popup->text_w, 1, default_value, 1, MEDIUMFONT, precision) { this->popup = popup; } @@ -2689,19 +2644,10 @@ int BC_TumbleTextBoxText::handle_event() int BC_TumbleTextBoxText::button_press_event() { - if(is_event_win()) - { - if(get_buttonpress() < 4) return BC_TextBox::button_press_event(); - - if(get_buttonpress() == 4) - { - popup->tumbler->handle_up_event(); - } - else - if(get_buttonpress() == 5) - { - popup->tumbler->handle_down_event(); - } + if( get_enabled() && is_event_win() ) { + if( get_buttonpress() < 4 ) return BC_TextBox::button_press_event(); + if( get_buttonpress() == 4 ) popup->tumbler->handle_up_event(); + else if( get_buttonpress() == 5 ) popup->tumbler->handle_down_event(); return 1; } return 0; @@ -2816,39 +2762,17 @@ int BC_TumbleTextBox::create_objects() { int x = this->x, y = this->y; - if(use_float) - { - parent_window->add_subwindow(textbox = new BC_TumbleTextBoxText(this, - default_value_f, - min_f, - max_f, - x, - y)); - textbox->set_precision(precision); - } - else - parent_window->add_subwindow(textbox = new BC_TumbleTextBoxText(this, - default_value, - min, - max, - x, - y)); + textbox = use_float ? + new BC_TumbleTextBoxText(this, default_value_f, x, y, precision) : + new BC_TumbleTextBoxText(this, default_value, x, y); + parent_window->add_subwindow(textbox); x += textbox->get_w(); - if(use_float) - parent_window->add_subwindow(tumbler = new BC_FTumbler(textbox, - min_f, - max_f, - x, - y)); - else - parent_window->add_subwindow(tumbler = new BC_ITumbler(textbox, - min, - max, - x, - y)); - + tumbler = use_float ? + (BC_Tumbler *)new BC_FTumbler(textbox, min_f, max_f, x, y) : + (BC_Tumbler *)new BC_ITumbler(textbox, min, max, x, y); + parent_window->add_subwindow(tumbler); tumbler->set_increment(increment); return 0; } @@ -2871,18 +2795,21 @@ BC_TextBox* BC_TumbleTextBox::get_textbox() int BC_TumbleTextBox::update(const char *value) { textbox->update(value); + textbox->set_text_row(0); return 0; } int BC_TumbleTextBox::update(int64_t value) { textbox->update(value); + textbox->set_text_row(0); return 0; } int BC_TumbleTextBox::update(float value) { textbox->update(value); + textbox->set_text_row(0); return 0; } @@ -2907,17 +2834,23 @@ int BC_TumbleTextBox::get_h() return textbox->get_h(); } -void BC_TumbleTextBox::disable() +void BC_TumbleTextBox::disable(int hide_text) { + if( hide_text && !textbox->is_hidden() ) + textbox->hide_window(0); + if( !tumbler->is_hidden() ) + tumbler->hide_window(0); if( !get_enabled() ) return; - tumbler->hide_window(0); return textbox->disable(); } void BC_TumbleTextBox::enable() { + if( textbox->is_hidden() ) + textbox->show_window(0); + if( tumbler->is_hidden() ) + tumbler->show_window(0); if( get_enabled() ) return; - tumbler->show_window(0); return textbox->enable(); } @@ -2955,3 +2888,69 @@ void BC_TumbleTextBox::set_boundaries(float min, float max) { tumbler->set_boundaries(min, max); } + + + +BC_TextMenu::BC_TextMenu(BC_TextBox *textbox) + : BC_PopupMenu(0, 0, 0, "", 0) +{ + this->textbox = textbox; +} + +BC_TextMenu::~BC_TextMenu() +{ +} + +void BC_TextMenu::create_objects() +{ + add_item(new BC_TextMenuCut(this)); + add_item(new BC_TextMenuCopy(this)); + add_item(new BC_TextMenuPaste(this)); +} + + +BC_TextMenuCut::BC_TextMenuCut(BC_TextMenu *menu) + : BC_MenuItem(_("Cut")) +{ + this->menu = menu; +} + +int BC_TextMenuCut::handle_event() +{ + menu->textbox->cut(1); + + return 0; +} + + +BC_TextMenuCopy::BC_TextMenuCopy(BC_TextMenu *menu) + : BC_MenuItem(_("Copy")) +{ + this->menu = menu; +} + +int BC_TextMenuCopy::handle_event() +{ + menu->textbox->copy(1); + return 0; +} + + +BC_TextMenuPaste::BC_TextMenuPaste(BC_TextMenu *menu) + : BC_MenuItem(_("Paste")) +{ + this->menu = menu; +} + +int BC_TextMenuPaste::handle_event() +{ + menu->textbox->paste(1); + return 0; +} + + +void BC_TumbleTextBox::set_tooltip(const char *text) +{ + textbox->set_tooltip(text); +} +