Ticket #1767: 1767.5.diff
File 1767.5.diff, 15.3 KB (added by , 9 years ago) |
---|
-
binaries/data/mods/public/gui/common/functions_utility.js
240 240 // Limit the length to 20 characters 241 241 return sanitizedName.substr(0,20); 242 242 } 243 244 function tryAutoComplete(text, autoCompleteList) 245 { 246 if (text.length == 0) 247 return text; 248 249 var wordSplit = text.split(/\s/g); 250 251 if (!wordSplit.length) 252 return text; 253 254 var lastWord = wordSplit.pop(); 255 if (!lastWord.length) 256 return text; 257 258 for (var wordAutoCompletion of autoCompleteList) 259 { 260 if (wordAutoCompletion.toLowerCase().indexOf(lastWord.toLowerCase()) == 0) 261 { 262 text = wordSplit.join(" ") 263 if (text.length > 0) 264 text += " "; 265 266 text += wordAutoCompletion; 267 break; 268 } 269 } 270 return text; 271 } 272 273 //listPlayer parameter must be an array and every object with name property 274 function autoCompleteNick(guiName, listPlayer) 275 { 276 var input = Engine.GetGUIObjectByName(guiName); 277 var text = input.caption; 278 if (!text.length) 279 return; 280 281 var autoCompleteList = []; 282 for (var player of listPlayer) 283 autoCompleteList.push(player.name); 284 285 var bufferPosition = input.buffer_position; 286 var textTillBufferPosition = text.substring(0, bufferPosition); 287 var newText = tryAutoComplete(textTillBufferPosition, autoCompleteList); 288 input.caption = newText + text.substring(bufferPosition); 289 input.buffer_position = bufferPosition + (newText.length - textTillBufferPosition.length); 290 } 291 No newline at end of file -
binaries/data/mods/public/gui/lobby/lobby.js
752 752 } 753 753 } 754 754 755 function completeNick()756 {757 var input = Engine.GetGUIObjectByName("chatInput");758 var text = escapeText(input.caption);759 if (text.length)760 {761 var matched = false;762 for each (var playerObj in Engine.GetPlayerList())763 {764 var player = playerObj.name;765 var breaks = text.match(/(\s+)/g) || [];766 text.split(/\s+/g).reduceRight(function (wordsSoFar, word, index)767 {768 if (matched)769 return null;770 var matchCandidate = word + (breaks[index - 1] || "") + wordsSoFar;771 if (player.toUpperCase().indexOf(matchCandidate.toUpperCase().trim()) == 0)772 {773 input.caption = text.replace(matchCandidate.trim(), player);774 matched = true;775 }776 return matchCandidate;777 }, "");778 if (matched)779 break;780 }781 }782 }783 784 755 function isValidNick(nick) 785 756 { 786 757 var prohibitedNicks = ["system"]; -
binaries/data/mods/public/gui/lobby/lobby.xml
231 231 <object name="chatText" size="0 0 100% 94%" type="text" style="ChatPanel" font="sans-13"/> 232 232 <object name="chatInput" size="0 94% 100% 100%" type="input" style="ModernInput" font="sans-13"> 233 233 <action on="Press">submitChatInput();</action> 234 <action on="Tab"> completeNick();</action>234 <action on="Tab">autoCompleteNick("chatInput", Engine.GetPlayerList());</action> 235 235 </object> 236 236 </object> 237 237 </object> -
binaries/data/mods/public/gui/session/messages.js
613 614 msg.hide = true; 614 615 recurse = true; 615 616 break; 617 case "/allies": 618 var player = g_Players[Engine.GetPlayerID()]; 619 620 if (player && player.isAlly[sender]) 621 msg.context = translate("Ally"); 622 else 623 msg.hide = true; 624 625 recurse = true; 626 break; 616 627 case "/enemy": 617 628 // Check if we are in a team. 618 629 if (g_Players[Engine.GetPlayerID()] && g_Players[Engine.GetPlayerID()].team != -1) -
source/gui/CInput.cpp
1 /* Copyright (C) 201 4Wildfire Games.1 /* Copyright (C) 2015 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 42 42 43 43 extern int g_yres; 44 44 45 #define UpdateBufferPositionSetting int* bufferPos = (int*)m_Settings["buffer_position"].m_pSetting; *bufferPos = m_iBufferPos; 46 45 47 //------------------------------------------------------------------- 46 48 // Constructor / Destructor 47 49 //------------------------------------------------------------------- … … 52 54 { 53 55 AddSetting(GUIST_float, "buffer_zone"); 54 56 AddSetting(GUIST_CStrW, "caption"); 57 AddSetting(GUIST_int, "buffer_position"); 55 58 AddSetting(GUIST_int, "cell_id"); 56 59 AddSetting(GUIST_CStrW, "font"); 57 60 AddSetting(GUIST_CStrW, "mask_char"); … … 84 87 CStrW *pCaption = (CStrW*)m_Settings["caption"].m_pSetting; 85 88 pCaption->erase(m_iInsertPos, m_iComposedLength); 86 89 m_iBufferPos = m_iInsertPos; 90 UpdateBufferPositionSetting; 87 91 m_iComposedLength = 0; 88 92 m_iComposedPos = 0; 89 93 } … … 124 128 pCaption->insert(m_iBufferPos, text); 125 129 126 130 UpdateText(m_iBufferPos, m_iBufferPos, m_iBufferPos+1); 127 131 128 132 m_iBufferPos += text.length(); 133 UpdateBufferPositionSetting; 129 134 m_iBufferPos_Tail = -1; 130 135 131 136 UpdateAutoScroll(); 132 137 133 138 return IN_HANDLED; … … 140 145 const char *rawText = ev->ev.edit.text; 141 146 int rawLength = strlen(rawText); 142 147 std::wstring wtext = wstring_from_utf8(rawText); 143 148 144 149 debug_printf(L"SDL_TEXTEDITING: text=%hs, start=%d, length=%d\n", rawText, ev->ev.edit.start, ev->ev.edit.length); 145 150 m_WantedX=0.0f; 146 151 … … 166 171 m_iComposedLength = wtext.length(); 167 172 m_iComposedPos = ev->ev.edit.start < m_iComposedLength ? ev->ev.edit.start : m_iComposedLength; 168 173 m_iBufferPos = m_iInsertPos + m_iComposedPos; 169 174 170 175 // TODO: composed text selection - what does ev.edit.length do? 171 176 m_iBufferPos_Tail = -1; 172 177 } 173 178 179 UpdateBufferPositionSetting; 174 180 UpdateText(m_iBufferPos, m_iBufferPos, m_iBufferPos+1); 175 181 176 182 UpdateAutoScroll(); … … 228 234 pCaption->Right( (long) pCaption->length()-m_iBufferPos ); 229 235 230 236 --m_iBufferPos; 231 237 232 238 UpdateText(m_iBufferPos, m_iBufferPos+1, m_iBufferPos); 233 239 } 234 240 } … … 372 378 m_iBufferPos = m_iBufferPos_Tail; 373 379 374 380 m_iBufferPos_Tail = -1; 375 } 381 } 376 382 377 383 UpdateAutoScroll(); 378 384 break; … … 414 420 if (m_iBufferPos >= current->m_ListStart && 415 421 m_iBufferPos <= current->m_ListStart+(int)current->m_ListOfX.size()) 416 422 break; 417 423 418 424 ++current; 419 425 } 420 426 … … 437 443 m_iBufferPos = current->m_ListStart + GetXTextPosition(current, pos_x, m_WantedX); 438 444 } 439 445 // else we can't move up 440 446 441 447 UpdateAutoScroll(); 442 448 } 443 449 break; … … 459 465 if (m_iBufferPos >= current->m_ListStart && 460 466 m_iBufferPos <= current->m_ListStart+(int)current->m_ListOfX.size()) 461 467 break; 462 468 463 469 ++current; 464 470 } 465 471 … … 551 557 break; 552 558 } 553 559 560 UpdateBufferPositionSetting; 554 561 return IN_HANDLED; 555 562 } 556 563 … … 585 592 UpdateText(m_iBufferPos, m_iBufferPos, m_iBufferPos+1); 586 593 587 594 m_iBufferPos += (int)wcslen(text); 595 UpdateBufferPositionSetting; 588 596 589 597 sys_clipboard_free(text); 590 598 } … … 644 652 645 653 m_iBufferPos--; 646 654 } 647 655 648 656 // If we end up on a puctuation char we just delete it (treat punct like a word) 649 657 if (iswpunct(searchString[m_iBufferPos - 1])) 650 658 m_iBufferPos--; … … 660 668 } 661 669 } 662 670 671 UpdateBufferPositionSetting; 663 672 DeleteCurSelection(); 664 673 } 665 674 return IN_HANDLED; … … 692 701 693 702 m_iBufferPos++; 694 703 } 704 UpdateBufferPositionSetting; 695 705 DeleteCurSelection(); 696 706 } 697 return IN_HANDLED; 707 return IN_HANDLED; 698 708 } 699 709 else if (hotkey == "text.move.left") 700 710 { 701 711 m_WantedX=0.0f; 702 712 703 713 if (shiftKeyPressed || !SelectingText()) 704 714 { 705 715 if (!shiftKeyPressed) … … 723 733 724 734 m_iBufferPos--; 725 735 } 726 736 727 737 // If we end up on a puctuation char we just select it (treat punct like a word) 728 738 if (iswpunct(searchString[m_iBufferPos - 1])) 729 739 m_iBufferPos--; … … 748 758 m_iBufferPos_Tail = -1; 749 759 } 750 760 761 UpdateBufferPositionSetting; 751 762 UpdateAutoScroll(); 752 763 753 764 return IN_HANDLED; … … 794 805 m_iBufferPos = m_iBufferPos_Tail; 795 806 796 807 m_iBufferPos_Tail = -1; 797 } 808 } 798 809 810 UpdateBufferPositionSetting; 799 811 UpdateAutoScroll(); 800 812 801 813 return IN_HANDLED; … … 825 837 (Message.value == CStr("size") || 826 838 Message.value == CStr("z") || 827 839 Message.value == CStr("absolute"))) 828 { 840 { 829 841 GetScrollBar(0).SetX(m_CachedActualSize.right); 830 842 GetScrollBar(0).SetY(m_CachedActualSize.top); 831 843 GetScrollBar(0).SetZ(GetBufferedZ()); … … 841 853 GetScrollBar(0).SetScrollBarStyle(scrollbar_style); 842 854 } 843 855 856 if (Message.value == CStr("buffer_position")) 857 { 858 GUI<int>::GetSetting(this, Message.value, m_iBufferPos); 859 } 860 844 861 if (Message.value == CStr("size") || 845 862 Message.value == CStr("z") || 846 863 Message.value == CStr("font") || … … 868 885 869 886 UpdateText(); 870 887 } 871 888 872 889 }break; 873 890 874 891 case GUIM_MOUSE_PRESS_LEFT: … … 902 919 } 903 920 904 921 m_SelectingText = true; 905 922 906 923 UpdateAutoScroll(); 907 924 908 925 // If we immediately release the button it will just be seen as a click … … 1098 1115 default: 1099 1116 break; 1100 1117 } 1118 UpdateBufferPositionSetting; 1101 1119 } 1102 1120 1103 1121 void CInput::UpdateCachedSize() … … 1155 1173 } 1156 1174 1157 1175 if (GetGUI()) 1158 { 1176 { 1159 1177 CStrW font_name_w; 1160 1178 CColor color, color_selected; 1161 1179 //CStrW caption; … … 1163 1181 GUI<CColor>::GetSetting(this, "textcolor", color); 1164 1182 GUI<CColor>::GetSetting(this, "textcolor_selected", color_selected); 1165 1183 CStrIntern font_name(font_name_w.ToUTF8()); 1166 1184 1167 1185 // Get pointer of caption, it might be very large, and we don't 1168 1186 // want to copy it continuously. 1169 1187 CStrW *pCaption = NULL; … … 1180 1198 1181 1199 CGUISpriteInstance *sprite=NULL, *sprite_selectarea=NULL; 1182 1200 int cell_id; 1183 1201 1184 1202 GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite", sprite); 1185 1203 GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite_selectarea", sprite_selectarea); 1186 1204 1187 1205 GUI<int>::GetSetting(this, "cell_id", cell_id); 1188 1206 1189 1207 GetGUI()->DrawSprite(*sprite, cell_id, bz, m_CachedActualSize); … … 1244 1262 float ls = (float)font.GetLineSpacing(); 1245 1263 1246 1264 CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_gui_text); 1247 1265 1248 1266 CTextRenderer textRenderer(tech->GetShader()); 1249 1267 textRenderer.Font(font_name); 1250 1268 … … 1254 1272 (float)(int)(m_CachedActualSize.left) + buffer_zone, 1255 1273 (float)(int)(m_CachedActualSize.top+h) + buffer_zone, 1256 1274 bz+0.1f); 1257 1275 1258 1276 // U+FE33: PRESENTATION FORM FOR VERTICAL LOW LINE 1259 1277 // (sort of like a | which is aligned to the left of most characters) 1260 1278 … … 1411 1429 1412 1430 // Reset some from previous run 1413 1431 buffered_y = -scroll; 1414 1432 1415 1433 // Setup initial color (then it might change and change back, when drawing selected area) 1416 1434 textRenderer.Color(color); 1417 1435 … … 1418 1436 tech->BeginPass(); 1419 1437 1420 1438 bool using_selected_color = false; 1421 1439 1422 1440 for (std::list<SRow>::const_iterator it = m_CharacterPositions.begin(); 1423 1441 it != m_CharacterPositions.end(); 1424 1442 ++it, buffered_y += ls) … … 1432 1450 } 1433 1451 1434 1452 CMatrix3D savedTransform = textRenderer.GetTransform(); 1435 1453 1436 1454 // Text must always be drawn in integer values. So we have to convert scroll 1437 1455 if (multiline) 1438 1456 textRenderer.Translate(0.f, -(float)(int)scroll, 0.f); … … 1492 1510 } 1493 1511 1494 1512 // check it's now outside a one-liner, then we'll break 1495 if (!multiline && i < (int)it->m_ListOfX.size()) 1513 if (!multiline && i < (int)it->m_ListOfX.size()) 1496 1514 { 1497 1515 if (it->m_ListOfX[i] - m_HorizontalScroll > m_CachedActualSize.GetWidth()-buffer_zone) 1498 1516 break; … … 1514 1532 textRenderer.SetTransform(savedTransform); 1515 1533 } 1516 1534 1517 textRenderer.Translate(0.f, ls, 0.f); 1535 textRenderer.Translate(0.f, ls, 0.f); 1518 1536 } 1519 1537 1520 1538 textRenderer.Render(); … … 1552 1570 // Ensure positions are valid after caption changes 1553 1571 m_iBufferPos = std::min(m_iBufferPos, (int)caption.size()); 1554 1572 m_iBufferPos_Tail = std::min(m_iBufferPos_Tail, (int)caption.size()); 1573 UpdateBufferPositionSetting; 1555 1574 1556 1575 if (font_name.empty()) 1557 1576 { … … 1563 1582 1564 1583 SRow row; 1565 1584 row.m_ListStart = 0; 1566 1585 1567 1586 int to = 0; // make sure it's initialized 1568 1587 1569 1588 if (to_before == -1) … … 1670 1689 // set 'from' to the row we'll destroy from 1671 1690 // and 'to' to the row we'll destroy to 1672 1691 from = destroy_row_from->m_ListStart; 1673 1692 1674 1693 if (destroy_row_to != m_CharacterPositions.end()) 1675 1694 to = destroy_row_to->m_ListStart; // notice it will iterate [from, to), so it will never reach to. 1676 1695 else … … 1684 1703 --temp_it; 1685 1704 1686 1705 current_line = m_CharacterPositions.erase(destroy_row_from, destroy_row_to); 1687 1706 1688 1707 // If there has been a change in number of characters 1689 1708 // we need to change all m_ListStart that comes after 1690 1709 // the interval we just destroyed. We'll change all … … 1707 1726 to += delta; 1708 1727 } 1709 1728 } 1710 1729 1711 1730 int last_word_started=from; 1712 1731 //int last_list_start=-1; // unused 1713 1732 float x_pos = 0.f; … … 1721 1740 { 1722 1741 if (i==to-1 && to != (int)caption.length()) 1723 1742 break; // it will be added outside 1724 1743 1725 1744 current_line = m_CharacterPositions.insert( current_line, row ); 1726 1745 ++current_line; 1727 1746 … … 1760 1779 // regular word-wrap 1761 1780 row.m_ListOfX.resize(row.m_ListOfX.size() - (i-last_word_started+1)); 1762 1781 } 1763 1782 1764 1783 // Now, create a new line: 1765 1784 // notice: when we enter a newline, you can stand with the cursor 1766 1785 // both before and after that character, being on different … … 1868 1887 // set 'from' to the from row we'll destroy 1869 1888 // and 'to' to 'to_after' 1870 1889 from = destroy_row_from->m_ListStart; 1871 1890 1872 1891 if (destroy_row_to != m_CharacterPositions.end()) 1873 1892 to = destroy_row_to->m_ListStart; // notice it will iterate [from, to[, so it will never reach to. 1874 1893 else … … 1936 1955 GUI<CStrW>::GetSetting(this, "font", font_name_w); 1937 1956 GUI<bool>::GetSetting(this, "scrollbar", scrollbar); 1938 1957 CStrIntern font_name(font_name_w.ToUTF8()); 1939 1958 1940 1959 float scroll=0.f; 1941 1960 if (scrollbar) 1942 1961 { … … 1985 2004 1986 2005 //m_iBufferPos = m_CharacterPositions.get.m_ListStart; 1987 2006 retPosition = current->m_ListStart; 1988 2007 1989 2008 // Okay, now loop through the glyphs to find the appropriate X position 1990 2009 float dummy; 1991 2010 retPosition += GetXTextPosition(current, mouse.x, dummy); … … 2053 2072 // Remove selection 2054 2073 m_iBufferPos_Tail = -1; 2055 2074 m_iBufferPos = virtualFrom; 2075 UpdateBufferPositionSetting; 2056 2076 } 2057 2077 2058 2078 bool CInput::SelectingText() const … … 2089 2109 GUI<CStrW>::GetSetting(this, "font", font_name_w); 2090 2110 GUI<bool>::GetSetting(this, "scrollbar", scrollbar); 2091 2111 CStrIntern font_name(font_name_w.ToUTF8()); 2092 2112 2093 2113 float scroll=0.f; 2094 2114 if (!scrollbar) 2095 2115 return; 2096 2116 2097 2117 scroll = GetScrollBar(0).GetPos(); 2098 2118 2099 2119 // Now get the height of the font. 2100 2120 // TODO: Get the real font 2101 2121 CFontMetrics font(font_name); … … 2112 2132 if (m_iBufferPos >= current->m_ListStart && 2113 2133 m_iBufferPos <= current->m_ListStart+(int)current->m_ListOfX.size()) 2114 2134 break; 2115 2135 2116 2136 ++current; 2117 2137 ++row; 2118 2138 }