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
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
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
00171 int text_len = strlen(text);
00172
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
00289
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
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
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
00344
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
00365 set_font(font);
00366 text_len = strlen(text);
00367
00368
00369 for(i = 0, k = text_y; i < text_len && k < get_h(); k += text_height)
00370 {
00371
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
00382
00383 if(k > -text_height + top_margin && k < get_h() - bottom_margin)
00384 {
00385
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
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
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
00429 if(need_ibeam)
00430 {
00431 ibeam_x = 0;
00432 ibeam_y = 0;
00433 }
00434
00435
00436
00437 if (active)
00438 draw_cursor();
00439
00440
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
00638
00639
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
00654 (top_level->get_keypress() > 30 && top_level->get_keypress() <= 255))
00655 {
00656
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
00701
00702
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
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
00747 if(!ctrl_down())
00748 {
00749 ibeam_letter--;
00750 }
00751 else
00752
00753 {
00754 ibeam_letter--;
00755 while(ibeam_letter > 0 && isalnum(text[ibeam_letter - 1]))
00756 ibeam_letter--;
00757 }
00758
00759
00760
00761 if(top_level->shift_down())
00762 {
00763
00764 if(highlight_letter1 == highlight_letter2)
00765 {
00766 highlight_letter1 = ibeam_letter;
00767 highlight_letter2 = old_ibeam_letter;
00768 }
00769 else
00770
00771 if(highlight_letter1 == old_ibeam_letter)
00772 {
00773 highlight_letter1 = ibeam_letter;
00774 }
00775 else
00776
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
00799 if(!ctrl_down())
00800 {
00801 ibeam_letter++;
00802 }
00803 else
00804
00805 {
00806 while(ibeam_letter < text_len && isalnum(text[ibeam_letter++]))
00807 ;
00808 }
00809
00810
00811
00812
00813 if(top_level->shift_down())
00814 {
00815
00816 if(highlight_letter1 == highlight_letter2)
00817 {
00818 highlight_letter1 = old_ibeam_letter;
00819 highlight_letter2 = ibeam_letter;
00820 }
00821 else
00822
00823 if(highlight_letter1 == old_ibeam_letter)
00824 {
00825 highlight_letter1 = ibeam_letter;
00826 }
00827 else
00828
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
00849 int new_letter = get_cursor_letter(ibeam_x + text_x,
00850 ibeam_y + text_y - text_height);
00851
00852
00853
00854 if(top_level->shift_down())
00855 {
00856
00857 if(highlight_letter1 == highlight_letter2)
00858 {
00859 highlight_letter1 = new_letter;
00860 highlight_letter2 = ibeam_letter;
00861 }
00862 else
00863
00864 if(highlight_letter1 == ibeam_letter)
00865 {
00866 highlight_letter1 = new_letter;
00867 }
00868 else
00869
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
00899 if(top_level->shift_down())
00900 {
00901
00902 if(highlight_letter1 == highlight_letter2)
00903 {
00904 highlight_letter1 = new_letter;
00905 highlight_letter2 = ibeam_letter;
00906 }
00907 else
00908
00909 if(highlight_letter1 == ibeam_letter)
00910 {
00911 highlight_letter1 = new_letter;
00912 }
00913 else
00914
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
00939 {
00940
00941 int new_letter = get_cursor_letter(ibeam_x + text_x,
00942 ibeam_y + text_y + text_height);
00943
00944
00945 if(top_level->shift_down())
00946 {
00947
00948 if(highlight_letter1 == highlight_letter2)
00949 {
00950 highlight_letter1 = new_letter;
00951 highlight_letter2 = ibeam_letter;
00952 }
00953 else
00954
00955 if(highlight_letter1 == ibeam_letter)
00956 {
00957 highlight_letter1 = new_letter;
00958 }
00959 else
00960
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
00981 }
00982 result = 1;
00983 break;
00984
00985 case PGDN:
00986 {
00987
00988 int new_letter = get_cursor_letter(ibeam_x + text_x,
00989 ibeam_y + text_y + get_h());
00990
00991
00992 if(top_level->shift_down())
00993 {
00994
00995 if(highlight_letter1 == highlight_letter2)
00996 {
00997 highlight_letter1 = new_letter;
00998 highlight_letter2 = ibeam_letter;
00999 }
01000 else
01001
01002 if(highlight_letter1 == ibeam_letter)
01003 {
01004 highlight_letter1 = new_letter;
01005 }
01006 else
01007
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
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
01042 if(highlight_letter1 == highlight_letter2)
01043 {
01044 highlight_letter2 = ibeam_letter;
01045 highlight_letter1 = old_ibeam_letter;
01046 }
01047 else
01048
01049 if(highlight_letter1 == old_ibeam_letter)
01050 {
01051 highlight_letter1 = highlight_letter2;
01052 highlight_letter2 = ibeam_letter;
01053 }
01054 else
01055
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
01080 if(highlight_letter1 == highlight_letter2)
01081 {
01082 highlight_letter2 = old_ibeam_letter;
01083 highlight_letter1 = ibeam_letter;
01084 }
01085 else
01086
01087 if(highlight_letter1 == old_ibeam_letter)
01088 {
01089 highlight_letter1 = ibeam_letter;
01090 }
01091 else
01092
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