Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

bctextbox.C

Go to the documentation of this file.
00001 #include "bcclipboard.h"
00002 #include "bclistboxitem.h"
00003 #include "bcresources.h"
00004 #include "bctextbox.h"
00005 #include "clip.h"
00006 #include "colors.h"
00007 #include <ctype.h>
00008 #include "cursors.h"
00009 #include "keys.h"
00010 #include <math.h>
00011 #include "bctimer.h"
00012 #include "vframe.h"
00013 
00014 #include <string.h>
00015 
00016 #define VERTICAL_MARGIN 2
00017 #define VERTICAL_MARGIN_NOBORDER 0
00018 #define HORIZONTAL_MARGIN 4
00019 #define HORIZONTAL_MARGIN_NOBORDER 2
00020 
00021 BC_TextBox::BC_TextBox(int x, 
00022         int y, 
00023         int w, 
00024         int rows, 
00025         char *text, 
00026         int has_border, 
00027         int font)
00028  : BC_SubWindow(x, y, w, 0, -1)
00029 {
00030         skip_cursor = 0;
00031         reset_parameters(rows, has_border, font);
00032         strcpy(this->text, text);
00033 }
00034 
00035 BC_TextBox::BC_TextBox(int x, 
00036         int y, 
00037         int w, 
00038         int rows, 
00039         int64_t text, 
00040         int has_border, 
00041         int font)
00042  : BC_SubWindow(x, y, w, 0, -1)
00043 {
00044         skip_cursor = 0;
00045         reset_parameters(rows, has_border, font);
00046         sprintf(this->text, "%lld", text);
00047 }
00048 
00049 BC_TextBox::BC_TextBox(int x, 
00050         int y, 
00051         int w, 
00052         int rows, 
00053         float text, 
00054         int has_border, 
00055         int font,
00056         int precision)
00057  : BC_SubWindow(x, y, w, 0, -1)
00058 {
00059         skip_cursor = 0;
00060         reset_parameters(rows, has_border, font);
00061         this->precision = precision;
00062         sprintf(this->text, "%0.*f", precision, text);
00063 }
00064 
00065 BC_TextBox::BC_TextBox(int x, 
00066         int y, 
00067         int w, 
00068         int rows, 
00069         int text, 
00070         int has_border, 
00071         int font)
00072  : BC_SubWindow(x, y, w, 0, -1)
00073 {
00074         skip_cursor = 0;
00075         reset_parameters(rows, has_border, font);
00076         sprintf(this->text, "%d", text);
00077 }
00078 
00079 BC_TextBox::~BC_TextBox()
00080 {
00081         if(skip_cursor) delete skip_cursor;
00082 }
00083 
00084 int BC_TextBox::reset_parameters(int rows, int has_border, int font)
00085 {
00086         this->rows = rows;
00087         this->has_border = has_border;
00088         this->font = font;
00089         text_start = 0;
00090         text_end = 0;
00091         highlight_letter1 = highlight_letter2 = 0;
00092         highlight_letter3 = highlight_letter4 = 0;
00093         ibeam_letter = 0;
00094         active = 0;
00095         text_selected = word_selected = 0;
00096         text_x = 0;
00097         enabled = 1;
00098         highlighted = 0;
00099         precision = 4;
00100         if (!skip_cursor)
00101                 skip_cursor = new Timer;
00102         keypress_draw = 1;
00103         last_keypress = 0;
00104         separators = 0;
00105         return 0;
00106 }
00107 
00108 int BC_TextBox::initialize()
00109 {
00110         if (!skip_cursor)
00111                 skip_cursor = new Timer;
00112         skip_cursor->update();
00113 // Get dimensions
00114         text_ascent = get_text_ascent(font) + 1;
00115         text_descent = get_text_descent(font) + 1;
00116         text_height = text_ascent + text_descent;
00117         ibeam_letter = strlen(text);
00118         if(has_border)
00119         {
00120                 left_margin = right_margin = HORIZONTAL_MARGIN;
00121                 top_margin = bottom_margin = VERTICAL_MARGIN;
00122         }
00123         else
00124         {
00125                 left_margin = right_margin = HORIZONTAL_MARGIN_NOBORDER;
00126                 top_margin = bottom_margin = VERTICAL_MARGIN_NOBORDER;
00127         }
00128         h = get_row_h(rows);
00129         text_x = left_margin;
00130         text_y = top_margin;
00131         find_ibeam(0);
00132 
00133 // Create the subwindow
00134         BC_SubWindow::initialize();
00135 
00136         BC_Resources *resources = get_resources();
00137         if(has_border)
00138         {
00139                 back_color = resources->text_background;
00140                 high_color = resources->text_background_hi;
00141         }
00142         else 
00143         {
00144                 high_color = resources->text_background_noborder_hi;
00145                 back_color = bg_color;
00146         }
00147 
00148         draw();
00149         set_cursor(IBEAM_CURSOR);
00150         return 0;
00151 }
00152 
00153 int BC_TextBox::calculate_h(BC_WindowBase *gui, 
00154         int font, 
00155         int has_border,
00156         int rows)
00157 {
00158         return rows * (gui->get_text_ascent(font) + 1 + 
00159                 gui->get_text_descent(font) + 1) +
00160                 2 * (has_border ? VERTICAL_MARGIN : VERTICAL_MARGIN_NOBORDER);
00161 }
00162 
00163 void BC_TextBox::set_precision(int precision)
00164 {
00165         this->precision = precision;
00166 }
00167 
00168 int BC_TextBox::update(char *text)
00169 {
00170 //printf("BC_TextBox::update 1 %d %s %s\n", strcmp(text, this->text), text, this->text);
00171         int text_len = strlen(text);
00172 // Don't update if contents are the same
00173         if(!strcmp(text, this->text)) return 0;
00174 
00175 
00176         strcpy(this->text, text);
00177         if(highlight_letter1 > text_len) highlight_letter1 = text_len;
00178         if(highlight_letter2 > text_len) highlight_letter2 = text_len;
00179         if(ibeam_letter > text_len) ibeam_letter = text_len;
00180         draw();
00181         return 0;
00182 }
00183 
00184 int BC_TextBox::update(int64_t value)
00185 {
00186         char string[BCTEXTLEN];
00187         sprintf(string, "%lld", value);
00188 
00189 
00190         update(string);
00191         return 0;
00192 }
00193 
00194 int BC_TextBox::update(float value)
00195 {
00196         char string[BCTEXTLEN];
00197         sprintf(string, "%0.*f", precision, value);
00198 
00199         update(string);
00200         return 0;
00201 }
00202 
00203 void BC_TextBox::disable()
00204 {
00205         if(enabled)
00206         {
00207                 enabled = 0;
00208                 if(top_level)
00209                 {
00210                         if(active) top_level->deactivate();
00211                         draw();
00212                 }
00213         }
00214 }
00215 
00216 void BC_TextBox::enable()
00217 {
00218         if(!enabled)
00219         {
00220                 enabled = 1;
00221                 if(top_level)
00222                 {
00223                         draw();
00224                 }
00225         }
00226 }
00227 
00228 int BC_TextBox::get_enabled()
00229 {
00230         return enabled;
00231 }
00232 
00233 int BC_TextBox::pixels_to_rows(BC_WindowBase *window, int font, int pixels)
00234 {
00235         return (pixels - 4) / 
00236                 (window->get_text_ascent(font) + 1 + 
00237                         window->get_text_descent(font) + 1);
00238 }
00239 
00240 int BC_TextBox::calculate_row_h(int rows, 
00241         BC_WindowBase *parent_window, 
00242         int has_border, 
00243         int font)
00244 {
00245         return rows * 
00246                 (parent_window->get_text_ascent(font) + 1 + 
00247                 parent_window->get_text_descent(font) + 1) +
00248                 (has_border ? 4 : 0);
00249 }
00250 
00251 char* BC_TextBox::get_text()
00252 {
00253         return text;
00254 }
00255 
00256 int BC_TextBox::get_text_rows()
00257 {
00258         int text_len = strlen(text);
00259         int result = 1;
00260         for(int i = 0; i < text_len; i++)
00261         {
00262                 if(text[i] == 0xa) result++;
00263         }
00264         return result;
00265 }
00266 
00267 
00268 int BC_TextBox::get_row_h(int rows)
00269 {
00270         return rows * text_height + top_margin + bottom_margin;
00271 }
00272 
00273 int BC_TextBox::reposition_window(int x, int y, int w, int rows)
00274 {
00275         int new_h = get_h();
00276         if(w < 0) w = get_w();
00277         if(rows != -1)
00278         {
00279                 new_h = get_row_h(rows);
00280                 this->rows = rows;
00281         }
00282 
00283         if(x != get_x() || 
00284                 y != get_y() || 
00285                 w != get_w() || 
00286                 new_h != get_h())
00287         {
00288 // printf("BC_TextBox::reposition_window 1 %d %d %d %d %d %d %d %d\n",
00289 // x, get_x(), y, get_y(), w, get_w(), new_h, get_h());
00290                 BC_WindowBase::reposition_window(x, y, w, new_h);
00291                 draw();
00292         }
00293         return 0;
00294 }
00295 
00296 void BC_TextBox::draw_border()
00297 {
00298         BC_Resources *resources = get_resources();
00299 // Clear margins
00300         set_color(background_color);
00301         draw_box(0, 0, left_margin, get_h());
00302         draw_box(get_w() - right_margin, 0, right_margin, get_h());
00303 
00304         if(has_border)
00305         {
00306                 if(highlighted)
00307                         draw_3d_border(0, 0, w, h,
00308                                 resources->button_shadow, 
00309                                 resources->button_uphighlighted,
00310                                 resources->button_highlighted,
00311                                 resources->button_light);
00312                 else
00313                         draw_3d_border(0, 0, w, h, 
00314                                 resources->text_border1, 
00315                                 resources->text_border2,
00316                                 resources->text_border3,
00317                                 resources->text_border4);
00318         }
00319 }
00320 
00321 void BC_TextBox::draw_cursor()
00322 {
00323 //      set_color(background_color);
00324         set_color(WHITE);
00325         set_inverse();
00326 
00327         draw_box(ibeam_x + text_x, 
00328                 ibeam_y + text_y, 
00329                 BCCURSORW, 
00330                 text_height);
00331         set_opaque();
00332 }
00333 
00334 
00335 void BC_TextBox::draw()
00336 {
00337         int i, j, k, text_len;
00338         int row_begin, row_end;
00339         int highlight_x1, highlight_x2;
00340         int need_ibeam = 1;
00341         BC_Resources *resources = get_resources();
00342 
00343 //printf("BC_TextBox::draw 1 %s\n", text);
00344 // Background
00345         if(has_border)
00346         {
00347                 background_color = resources->text_background;
00348         }
00349         else
00350         {
00351                 if(highlighted)
00352                 {
00353                         background_color = high_color;
00354                 }
00355                 else
00356                 {
00357                         background_color = back_color;
00358                 }
00359         }
00360 
00361         set_color(background_color);
00362         draw_box(0, 0, w, h);
00363 
00364 // Draw text with selection
00365         set_font(font);
00366         text_len = strlen(text);
00367 //printf("BC_TextBox::draw 0 %s %d %d %d %d\n", text, text_y, text_len, get_w(), text_height);
00368 
00369         for(i = 0, k = text_y; i < text_len && k < get_h(); k += text_height)
00370         {
00371 // Draw row of text
00372                 if(text[i] == '\n') i++;
00373                 row_begin = i;
00374                 for(j = 0; text[i] != '\n' && i < text_len; j++, i++)
00375                 {
00376                         text_row[j] = text[i];
00377                 }
00378                 row_end = i;
00379                 text_row[j] = 0;
00380 
00381 //printf("BC_TextBox::draw 1 %d %d %c\n", row_begin, row_end, text_row[j - 1]);
00382 
00383                 if(k > -text_height + top_margin && k < get_h() - bottom_margin)
00384                 {
00385 // Draw highlighted region of row
00386                         if(highlight_letter2 > highlight_letter1 &&
00387                                 highlight_letter2 > row_begin && highlight_letter1 < row_end)
00388                         {
00389                                 if(active && enabled && get_has_focus())
00390                                         set_color(resources->text_highlight);
00391                                 else
00392                                         set_color(resources->text_inactive_highlight);
00393 
00394                                 if(highlight_letter1 >= row_begin && highlight_letter1 < row_end)
00395                                         highlight_x1 = get_text_width(font, text_row, highlight_letter1 - row_begin);
00396                                 else
00397                                         highlight_x1 = 0;
00398 
00399                                 if(highlight_letter2 > row_begin && highlight_letter2 <= row_end)
00400                                         highlight_x2 = get_text_width(font, text_row, highlight_letter2 - row_begin);
00401                                 else
00402                                         highlight_x2 = get_w();
00403 
00404                                 draw_box(highlight_x1 + text_x, 
00405                                         k, 
00406                                         highlight_x2 - highlight_x1, 
00407                                         text_height);
00408                         }
00409 
00410 // Draw text over highlight
00411                         if(enabled)
00412                                 set_color(resources->text_default);
00413                         else
00414                                 set_color(MEGREY);
00415 
00416                         draw_text(text_x, k + text_ascent, text_row);
00417 
00418 // Get ibeam location
00419                         if(ibeam_letter >= row_begin && ibeam_letter <= row_end)
00420                         {
00421                                 need_ibeam = 0;
00422                                 ibeam_y = k - text_y;
00423                                 ibeam_x = get_text_width(font, text_row, ibeam_letter - row_begin);
00424                         }
00425                 }
00426         }
00427 
00428 //printf("BC_TextBox::draw 3 %d\n", ibeam_y);
00429         if(need_ibeam)
00430         {
00431                 ibeam_x = 0;
00432                 ibeam_y = 0;
00433         }
00434 
00435 //printf("BC_TextBox::draw 4 %d\n", ibeam_y);
00436 // Draw solid cursor
00437         if (active) 
00438                 draw_cursor();
00439 
00440 // Border
00441         draw_border();
00442         flash();
00443         flush();   
00444 }
00445 
00446 int BC_TextBox::focus_in_event()
00447 {
00448         draw();
00449         return 1;
00450 }
00451 
00452 int BC_TextBox::focus_out_event()
00453 {
00454         draw();
00455         return 1;
00456 }
00457 
00458 int BC_TextBox::cursor_enter_event()
00459 {
00460         if(top_level->event_win == win && enabled)
00461         {
00462                 tooltip_done = 0;
00463 
00464                 if(!highlighted)
00465                 {
00466                         highlighted = 1;
00467                         draw_border();
00468                         flash();
00469                         flush();   
00470                 }
00471         }
00472         return 0;
00473 }
00474 
00475 int BC_TextBox::cursor_leave_event()
00476 {
00477         if(highlighted)
00478         {
00479                 highlighted = 0;
00480                 draw_border();
00481                 hide_tooltip();
00482                 flash();
00483                 flush();   
00484         }
00485         return 0;
00486 }
00487 
00488 int BC_TextBox::button_press_event()
00489 {
00490         if(get_buttonpress() > 2) return 0;
00491 
00492         int cursor_letter = 0;
00493         int text_len = strlen(text);
00494 
00495         if(!enabled) return 0;
00496 
00497         if(top_level->event_win == win)
00498         {
00499                 if(!active)
00500                 {
00501                         hide_tooltip();
00502                         top_level->deactivate();
00503                         activate();
00504                 }
00505 
00506                 cursor_letter = get_cursor_letter(top_level->cursor_x, top_level->cursor_y);
00507                 if(get_double_click())
00508                 {
00509                         word_selected = 1;
00510                         select_word(highlight_letter1, highlight_letter2, cursor_letter);
00511                         highlight_letter3 = highlight_letter1;
00512                         highlight_letter4 = highlight_letter2;
00513                         ibeam_letter = highlight_letter2;
00514                         copy_selection(PRIMARY_SELECTION);
00515                 }
00516                 else
00517                 if(get_buttonpress() == 2)
00518                 {
00519                         highlight_letter3 = highlight_letter4 = 
00520                                 ibeam_letter = highlight_letter1 = 
00521                                 highlight_letter2 = cursor_letter;
00522                         paste_selection(PRIMARY_SELECTION);
00523                 }
00524                 else
00525                 {
00526                         text_selected = 1;
00527                         highlight_letter3 = highlight_letter4 = 
00528                                 ibeam_letter = highlight_letter1 = 
00529                                 highlight_letter2 = cursor_letter;
00530                 }
00531                 
00532                 if(ibeam_letter < 0) ibeam_letter = 0;
00533                 if(ibeam_letter > text_len) ibeam_letter = text_len;
00534                 draw();
00535                 return 1;
00536         }
00537         else
00538         if(active)
00539         {
00540                 top_level->deactivate();
00541         }
00542 
00543         return 0;
00544 }
00545 
00546 int BC_TextBox::button_release_event()
00547 {
00548         if(active)
00549         {
00550                 hide_tooltip();
00551                 if(text_selected || word_selected)
00552                 {
00553                         text_selected = 0;
00554                         word_selected = 0;
00555                 }
00556         }
00557         return 0;
00558 }
00559 
00560 int BC_TextBox::cursor_motion_event()
00561 {
00562         int cursor_letter, text_len = strlen(text), letter1, letter2;
00563         if(active)
00564         {
00565                 if(text_selected || word_selected)
00566                 {
00567                         cursor_letter = get_cursor_letter(top_level->cursor_x, top_level->cursor_y);
00568                         if(word_selected)
00569                         {
00570                                 select_word(letter1, letter2, cursor_letter);
00571                         }
00572                         else
00573                         if(text_selected)
00574                         {
00575                                 letter1 = letter2 = cursor_letter;
00576                         }
00577 
00578                         if(letter1 <= highlight_letter3)
00579                         {
00580                                 highlight_letter1 = letter1;
00581                                 highlight_letter2 = highlight_letter4;
00582                                 ibeam_letter = letter1;
00583                         }
00584                         else
00585                         if(letter2 >= highlight_letter4)
00586                         {
00587                                 highlight_letter2 = letter2;
00588                                 highlight_letter1 = highlight_letter3;
00589                                 ibeam_letter = letter2;
00590                         }
00591                         
00592                         copy_selection(PRIMARY_SELECTION);
00593                         find_ibeam(1);
00594                         draw();
00595                         return 1;
00596                 }
00597         }
00598         return 0;
00599 }
00600 
00601 int BC_TextBox::activate()
00602 {
00603         top_level->active_subwindow = this;
00604         active = 1;
00605         draw();
00606         top_level->set_repeat(top_level->get_resources()->blink_rate);
00607         return 0;
00608 }
00609 
00610 int BC_TextBox::deactivate()
00611 {
00612         active = 0;
00613         top_level->unset_repeat(top_level->get_resources()->blink_rate);
00614         draw();
00615         return 0;
00616 }
00617 
00618 int BC_TextBox::repeat_event(int64_t duration)
00619 {
00620         int result = 0;
00621 
00622         if(duration == top_level->get_resources()->tooltip_delay &&
00623                 tooltip_text[0] != 0 &&
00624                 highlighted)
00625         {
00626                 show_tooltip();
00627                 tooltip_done = 1;
00628                 result = 1;
00629         }
00630                 
00631         if(duration == top_level->get_resources()->blink_rate && 
00632                 active &&
00633                 get_has_focus())
00634         {
00635                 if(skip_cursor->get_difference() < duration)
00636                 {
00637 // printf("BC_TextBox::repeat_event 1 %lld %lld\n", 
00638 // skip_cursor->get_difference(), 
00639 // duration);
00640                         return 1;
00641                 }
00642                 draw_cursor();
00643                 flash();
00644                 flush();   
00645                 result = 1;
00646         }
00647         return result;
00648 }
00649 
00650 void BC_TextBox::default_keypress(int &dispatch_event, int &result)
00651 {
00652     if((top_level->get_keypress() == RETURN) ||
00653 //              (top_level->get_keypress() > 30 && top_level->get_keypress() < 127))
00654                 (top_level->get_keypress() > 30 && top_level->get_keypress() <= 255))
00655         {
00656 // Substitute UNIX linefeed
00657                 if(top_level->get_keypress() == RETURN) 
00658                         temp_string[0] = 0xa;
00659                 else
00660                         temp_string[0] = top_level->get_keypress();
00661                 temp_string[1] = 0;
00662                 insert_text(temp_string);
00663                 find_ibeam(1);
00664                 draw();
00665                 dispatch_event = 1;
00666                 result = 1;
00667         }
00668 }
00669 
00670 int BC_TextBox::select_whole_text(int select)
00671 {
00672         if (select == 1) 
00673         {
00674                 highlight_letter1 = 0;
00675                 highlight_letter2 = strlen(text);
00676                 text_selected = word_selected = 0;      
00677                 ibeam_letter = highlight_letter1;
00678                 find_ibeam(1);
00679                 if(keypress_draw) draw();
00680         } else
00681         if (select == -1)
00682         {
00683                 ibeam_letter = strlen(text);
00684                 highlight_letter1 = ibeam_letter;
00685                 highlight_letter2 = ibeam_letter;
00686                 text_selected = word_selected = 0;
00687                 find_ibeam(1);
00688                 if(keypress_draw) draw();
00689         }
00690         return highlight_letter2 - highlight_letter1;
00691 }
00692 
00693 void BC_TextBox::cycle_textboxes(int amout)
00694 {
00695         top_level->cycle_textboxes(amout);
00696 }
00697 
00698 int BC_TextBox::keypress_event()
00699 {
00700 // Result == 2 contents changed
00701 // Result == 1 trapped keypress
00702 // Result == 0 nothing
00703         int result = 0;
00704         int text_len;
00705         int dispatch_event = 0;
00706 
00707         if(!active || !enabled) return 0;
00708 
00709         text_len = strlen(text);
00710         last_keypress = get_keypress();
00711         switch(get_keypress())
00712         {
00713                 case ESC:
00714                         top_level->deactivate();
00715                         result = 0;
00716                         break;
00717 
00718                 case RETURN:
00719                         if(rows == 1)
00720                         {
00721                                 top_level->deactivate();
00722                                 dispatch_event = 1;
00723                                 result = 0;
00724                         }
00725                         else
00726                         {
00727                                 default_keypress(dispatch_event, result);
00728                         }
00729                         break;
00730 // Handle like a default keypress
00731 
00732                 case TAB:
00733                         cycle_textboxes(1);
00734                         result = 1;
00735                         break;
00736 
00737                 case LEFTTAB:
00738                         cycle_textboxes(-1);
00739                         result = 1;
00740                         break;
00741 
00742                 case LEFT:
00743                         if(ibeam_letter > 0)
00744                         {
00745                                 int old_ibeam_letter = ibeam_letter;
00746 // Single character
00747                                 if(!ctrl_down())
00748                                 {
00749                                         ibeam_letter--;
00750                                 }
00751                                 else
00752 // Word
00753                                 {
00754                                         ibeam_letter--;
00755                                         while(ibeam_letter > 0 && isalnum(text[ibeam_letter - 1]))
00756                                                 ibeam_letter--;
00757                                 }
00758 
00759 
00760 // Extend selection
00761                                 if(top_level->shift_down())
00762                                 {
00763 // Initialize highlighting
00764                                         if(highlight_letter1 == highlight_letter2)
00765                                         {
00766                                                 highlight_letter1 = ibeam_letter;
00767                                                 highlight_letter2 = old_ibeam_letter;
00768                                         }
00769                                         else
00770 // Extend left highlight
00771                                         if(highlight_letter1 == old_ibeam_letter)
00772                                         {
00773                                                 highlight_letter1 = ibeam_letter;
00774                                         }
00775                                         else
00776 // Shrink right highlight
00777                                         if(highlight_letter2 == old_ibeam_letter)
00778                                         {
00779                                                 highlight_letter2 = ibeam_letter;
00780                                         }
00781                                 }
00782                                 else
00783                                 {
00784                                         highlight_letter1 = highlight_letter2 = ibeam_letter;
00785                                 }
00786 
00787 
00788                                 find_ibeam(1);
00789                                 if(keypress_draw) draw();
00790                         }
00791                         result = 1;
00792                         break;
00793 
00794                 case RIGHT:
00795                         if(ibeam_letter < text_len)
00796                         {
00797                                 int old_ibeam_letter = ibeam_letter;
00798 // Single character
00799                                 if(!ctrl_down())
00800                                 {
00801                                         ibeam_letter++;
00802                                 }
00803                                 else
00804 // Word
00805                                 {
00806                                         while(ibeam_letter < text_len && isalnum(text[ibeam_letter++]))
00807                                                 ;
00808                                 }
00809 
00810 
00811 
00812 // Extend selection
00813                                 if(top_level->shift_down())
00814                                 {
00815 // Initialize highlighting
00816                                         if(highlight_letter1 == highlight_letter2)
00817                                         {
00818                                                 highlight_letter1 = old_ibeam_letter;
00819                                                 highlight_letter2 = ibeam_letter;
00820                                         }
00821                                         else
00822 // Shrink left highlight
00823                                         if(highlight_letter1 == old_ibeam_letter)
00824                                         {
00825                                                 highlight_letter1 = ibeam_letter;
00826                                         }
00827                                         else
00828 // Expand right highlight
00829                                         if(highlight_letter2 == old_ibeam_letter)
00830                                         {
00831                                                 highlight_letter2 = ibeam_letter;
00832                                         }
00833                                 }
00834                                 else
00835                                 {
00836                                         highlight_letter1 = highlight_letter2 = ibeam_letter;
00837                                 }
00838 
00839                                 find_ibeam(1);
00840                                 if(keypress_draw) draw();
00841                         }
00842                         result = 1;
00843                         break;
00844 
00845                 case UP:
00846                         if(ibeam_letter > 0)
00847                         {
00848 //printf("BC_TextBox::keypress_event 1 %d %d %d\n", ibeam_x, ibeam_y, ibeam_letter);
00849                                 int new_letter = get_cursor_letter(ibeam_x + text_x, 
00850                                         ibeam_y + text_y - text_height);
00851 //printf("BC_TextBox::keypress_event 2 %d %d %d\n", ibeam_x, ibeam_y, new_letter);
00852 
00853 // Extend selection
00854                                 if(top_level->shift_down())
00855                                 {
00856 // Initialize highlighting
00857                                         if(highlight_letter1 == highlight_letter2)
00858                                         {
00859                                                 highlight_letter1 = new_letter;
00860                                                 highlight_letter2 = ibeam_letter;
00861                                         }
00862                                         else
00863 // Expand left highlight
00864                                         if(highlight_letter1 == ibeam_letter)
00865                                         {
00866                                                 highlight_letter1 = new_letter;
00867                                         }
00868                                         else
00869 // Shrink right highlight
00870                                         if(highlight_letter2 == ibeam_letter)
00871                                         {
00872                                                 highlight_letter2 = new_letter;
00873                                         }
00874                                 }
00875                                 else
00876                                         highlight_letter1 = highlight_letter2 = new_letter;
00877 
00878                                 if(highlight_letter1 > highlight_letter2)
00879                                 {
00880                                         int temp = highlight_letter1;
00881                                         highlight_letter1 = highlight_letter2;
00882                                         highlight_letter2 = temp;
00883                                 }
00884                                 ibeam_letter = new_letter;
00885 
00886                                 find_ibeam(1);
00887                                 if(keypress_draw) draw();
00888                         }
00889                         result = 1;
00890                         break;
00891 
00892                 case PGUP:
00893                         if(ibeam_letter > 0)
00894                         {
00895                                 int new_letter = get_cursor_letter(ibeam_x + text_x, 
00896                                         ibeam_y + text_y - get_h());
00897 
00898 // Extend selection
00899                                 if(top_level->shift_down())
00900                                 {
00901 // Initialize highlighting
00902                                         if(highlight_letter1 == highlight_letter2)
00903                                         {
00904                                                 highlight_letter1 = new_letter;
00905                                                 highlight_letter2 = ibeam_letter;
00906                                         }
00907                                         else
00908 // Expand left highlight
00909                                         if(highlight_letter1 == ibeam_letter)
00910                                         {
00911                                                 highlight_letter1 = new_letter;
00912                                         }
00913                                         else
00914 // Shrink right highlight
00915                                         if(highlight_letter2 == ibeam_letter)
00916                                         {
00917                                                 highlight_letter2 = new_letter;
00918                                         }
00919                                 }
00920                                 else
00921                                         highlight_letter1 = highlight_letter2 = new_letter;
00922 
00923                                 if(highlight_letter1 > highlight_letter2)
00924                                 {
00925                                         int temp = highlight_letter1;
00926                                         highlight_letter1 = highlight_letter2;
00927                                         highlight_letter2 = temp;
00928                                 }
00929                                 ibeam_letter = new_letter;
00930 
00931                                 find_ibeam(1);
00932                                 if(keypress_draw) draw();
00933                         }
00934                         result = 1;
00935                         break;
00936 
00937                 case DOWN:
00938 //                      if(ibeam_letter > 0)
00939                         {
00940 // Extend selection
00941                                 int new_letter = get_cursor_letter(ibeam_x + text_x, 
00942                                         ibeam_y + text_y + text_height);
00943 //printf("BC_TextBox::keypress_event 10 %d\n", new_letter);
00944 
00945                                 if(top_level->shift_down())
00946                                 {
00947 // Initialize highlighting
00948                                         if(highlight_letter1 == highlight_letter2)
00949                                         {
00950                                                 highlight_letter1 = new_letter;
00951                                                 highlight_letter2 = ibeam_letter;
00952                                         }
00953                                         else
00954 // Shrink left highlight
00955                                         if(highlight_letter1 == ibeam_letter)
00956                                         {
00957                                                 highlight_letter1 = new_letter;
00958                                         }
00959                                         else
00960 // Expand right highlight
00961                                         if(highlight_letter2 == ibeam_letter)
00962                                         {
00963                                                 highlight_letter2 = new_letter;
00964                                         }
00965                                 }
00966                                 else
00967                                         highlight_letter1 = highlight_letter2 = new_letter;
00968 
00969                                 if(highlight_letter1 > highlight_letter2)
00970                                 {
00971                                         int temp = highlight_letter1;
00972                                         highlight_letter1 = highlight_letter2;
00973                                         highlight_letter2 = temp;
00974                                 }
00975                                 ibeam_letter = new_letter;
00976 
00977                                 find_ibeam(1);
00978                                 if(keypress_draw) draw();
00979 
00980 //printf("BC_TextBox::keypress_event 20 %d\n", ibeam_letter);
00981                         }
00982                         result = 1;
00983                         break;
00984 
00985                 case PGDN:
00986                         {
00987 // Extend selection
00988                                 int new_letter = get_cursor_letter(ibeam_x + text_x, 
00989                                         ibeam_y + text_y + get_h());
00990 //printf("BC_TextBox::keypress_event 10 %d\n", new_letter);
00991 
00992                                 if(top_level->shift_down())
00993                                 {
00994 // Initialize highlighting
00995                                         if(highlight_letter1 == highlight_letter2)
00996                                         {
00997                                                 highlight_letter1 = new_letter;
00998                                                 highlight_letter2 = ibeam_letter;
00999                                         }
01000                                         else
01001 // Shrink left highlight
01002                                         if(highlight_letter1 == ibeam_letter)
01003                                         {
01004                                                 highlight_letter1 = new_letter;
01005                                         }
01006                                         else
01007 // Expand right highlight
01008                                         if(highlight_letter2 == ibeam_letter)
01009                                         {
01010                                                 highlight_letter2 = new_letter;
01011                                         }
01012                                 }
01013                                 else
01014                                         highlight_letter1 = highlight_letter2 = new_letter;
01015 
01016                                 if(highlight_letter1 > highlight_letter2)
01017                                 {
01018                                         int temp = highlight_letter1;
01019                                         highlight_letter1 = highlight_letter2;
01020                                         highlight_letter2 = temp;
01021                                 }
01022                                 ibeam_letter = new_letter;
01023 
01024                                 find_ibeam(1);
01025                                 if(keypress_draw) draw();
01026 
01027 //printf("BC_TextBox::keypress_event 20 %d\n", ibeam_letter);
01028                         }
01029                         result = 1;
01030                         break;
01031                 
01032                 case END:
01033                 {
01034                         int old_ibeam_letter = ibeam_letter;
01035 
01036                         while(ibeam_letter < text_len && text[ibeam_letter] != '\n')
01037                                 ibeam_letter++;
01038 
01039                         if(top_level->shift_down())
01040                         {
01041 // Begin selection
01042                                 if(highlight_letter1 == highlight_letter2)
01043                                 {
01044                                         highlight_letter2 = ibeam_letter;
01045                                         highlight_letter1 = old_ibeam_letter;
01046                                 }
01047                                 else
01048 // Shrink selection
01049                                 if(highlight_letter1 == old_ibeam_letter)
01050                                 {
01051                                         highlight_letter1 = highlight_letter2;
01052                                         highlight_letter2 = ibeam_letter;
01053                                 }
01054                                 else
01055 // Extend selection
01056                                 if(highlight_letter2 == old_ibeam_letter)
01057                                 {
01058                                         highlight_letter2 = ibeam_letter;
01059                                 }
01060                         }
01061                         else
01062                                 highlight_letter1 = highlight_letter2 = ibeam_letter;
01063 
01064                         find_ibeam(1);
01065                         if(keypress_draw) draw();
01066                         result = 1;
01067                         break;
01068                 }
01069 
01070                 case HOME:
01071                 {
01072                         int old_ibeam_letter = ibeam_letter;
01073 
01074                         while(ibeam_letter > 0 && text[ibeam_letter - 1] != '\n')
01075                                 ibeam_letter--;
01076 
01077                         if(top_level->shift_down())
01078                         {
01079 // Begin selection
01080                                 if(highlight_letter1 == highlight_letter2)
01081                                 {
01082                                         highlight_letter2 = old_ibeam_letter;
01083                                         highlight_letter1 = ibeam_letter;
01084                                 }
01085                                 else
01086 // Extend selection
01087                                 if(highlight_letter1 == old_ibeam_letter)
01088                                 {
01089                                         highlight_letter1 = ibeam_letter;
01090                                 }
01091                                 else
01092 // Shrink selection
01093                                 if(highlight_letter2 == old_ibeam_letter)
01094                                 {
01095                                         highlight_letter2 = highlight_letter1;
01096                                         highlight_letter1 = ibeam_letter;
01097                                 }
01098                         }
01099                         else
01100                                 highlight_letter1 = highlight_letter2 = ibeam_letter;
01101 
01102                         find_ibeam(1);
01103                         if(keypress_draw) draw();
01104                         result = 1;
01105                         break;
01106                 }
01107 
01108         case BACKSPACE:
01109                         if(highlight_letter1 == highlight_letter2)
01110                         {
01111                                 if(ibeam_letter > 0)
01112                                 {
01113                                         delete_selection(ibeam_letter - 1, ibeam_letter, text_len);
01114                                         ibeam_letter--;
01115                                 }
01116                         }
01117                         else
01118                         {
01119                                 delete_selection(highlight_letter1, highlight_letter2, text_len);
01120                                 highlight_letter2 = ibeam_letter = highlight_letter1;
01121                         }
01122 
01123                         find_ibeam(1);
01124                         if(keypress_draw) draw();
01125                         dispatch_event = 1;
01126                         result = 1;
01127                 break;
01128 
01129                 case DELETE:
01130                         if(highlight_letter1 == highlight_letter2)
01131                         {
01132                                 if(ibeam_letter < text_len)
01133                                 {
01134                                         delete_selection(ibeam_letter, ibeam_letter + 1, text_len);
01135                                 }
01136                         }
01137                         else
01138                         {
01139                                 delete_selection(highlight_letter1, highlight_letter2, text_len);
01140                                 highlight_letter2 = ibeam_letter = highlight_letter1;
01141                         }
01142                         
01143                         find_ibeam(1);
01144                         if(keypress_draw) draw();
01145                         dispatch_event = 1;
01146                         result = 1;
01147                         break;
01148 
01149 
01150 
01151                 default:
01152                         if(ctrl_down())
01153                         {
01154                                 if(get_keypress() == 'c' || get_keypress() == 'C')
01155                                 {
01156                                         if(highlight_letter1 != highlight_letter2)
01157                                         {
01158                                                 copy_selection(SECONDARY_SELECTION);
01159                                                 result = 1;
01160                                         }
01161                                 }
01162                                 else
01163