Ticket #511: CInputEnhancementsAndFixes.patch
File CInputEnhancementsAndFixes.patch, 23.2 KB (added by , 13 years ago) |
---|
-
binaries/data/config/default.cfg
129 129 hotkey.console.toggle = BackQuote, F9 ; Open/close console 130 130 hotkey.console.copy = "Ctrl+C" ; Copy from console to clipboard 131 131 hotkey.console.paste = "Ctrl+V" ; Paste clipboard to console 132 hotkey.console.cut = "Ctrl+X" ; Cut the selected text and copy it to the clipboard 132 133 133 134 ; > ENTITY SELECTION 134 135 hotkey.selection.add = Shift ; Add units to selection … … 186 187 ; > HOTKEYS ONLY 187 188 hotkey.chat = Return ; Toggle chat window 188 189 190 ; > GUI TEXTBOX HOTKEYS 191 hotkey.text.delete.word.left = "Ctrl+Backspace" ; Used in text input boxes to delete word to the left of cursor 192 hotkey.text.delete.word.right = "Ctrl+Del" ; Used in text input boxes to delete word to the right of cursor 193 hotkey.text.move.word.left = "Ctrl+LeftArrow" ; Move cursor to start of word to the left of cursor 194 hotkey.text.move.word.right = "Ctrl+RightArrow" ; Move cursor to start of word to the left of cursor 195 189 196 ; > PROFILER 190 197 hotkey.profile.toggle = "F11" ; Enable/disable real-time profiler 191 198 hotkey.profile.save = "Shift+F11" ; Save current profiler data to logs/profile.txt -
source/gui/CInput.cpp
34 34 #include "ps/CLogger.h" 35 35 #include "ps/Globals.h" 36 36 37 #include <sstream> 37 38 38 39 //------------------------------------------------------------------- 39 40 // Constructor / Destructor … … 70 71 { 71 72 ENSURE(m_iBufferPos != -1); 72 73 73 // Since the GUI framework doesn't handle to set settings74 // in Unicode (CStrW), we'll simply retrieve the actual75 // pointer and edit that.76 CStrW *pCaption = (CStrW*)m_Settings["caption"].m_pSetting;77 78 74 if (ev->ev.type == SDL_HOTKEYDOWN) 79 75 { 80 std::string hotkey = static_cast<const char*>(ev->ev.user.data1); 81 if (hotkey == "console.paste") 82 { 83 wchar_t* text = sys_clipboard_get(); 84 if (text) 85 { 86 if (m_iBufferPos == (int)pCaption->length()) 87 *pCaption += text; 88 else 89 *pCaption = pCaption->Left(m_iBufferPos) + text + 90 pCaption->Right((long) pCaption->length()-m_iBufferPos); 91 92 UpdateText(m_iBufferPos, m_iBufferPos, m_iBufferPos+1); 93 94 m_iBufferPos += (int)wcslen(text); 95 96 sys_clipboard_free(text); 97 } 98 99 return IN_HANDLED; 100 } 76 return(ManuallyHandleHotkeyEvent(ev)); 101 77 } 102 78 else if (ev->ev.type == SDL_KEYDOWN) 103 79 { 80 // Since the GUI framework doesn't handle to set settings 81 // in Unicode (CStrW), we'll simply retrieve the actual 82 // pointer and edit that. 83 CStrW *pCaption = (CStrW*)m_Settings["caption"].m_pSetting; 84 bool shiftKeyPressed = g_keys[SDLK_RSHIFT] || g_keys[SDLK_LSHIFT]; 85 104 86 int szChar = ev->ev.key.keysym.sym; 105 87 wchar_t cooked = (wchar_t)ev->ev.key.keysym.unicode; 106 88 107 89 switch (szChar) 108 90 { 109 case '\t':91 case SDLK_TAB: // '\t' 110 92 /* Auto Complete */ 111 93 // TODO Gee: (2004-09-07) What to do with tab? 112 94 break; 113 95 114 case '\b':115 m_WantedX=0. f;96 case SDLK_BACKSPACE: // '\b' 97 m_WantedX=0.0f; 116 98 117 99 if (SelectingText()) 118 100 DeleteCurSelection(); … … 120 102 { 121 103 m_iBufferPos_Tail = -1; 122 104 123 if (pCaption->empty() || 124 m_iBufferPos == 0)105 if (pCaption->empty() || m_iBufferPos == 0) 106 { 125 107 break; 126 127 if (m_iBufferPos == (int)pCaption->length()) 128 *pCaption = pCaption->Left( (long) pCaption->length()-1); 108 } 129 109 else 130 *pCaption = pCaption->Left( m_iBufferPos-1 ) + 131 pCaption->Right( (long) pCaption->length()-m_iBufferPos ); 110 { 111 if (m_iBufferPos == (int)pCaption->length()) 112 *pCaption = pCaption->Left( (long) pCaption->length()-1); 113 else 114 *pCaption = pCaption->Left( m_iBufferPos-1 ) + 115 pCaption->Right( (long) pCaption->length()-m_iBufferPos ); 132 116 133 --m_iBufferPos;117 --m_iBufferPos; 134 118 135 UpdateText(m_iBufferPos, m_iBufferPos+1, m_iBufferPos); 119 UpdateText(m_iBufferPos, m_iBufferPos+1, m_iBufferPos); 120 } 136 121 } 137 122 138 123 UpdateAutoScroll(); 139 124 break; 140 125 141 126 case SDLK_DELETE: 142 m_WantedX=0. f;127 m_WantedX=0.0f; 143 128 // If selection: 144 129 if (SelectingText()) 145 130 { … … 147 132 } 148 133 else 149 134 { 150 if (pCaption->empty() || 151 m_iBufferPos == (int)pCaption->length())135 if (pCaption->empty() || m_iBufferPos == (int)pCaption->length()) 136 { 152 137 break; 138 } 139 else 140 { 141 *pCaption = pCaption->Left( m_iBufferPos ) + 142 pCaption->Right( (long) pCaption->length()-(m_iBufferPos+1) ); 153 143 154 *pCaption = pCaption->Left( m_iBufferPos ) + 155 pCaption->Right( (long) pCaption->length()-(m_iBufferPos+1) ); 156 157 UpdateText(m_iBufferPos, m_iBufferPos+1, m_iBufferPos); 144 UpdateText(m_iBufferPos, m_iBufferPos+1, m_iBufferPos); 145 } 158 146 } 159 147 160 148 UpdateAutoScroll(); … … 162 150 163 151 case SDLK_HOME: 164 152 // If there's not a selection, we should create one now 165 if (! g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT])153 if (!shiftKeyPressed) 166 154 { 167 155 // Make sure a selection isn't created. 168 156 m_iBufferPos_Tail = -1; … … 174 162 } 175 163 176 164 m_iBufferPos = 0; 177 m_WantedX=0. f;165 m_WantedX=0.0f; 178 166 179 167 UpdateAutoScroll(); 180 168 break; 181 169 182 170 case SDLK_END: 183 171 // If there's not a selection, we should create one now 184 if (! g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT])172 if (!shiftKeyPressed) 185 173 { 186 174 // Make sure a selection isn't created. 187 175 m_iBufferPos_Tail = -1; … … 193 181 } 194 182 195 183 m_iBufferPos = (long) pCaption->length(); 196 m_WantedX=0. f;184 m_WantedX=0.0f; 197 185 198 186 UpdateAutoScroll(); 199 187 break; … … 221 209 222 210 **/ 223 211 case SDLK_LEFT: 224 // reset m_WantedX, very important225 212 m_WantedX=0.f; 226 213 227 if (g_keys[SDLK_RSHIFT] || g_keys[SDLK_LSHIFT] || 228 !SelectingText()) 214 if (shiftKeyPressed || !SelectingText()) 229 215 { 230 // If there's not a selection, we should create one now 231 if (!SelectingText() && !g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT]) 216 if (!shiftKeyPressed) 232 217 { 233 // Make sure a selection isn't created.234 218 m_iBufferPos_Tail = -1; 235 219 } 236 220 else if (!SelectingText()) 237 221 { 238 // Place tail at the current point:239 222 m_iBufferPos_Tail = m_iBufferPos; 240 223 } 241 224 242 if (m_iBufferPos )225 if (m_iBufferPos > 0) 243 226 --m_iBufferPos; 244 227 } 245 228 else … … 254 237 break; 255 238 256 239 case SDLK_RIGHT: 257 m_WantedX=0. f;240 m_WantedX=0.0f; 258 241 259 if (g_keys[SDLK_RSHIFT] || g_keys[SDLK_LSHIFT] || 260 !SelectingText()) 242 if (shiftKeyPressed || !SelectingText()) 261 243 { 262 // If there's not a selection, we should create one now 263 if (!SelectingText() && !g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT]) 244 if (!shiftKeyPressed) 264 245 { 265 // Make sure a selection isn't created.266 246 m_iBufferPos_Tail = -1; 267 247 } 268 248 else if (!SelectingText()) 269 249 { 270 // Place tail at the current point:271 250 m_iBufferPos_Tail = m_iBufferPos; 272 251 } 273 252 274 275 if (m_iBufferPos != (int)pCaption->length()) 253 if (m_iBufferPos < (int)pCaption->length()) 276 254 ++m_iBufferPos; 277 255 } 278 256 else … … 308 286 **/ 309 287 case SDLK_UP: 310 288 { 311 // If there's not a selection, we should create one now 312 if (!g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT]) 289 if (!shiftKeyPressed) 313 290 { 314 // Make sure a selection isn't created.315 291 m_iBufferPos_Tail = -1; 316 292 } 317 293 else if (!SelectingText()) 318 294 { 319 // Place tail at the current point:320 295 m_iBufferPos_Tail = m_iBufferPos; 321 296 } 322 297 … … 356 331 357 332 case SDLK_DOWN: 358 333 { 359 // If there's not a selection, we should create one now 360 if (!g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT]) 334 if (!shiftKeyPressed) 361 335 { 362 // Make sure a selection isn't created.363 336 m_iBufferPos_Tail = -1; 364 337 } 365 338 else if (!SelectingText()) 366 339 { 367 // Place tail at the current point:368 340 m_iBufferPos_Tail = m_iBufferPos; 369 341 } 370 342 … … 428 400 } 429 401 default: //Insert a character 430 402 { 431 // If there's a selection, delete if first.432 403 if (cooked == 0) 433 404 return IN_PASS; // Important, because we didn't use any key 434 405 … … 438 409 if (max_length != 0 && (int)pCaption->length() >= max_length) 439 410 break; 440 411 441 m_WantedX=0. f;412 m_WantedX=0.0f; 442 413 443 414 if (SelectingText()) 444 415 DeleteCurSelection(); … … 465 436 return IN_PASS; 466 437 } 467 438 439 440 InReaction CInput::ManuallyHandleHotkeyEvent(const SDL_Event_* ev) 441 { 442 CStrW *pCaption = (CStrW*)m_Settings["caption"].m_pSetting; 443 bool shiftKeyPressed = g_keys[SDLK_RSHIFT] || g_keys[SDLK_LSHIFT]; 444 445 std::string hotkey = static_cast<const char*>(ev->ev.user.data1); 446 if (hotkey == "console.paste") 447 { 448 m_WantedX=0.0f; 449 450 wchar_t* text = sys_clipboard_get(); 451 if (text) 452 { 453 if (m_iBufferPos == (int)pCaption->length()) 454 *pCaption += text; 455 else 456 *pCaption = pCaption->Left(m_iBufferPos) + text + 457 pCaption->Right((long) pCaption->length()-m_iBufferPos); 458 459 UpdateText(m_iBufferPos, m_iBufferPos, m_iBufferPos+1); 460 461 m_iBufferPos += (int)wcslen(text); 462 463 sys_clipboard_free(text); 464 } 465 466 return IN_HANDLED; 467 } 468 else if (hotkey == "console.copy" || hotkey == "console.cut") 469 { 470 m_WantedX=0.0f; 471 472 if (SelectingText()) 473 { 474 int virtualFrom; 475 int virtualTo; 476 477 if (m_iBufferPos_Tail >= m_iBufferPos) 478 { 479 virtualFrom = m_iBufferPos; 480 virtualTo = m_iBufferPos_Tail; 481 } 482 else 483 { 484 virtualFrom = m_iBufferPos_Tail; 485 virtualTo = m_iBufferPos; 486 } 487 488 CStrW text = (pCaption->Left(virtualTo)).Right(virtualTo - virtualFrom); 489 490 sys_clipboard_set(&text[0]); 491 492 if (hotkey == "console.cut") 493 { 494 DeleteCurSelection(); 495 } 496 } 497 498 return IN_HANDLED; 499 } 500 else if (hotkey == "text.delete.word.left") 501 { 502 m_WantedX=0.0f; 503 504 if (SelectingText()) 505 { 506 DeleteCurSelection(); 507 } 508 if (!pCaption->empty() && !m_iBufferPos == 0) 509 { 510 m_iBufferPos_Tail = m_iBufferPos; 511 CStrW searchString = pCaption->Left( m_iBufferPos ); 512 513 // If we are starting in whitespace, adjust position until we get a non whitespace 514 while (m_iBufferPos > 0) 515 { 516 if (!iswspace(searchString[m_iBufferPos - 1])) 517 break; 518 519 m_iBufferPos--; 520 } 521 522 // If we end up on a puctuation char we just delete it (treat punct like a word) 523 if (iswpunct(searchString[m_iBufferPos - 1])) 524 m_iBufferPos--; 525 else 526 { 527 // Now we are on a non white space character, adjust position to char after next whitespace char is found 528 while (m_iBufferPos > 0) 529 { 530 if (iswspace(searchString[m_iBufferPos - 1]) || iswpunct(searchString[m_iBufferPos - 1])) 531 break; 532 533 m_iBufferPos--; 534 } 535 } 536 537 DeleteCurSelection(); 538 } 539 return IN_HANDLED; 540 } 541 else if (hotkey == "text.delete.word.right") 542 { 543 m_WantedX=0.0f; 544 545 if (SelectingText()) 546 { 547 DeleteCurSelection(); 548 } 549 if (!pCaption->empty() && m_iBufferPos < (int)pCaption->length()) 550 { 551 // Delete the word to the right of the cursor 552 m_iBufferPos_Tail = m_iBufferPos; 553 554 // Delete chars to the right unit we hit whitespace 555 while (++m_iBufferPos < (int)pCaption->length()) 556 { 557 if (iswspace((*pCaption)[m_iBufferPos]) || iswpunct((*pCaption)[m_iBufferPos])) 558 break; 559 } 560 561 // Eliminate any whitespace behind the word we just deleted 562 while (m_iBufferPos < (int)pCaption->length()) 563 { 564 if (!iswspace((*pCaption)[m_iBufferPos])) 565 break; 566 567 m_iBufferPos++; 568 } 569 DeleteCurSelection(); 570 } 571 return IN_HANDLED; 572 } 573 else if (hotkey == "text.move.word.left") 574 { 575 m_WantedX=0.0f; 576 577 if (shiftKeyPressed || !SelectingText()) 578 { 579 if (!shiftKeyPressed) 580 { 581 m_iBufferPos_Tail = -1; 582 } 583 else if (!SelectingText()) 584 { 585 m_iBufferPos_Tail = m_iBufferPos; 586 } 587 588 if (!pCaption->empty() && !m_iBufferPos == 0) 589 { 590 CStrW searchString = pCaption->Left( m_iBufferPos ); 591 592 // If we are starting in whitespace, adjust position until we get a non whitespace 593 while (m_iBufferPos > 0) 594 { 595 if (!iswspace(searchString[m_iBufferPos - 1])) 596 break; 597 598 m_iBufferPos--; 599 } 600 601 // If we end up on a puctuation char we just select it (treat punct like a word) 602 if (iswpunct(searchString[m_iBufferPos - 1])) 603 m_iBufferPos--; 604 else 605 { 606 // Now we are on a non white space character, adjust position to char after next whitespace char is found 607 while (m_iBufferPos > 0) 608 { 609 if (iswspace(searchString[m_iBufferPos - 1]) || iswpunct(searchString[m_iBufferPos - 1])) 610 break; 611 612 m_iBufferPos--; 613 } 614 } 615 } 616 } 617 else 618 { 619 if (m_iBufferPos_Tail < m_iBufferPos) 620 m_iBufferPos = m_iBufferPos_Tail; 621 622 m_iBufferPos_Tail = -1; 623 } 624 625 UpdateAutoScroll(); 626 627 return IN_HANDLED; 628 } 629 else if (hotkey == "text.move.word.right") 630 { 631 m_WantedX=0.0f; 632 633 if (shiftKeyPressed || !SelectingText()) 634 { 635 if (!shiftKeyPressed) 636 { 637 m_iBufferPos_Tail = -1; 638 } 639 else if (!SelectingText()) 640 { 641 m_iBufferPos_Tail = m_iBufferPos; 642 } 643 644 if (!pCaption->empty() && m_iBufferPos < (int)pCaption->length()) 645 { 646 CStrW searchString = *pCaption; 647 648 // Select chars to the right until we hit whitespace 649 while (++m_iBufferPos < (int)pCaption->length()) 650 { 651 if (iswspace((*pCaption)[m_iBufferPos]) || iswpunct((*pCaption)[m_iBufferPos])) 652 break; 653 } 654 655 // Also select any whitespace following the word we just selected 656 while (m_iBufferPos < (int)pCaption->length()) 657 { 658 if (!iswspace((*pCaption)[m_iBufferPos])) 659 break; 660 661 m_iBufferPos++; 662 } 663 } 664 } 665 else 666 { 667 if (m_iBufferPos_Tail > m_iBufferPos) 668 m_iBufferPos = m_iBufferPos_Tail; 669 670 m_iBufferPos_Tail = -1; 671 } 672 673 UpdateAutoScroll(); 674 675 return IN_HANDLED; 676 } 677 else 678 { 679 return IN_PASS; 680 } 681 } 682 683 468 684 void CInput::HandleMessage(SGUIMessage &Message) 469 685 { 470 686 // TODO Gee: … … 560 776 561 777 UpdateAutoScroll(); 562 778 563 // If we immediately release the button it will just be seen as a click779 // If we immediately release the button it will just be seen as a click 564 780 // for the user though. 565 781 566 782 }break; 567 783 784 case GUIM_MOUSE_DBLCLICK_LEFT: 785 { 786 CStrW *pCaption = (CStrW*)m_Settings["caption"].m_pSetting; 787 m_iBufferPos = m_iBufferPos_Tail = GetMouseHoveringTextPosition(); 788 789 // See if we are clicking over whitespace 790 if (iswspace((*pCaption)[m_iBufferPos])) 791 { 792 // see if we are in a section of whitespace greater than one character 793 if ((m_iBufferPos + 1 < (int) pCaption->length() && iswspace((*pCaption)[m_iBufferPos + 1])) || 794 (m_iBufferPos - 1 > 0 && iswspace((*pCaption)[m_iBufferPos - 1]))) 795 { 796 // 797 // We are clicking in an area with more than one whitespace character 798 // so we select both the word to the left and then the word to the right 799 // 800 // [1] First the left 801 // skip the whitespace 802 while (m_iBufferPos > 0) 803 { 804 if (!iswspace((*pCaption)[m_iBufferPos - 1])) 805 break; 806 807 m_iBufferPos--; 808 } 809 // now go until we hit white space or punctuation 810 while (m_iBufferPos > 0) 811 { 812 if (iswspace((*pCaption)[m_iBufferPos - 1])) 813 break; 814 815 m_iBufferPos--; 816 817 if (iswpunct((*pCaption)[m_iBufferPos])) 818 break; 819 } 820 821 // [2] Then the right 822 // go right until we are not in whitespace 823 while (++m_iBufferPos_Tail < (int)pCaption->length()) 824 { 825 if (!iswspace((*pCaption)[m_iBufferPos_Tail])) 826 break; 827 } 828 // now go to the right until we hit whitespace or punctuation 829 while (++m_iBufferPos_Tail < (int)pCaption->length()) 830 { 831 if (iswspace((*pCaption)[m_iBufferPos_Tail]) || iswpunct((*pCaption)[m_iBufferPos_Tail])) 832 break; 833 } 834 } 835 else 836 { 837 // single whitespace so select word to the right 838 while (++m_iBufferPos_Tail < (int)pCaption->length()) 839 { 840 if (!iswspace((*pCaption)[m_iBufferPos_Tail])) 841 break; 842 } 843 844 // Don't include the leading whitespace 845 m_iBufferPos = m_iBufferPos_Tail; 846 847 // now go to the right until we hit whitespace or punctuation 848 while (++m_iBufferPos_Tail < (int)pCaption->length()) 849 { 850 if (iswspace((*pCaption)[m_iBufferPos_Tail]) || iswpunct((*pCaption)[m_iBufferPos_Tail])) 851 break; 852 } 853 } 854 } 855 else 856 { 857 // clicked on non-whitespace so select current word 858 // go until we hit white space or punctuation 859 while (m_iBufferPos > 0) 860 { 861 if (iswspace((*pCaption)[m_iBufferPos - 1])) 862 break; 863 864 m_iBufferPos--; 865 866 if (iswpunct((*pCaption)[m_iBufferPos])) 867 break; 868 } 869 // go to the right until we hit whitespace or punctuation 870 while (++m_iBufferPos_Tail < (int)pCaption->length()) 871 { 872 if (iswspace((*pCaption)[m_iBufferPos_Tail]) || iswpunct((*pCaption)[m_iBufferPos_Tail])) 873 break; 874 } 875 } 876 } 877 break; 878 568 879 case GUIM_MOUSE_RELEASE_LEFT: 569 880 if (m_SelectingText) 570 881 { … … 1428 1739 return 0; 1429 1740 1430 1741 // Return position 1431 int RetPosition;1742 int retPosition; 1432 1743 1433 1744 float buffer_zone; 1434 1745 bool multiline; … … 1493 1804 } 1494 1805 1495 1806 //m_iBufferPos = m_CharacterPositions.get.m_ListStart; 1496 RetPosition = current->m_ListStart;1807 retPosition = current->m_ListStart; 1497 1808 1498 1809 // Okay, now loop through the glyphs to find the appropriate X position 1499 1810 float dummy; 1500 RetPosition += GetXTextPosition(current, mouse.x, dummy);1811 retPosition += GetXTextPosition(current, mouse.x, dummy); 1501 1812 1502 return RetPosition;1813 return retPosition; 1503 1814 } 1504 1815 1505 1816 // Does not process horizontal scrolling, 'x' must be modified before inputted. 1506 1817 int CInput::GetXTextPosition(const std::list<SRow>::iterator ¤t, const float &x, float &wanted) 1507 1818 { 1508 int Ret=0; 1509 1819 int ret=0; 1510 1820 float previous=0.f; 1511 1821 int i=0; 1512 1822 … … 1517 1827 if (*it >= x) 1518 1828 { 1519 1829 if (x - previous >= *it - x) 1520 Ret += i+1;1830 ret += i+1; 1521 1831 else 1522 Ret += i;1832 ret += i; 1523 1833 1524 1834 break; 1525 1835 } … … 1529 1839 // character of that line. 1530 1840 if (i == (int)current->m_ListOfX.size()) 1531 1841 { 1532 Ret += i;1842 ret += i; 1533 1843 wanted = x; 1534 1844 } 1535 1845 else wanted = 0.f; 1536 1846 1537 return Ret;1847 return ret; 1538 1848 } 1539 1849 1540 1850 void CInput::DeleteCurSelection() 1541 1851 { 1542 1852 CStrW *pCaption = (CStrW*)m_Settings["caption"].m_pSetting; 1543 1853 1544 int VirtualFrom, VirtualTo; 1854 int virtualFrom; 1855 int virtualTo; 1545 1856 1546 1857 if (m_iBufferPos_Tail >= m_iBufferPos) 1547 1858 { 1548 VirtualFrom = m_iBufferPos;1549 VirtualTo = m_iBufferPos_Tail;1859 virtualFrom = m_iBufferPos; 1860 virtualTo = m_iBufferPos_Tail; 1550 1861 } 1551 1862 else 1552 1863 { 1553 VirtualFrom = m_iBufferPos_Tail;1554 VirtualTo = m_iBufferPos;1864 virtualFrom = m_iBufferPos_Tail; 1865 virtualTo = m_iBufferPos; 1555 1866 } 1556 1867 1557 *pCaption = pCaption->Left( VirtualFrom ) +1558 pCaption->Right( (long) pCaption->length() -(VirtualTo) );1868 *pCaption = pCaption->Left( virtualFrom ) + 1869 pCaption->Right( (long) pCaption->length() - (virtualTo) ); 1559 1870 1560 UpdateText( VirtualFrom, VirtualTo, VirtualFrom);1871 UpdateText(virtualFrom, virtualTo, virtualFrom); 1561 1872 1562 1873 // Remove selection 1563 1874 m_iBufferPos_Tail = -1; 1564 m_iBufferPos = VirtualFrom;1875 m_iBufferPos = virtualFrom; 1565 1876 } 1566 1877 1567 1878 bool CInput::SelectingText() const -
source/gui/CInput.h
97 97 virtual InReaction ManuallyHandleEvent(const SDL_Event_* ev); 98 98 99 99 /** 100 * Handle hotkey events (MannuallHandleEvent call this for Hotkeys) 101 */ 102 virtual InReaction ManuallyHandleHotkeyEvent(const SDL_Event_* ev); 103 104 /** 100 105 * @see IGUIObject#UpdateCachedSize() 101 106 */ 102 107 virtual void UpdateCachedSize(); -
source/lib/sysdep/os/win/wclipboard.cpp
30 30 static Status SetClipboardText(const wchar_t* text, HGLOBAL* hMem) 31 31 { 32 32 const size_t numChars = wcslen(text); 33 *hMem = GlobalAlloc(G MEM_MOVEABLE, (numChars+1) * sizeof(wchar_t));33 *hMem = GlobalAlloc(GHND | GMEM_SHARE, (numChars + 1) * sizeof(wchar_t)); 34 34 if(!*hMem) 35 35 WARN_RETURN(ERR::NO_MEM); 36 36 … … 50 50 // "copy" text into the clipboard. replaces previous contents. 51 51 Status sys_clipboard_set(const wchar_t* text) 52 52 { 53 // 53 54 // note: MSDN claims that the window handle must not be 0; 54 55 // that does actually work on WinXP, but we'll play it safe. 55 if(!OpenClipboard(wutil_AppWindow())) 56 // 57 // Update (6/22/2011): 58 // ------------------------------------------------- 59 // DOESNT WORK --> HWND hWnd = wutil_AppWindow(); 60 // ------------------------------------------------- 61 // 62 // Using the above handle would allow you to open the clipboard 63 // but then upon trying to read from clipboard you would always 64 // get the error "The Handle Is Invalid" when calling GlobalLock 65 // on the clipboard memory handle. Strangely enough you could 66 // copy and paste between other applications, but not within 67 // this application. 68 // 69 // hWnd = NULL does work. 70 // 71 // From MSDN: A handle to the window to be associated with the 72 // open clipboard. If this parameter is NULL, the open clipboard 73 // is associated with the current task. 74 // 75 // This works with text, but may need to revisited if we want to 76 // cut and paste other things like graphics other digital assets. 77 // In that case we may need to add support to the AppWindow for 78 // processing WM_RENDERFORMAT and WM_RENDERALLFORMATS it has to 79 // do with some lazy update logic in the clipboard. 80 // 81 HWND hWnd = NULL; 82 if(!OpenClipboard(hWnd)) 56 83 WARN_RETURN(ERR::FAIL); 57 84 EmptyClipboard(); 58 85 … … 65 92 // freed until after CloseClipboard. however, GlobalFree still fails 66 93 // after the successful completion of both. we'll leave it in to avoid 67 94 // memory leaks, but ignore its return value. 95 // 96 // Update (6/22/2011): 97 // This is working fine now, GlobalFree is returning null indicating 98 // that it was successful. I will leave the message for historic and 99 // debugging purposes since the clipboard is a bit temperamental. 68 100 (void)GlobalFree(hMem); 69 101 70 102 return ret; … … 74 106 static wchar_t* CopyClipboardContents() 75 107 { 76 108 // Windows NT/2000+ auto convert UNICODETEXT <-> TEXT 109 if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) 110 return 0; 111 77 112 HGLOBAL hMem = GetClipboardData(CF_UNICODETEXT); 78 113 if(!hMem) 79 114 return 0; … … 91 126 return text; 92 127 } 93 128 94 // allow "pasting" from clipboard. returns the current contents if they129 // Allow "pasting" from clipboard. returns the current contents if they 95 130 // can be represented as text, otherwise 0. 96 // when it is no longer needed, the returned pointer must be freed via131 // When it is no longer needed, the returned pointer must be freed via 97 132 // sys_clipboard_free. (NB: not necessary if zero, but doesn't hurt) 98 133 wchar_t* sys_clipboard_get() 99 134 { 100 135 if(!OpenClipboard(wutil_AppWindow())) 101 136 return 0; 137 102 138 wchar_t* const ret = CopyClipboardContents(); 103 139 CloseClipboard(); 140 104 141 return ret; 105 142 } 106 143 107 144 108 // frees memory used by <copy>, which must have been returned by145 // Frees memory used by <copy>, which must have been returned by 109 146 // sys_clipboard_get. see note above. 110 147 Status sys_clipboard_free(wchar_t* text) 111 148 {