• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files

hvirtual/guicast/bctextbox.C

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