textinput.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import pygame, sys
  2. import pygame.freetype
  3. ###CONSTS
  4. # Set to true or add 'showevent' in argv to see IME and KEYDOWN events
  5. PRINT_EVENT = False
  6. # frames per second, the general speed of the program
  7. FPS = 50
  8. # size of window
  9. WINDOWWIDTH, WINDOWHEIGHT = 640, 480
  10. BGCOLOR = (0, 0, 0)
  11. # position of chatlist and chatbox
  12. CHATLIST_POS = pygame.Rect(0, 20, WINDOWWIDTH, 400)
  13. CHATBOX_POS = pygame.Rect(0, 440, WINDOWWIDTH, 40)
  14. CHATLIST_MAXSIZE = 20
  15. TEXTCOLOR = (0,255,0)
  16. #Add fontname for each language, otherwise some text can't be correctly displayed.
  17. FONTNAMES = ["notosanscjktcregular", "notosansmonocjktcregular" ,
  18. "notosansregular,",
  19. "microsoftjhengheimicrosoftjhengheiuilight",
  20. "microsoftyaheimicrosoftyaheiuilight",
  21. "msgothicmsuigothicmspgothic",
  22. "msmincho",
  23. "Arial"]
  24. #Version check
  25. if (pygame.get_sdl_version() < (2,0,0)):
  26. raise Exception("This example requires SDL2.")
  27. #Initalize
  28. pygame.init()
  29. Screen = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT))
  30. pygame.display.set_caption("TextInput example")
  31. FPSClock = pygame.time.Clock()
  32. #Freetype
  33. #"The font name can be a comma separated list of font names to search for."
  34. FONTNAMES = ",".join(str(x) for x in FONTNAMES)
  35. Font = pygame.freetype.SysFont(FONTNAMES, 24)
  36. FontSmall = pygame.freetype.SysFont(FONTNAMES, 16)
  37. print("Using font: " + Font.name)
  38. #Main loop process
  39. def main():
  40. global BGCOLOR, PRINT_EVENT, CHATBOX_POS, CHATLIST_POS, CHATLIST_MAXSIZE
  41. global FPSClock , Font, Screen
  42. """
  43. https://wiki.libsdl.org/SDL_HINT_IME_INTERNAL_EDITING
  44. https://wiki.libsdl.org/Tutorials/TextInput
  45. Candidate list not showing due to SDL2 problem ;w;
  46. """
  47. pygame.key.start_text_input()
  48. input_rect = pygame.Rect(80,80,320,40)
  49. pygame.key.set_text_input_rect(input_rect)
  50. _IMEEditing = False
  51. _IMEText = ""
  52. _IMETextPos = 0
  53. _IMEEditingText = ""
  54. _IMEEditingPos = 0
  55. ChatList = []
  56. while True:
  57. for event in pygame.event.get():
  58. if event.type == pygame.QUIT:
  59. pygame.quit()
  60. return
  61. elif event.type == pygame.KEYDOWN:
  62. if (PRINT_EVENT):
  63. print(event)
  64. if _IMEEditing:
  65. if (len(_IMEEditingText) == 0):
  66. _IMEEditing = False
  67. continue
  68. if event.key == pygame.K_BACKSPACE:
  69. if (len(_IMEText) > 0 and _IMETextPos > 0):
  70. _IMEText = _IMEText[0:_IMETextPos-1] + _IMEText[_IMETextPos:]
  71. _IMETextPos = max(0,_IMETextPos-1)
  72. elif event.key == pygame.K_DELETE:
  73. _IMEText = _IMEText[0:_IMETextPos] + _IMEText[_IMETextPos+1:]
  74. elif event.key == pygame.K_LEFT:
  75. _IMETextPos = max(0,_IMETextPos-1)
  76. elif event.key == pygame.K_RIGHT:
  77. _IMETextPos = min(len(_IMEText),_IMETextPos+1)
  78. elif event.key in [pygame.K_RETURN, pygame.K_KP_ENTER] and len(event.unicode) == 0:
  79. #Block if we have no text to append
  80. if len(_IMEText) == 0:
  81. continue
  82. #Append chat list
  83. ChatList.append(_IMEText)
  84. if (len(ChatList) > CHATLIST_MAXSIZE):
  85. ChatList.pop(0)
  86. _IMEText = ""
  87. _IMETextPos = 0
  88. elif event.type == pygame.TEXTEDITING:
  89. if (PRINT_EVENT):
  90. print(event)
  91. _IMEEditing = True
  92. _IMEEditingText = event.text
  93. _IMEEditingPos = event.start
  94. elif event.type == pygame.TEXTINPUT:
  95. if (PRINT_EVENT):
  96. print(event)
  97. _IMEEditing = False
  98. _IMEEditingText = ""
  99. _IMEText = _IMEText[0:_IMETextPos] + event.text + _IMEText[_IMETextPos:]
  100. _IMETextPos += len(event.text)
  101. #Screen updates
  102. Screen.fill(BGCOLOR)
  103. #Chat List updates
  104. chat_height = CHATLIST_POS.height / CHATLIST_MAXSIZE
  105. for i in range(len(ChatList)):
  106. FontSmall.render_to(Screen, (CHATLIST_POS.x, CHATLIST_POS.y + i*chat_height), ChatList[i], TEXTCOLOR)
  107. #Chat box updates
  108. start_pos = CHATBOX_POS.copy()
  109. ime_textL = ">" + _IMEText[0:_IMETextPos]
  110. ime_textM = _IMEEditingText[0:_IMEEditingPos] + "|" + _IMEEditingText[_IMEEditingPos:]
  111. ime_textR = _IMEText[_IMETextPos:]
  112. rect_textL = Font.render_to(Screen, start_pos, ime_textL, TEXTCOLOR)
  113. start_pos.x += rect_textL.width
  114. #Editing texts should be underlined
  115. rect_textM = Font.render_to(Screen, start_pos, ime_textM, TEXTCOLOR, None, pygame.freetype.STYLE_UNDERLINE)
  116. start_pos.x += rect_textM.width
  117. rect_textr = Font.render_to(Screen, start_pos, ime_textR, TEXTCOLOR)
  118. pygame.display.update()
  119. FPSClock.tick(FPS)
  120. if __name__ == '__main__':
  121. if 'showevent' in sys.argv:
  122. PRINT_EVENT = True
  123. main()