Advertisement
Guest User

Keyboard Text Input 1.1

a guest
Nov 3rd, 2016
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 16.08 KB | None | 0 0
  1. #==============================================================================
  2. # ** Text Input script
  3. #------------------------------------------------------------------------------
  4. # author:  erpicci
  5. # version: 1.1
  6. # require: CP Keyboard Input script by Neon Black
  7. #
  8. #------------------------------------------------------------------------------
  9. # * Introduction
  10. #------------------------------------------------------------------------------
  11. # This script allows the player to insert a medium-sized text by typing
  12. # directly from the keyboard. Inserted text is returned as a string.
  13. #
  14. # Requires Neon Black's Keyboard Input Script to work.
  15. #
  16. # It is completely free, both for commercial and non-commercial use. All you
  17. # are asked to do is to give me credits for the script.
  18. #
  19. #------------------------------------------------------------------------------
  20. # * Installation
  21. #------------------------------------------------------------------------------
  22. # Be sure to have Neon Black's Keyboard Input Script installed.
  23. # Place this script in the "Materials" section of the scripts above main.
  24. #
  25. # To insert a text using an event, create a script event like:
  26. #   text_var = text_input("Window Title")
  27. #
  28. # To have a script call the text input, use:
  29. #   text_var = Scene_Text.read("Window Title")
  30. #
  31. # Only window title is mandatory. As optional arguments, you can set:
  32. #  * alignment: "center" (default), "left", "right"
  33. #  * maximum number of character: default is 104
  34. #  * left-to-right: default is true, use false to get a right-to-left input
  35. #  * configuration object (see examples)
  36. #
  37. #------------------------------------------------------------------------------
  38. # * Changelog and notes
  39. #------------------------------------------------------------------------------
  40. # -1.1:   Fixed a memoty leak
  41. #
  42. # -1.1rc: Added options to manipulate the text edit window (position, size,
  43. #         opacity); manipulation is obtained through the new Scene_Text_Config
  44. #         class. Backward compatibile.
  45. #
  46. #------------------------------------------------------------------------------
  47. # * Examples
  48. #------------------------------------------------------------------------------
  49. #   # Open a window whose title is "Talk to Bobby", text is centered, allows
  50. #   # to enter up to 20 characters, writing is right-to-left
  51. #   variable = Scene_Text.read("Talk to Bobby", "center", 20, false)
  52. #
  53. #   # Open a window whose title is "Tell me something", text is aligned to
  54. #   # right, allows to enter up to 88 characters, writing is left-to-right
  55. #   # (default)
  56. #   variable = Scene_Text.read("Talk to Bobby", "center", 20)
  57. #
  58. #   # Open a window whose title is "Insert text", text is centered (default),
  59. #   # accepts up to 104 characters (default), writing is left-to-right (default)
  60. #   variable = Scene_Text.read("Talk to Bobby")
  61. #
  62. #   # Open a window whose title is "Text:", text is centered, allows
  63. #   # to enter up to 20 characters, writing is right-to-left,
  64. #   # window is resized, centered in the screen and semi-transparent
  65. #   config = Scene_Text_Config.new
  66. #   config.width = 256
  67. #   config.height = 128
  68. #   config.verticalAlignment = "center"
  69. #   config.horizontalAlignment = "center"
  70. #   config.opacity = 64
  71. #   variable = Scene_Text.read("Text:", "center", 20, true, config)
  72. #
  73. #   # Open a window whose title is "Text:", text is centered, allows
  74. #   # to enter up to 30 characters, writing is right-to-left,
  75. #   # window is resized, aligned on the top-right corner and fully transparent
  76. #   config = Scene_Text_Config.new
  77. #   config.width = 128
  78. #   config.height = 256
  79. #   config.verticalAlignment = "top"
  80. #   config.horizontalAlignment = "right"
  81. #   config.opacity = 0
  82. #   variable = Scene_Text.read("Text:", "center", 30, true, config)
  83. #
  84. #   # Open a window whose title is "Text:", text is centered, allows to enter
  85. #   # up to 20 characters, writing is left-to-right, window is partially
  86. #   # transparent
  87. #   # config = Scene_Text_Config.new
  88. #   # config.opacity = 128
  89. #   # variable = Scene_Text.read("Text:", "center", 20, true, config)
  90. #==============================================================================
  91.  
  92. module Text_Input
  93.   ACCEPTED_KEYS = {
  94.     :k0 => 48, :k1 => 49, :k2 => 50, :k3 => 51, :k4 => 52,
  95.     :k5 => 53, :k6 => 54, :k7 => 55, :k8 => 56, :k9 => 57,
  96.    
  97.     :kA => 65, :kB => 66, :kC => 67, :kD => 68, :kE => 69, :kF => 70,
  98.     :kG => 71, :kH => 72, :kI => 73, :kJ => 74, :kK => 75, :kL => 76,
  99.     :kM => 77, :kN => 78, :kO => 79, :kP => 80, :kQ => 81, :kR => 82,
  100.     :kS => 83, :kT => 84, :kU => 85, :kV => 86, :kW => 87, :kX => 88,
  101.     :kY => 89, :kZ => 90,
  102.    
  103.     :kCOLON     => 186, :kQUOTE     => 222, :kSPACE      => 32,
  104.     :kCOMMA     => 188, :kPERIOD    => 190, :kSLASH      => 191,
  105.     :kBACKSLASH => 220, :kLEFTBRACE => 219, :kRIGHTBRACE => 221,
  106.     :kMINUS     => 189, :kEQUAL     => 187, :kTILDE      => 192,          
  107.   }
  108. end
  109.  
  110.  
  111.  
  112. #==============================================================================
  113. # ** Scebe_Text_Config
  114. #------------------------------------------------------------------------------
  115. #  This object contains additional configuration for the text edit window
  116. #==============================================================================
  117.  
  118. class Scene_Text_Config
  119.   attr_accessor :lines
  120.   attr_accessor :x
  121.   attr_accessor :y
  122.   attr_accessor :width
  123.   attr_accessor :height
  124.   attr_accessor :opacity
  125.  
  126.   #--------------------------------------------------------------------------
  127.   # * Object Initialization: set default values
  128.   #--------------------------------------------------------------------------
  129.   def initialize
  130.     @window  = nil
  131.     @lines   = 6
  132.     @x       = 0
  133.     @y       = Graphics.height - window.fitting_height(lines)
  134.     @width   = Graphics.width
  135.     @height  = window.fitting_height(lines)
  136.     @opacity = 256
  137.     window.dispose
  138.   end
  139.   #--------------------------------------------------------------------------
  140.   # * Access to Properties of Windows
  141.   #--------------------------------------------------------------------------
  142.   def window
  143.     if (@window.nil?)
  144.       @window = Window_Base.new(0, 0, 0, 0)
  145.     end
  146.     @window
  147.   end
  148.   #--------------------------------------------------------------------------
  149.   # * Sets Horizontal Alignment
  150.   #--------------------------------------------------------------------------
  151.   def horizontalAlignment=(position = "center")
  152.     if (position == "left")
  153.       @x = 0
  154.     elsif (position == "right")
  155.       @x = Graphics.width - @width
  156.     else
  157.       @x = (Graphics.width - @width) / 2
  158.     end
  159.   end
  160.   #--------------------------------------------------------------------------
  161.   # * Sets Vertical Alignment
  162.   #--------------------------------------------------------------------------
  163.   def verticalAlignment=(position = "bottom")
  164.     if (position == "top")
  165.       @y = 0
  166.     elsif (position == "center")
  167.       @y = (Graphics.height - @height) / 2
  168.     else
  169.       @y = Graphics.height - @height
  170.     end
  171.   end
  172. end
  173.  
  174.  
  175.  
  176. #==============================================================================
  177. # ** Scene_Text
  178. #------------------------------------------------------------------------------
  179. #  This class shows an input field for the player.
  180. #==============================================================================
  181.  
  182. class Scene_Text < Scene_MenuBase
  183.   ALIGN    = "center"
  184.   MAX_CHAR = 104
  185.   LTR      = true
  186.  
  187.   #--------------------------------------------------------------------------
  188.   # * Show a dialog window to the player
  189.   #--------------------------------------------------------------------------
  190.   def self.read(title, align = ALIGN, max_char = MAX_CHAR, ltr = LTR, opts = nil)
  191.     @@text     = ""
  192.     @@title    = title
  193.     @@align    = align
  194.     @@max_char = max_char
  195.     @@ltr      = ltr
  196.     @@opts     = opts.nil? ? Scene_Text_Config.new : opts
  197.     SceneManager.call(Scene_Text)
  198.     Fiber.yield while SceneManager.scene_is?(Scene_Text)
  199.     return @@text
  200.   end
  201.   #--------------------------------------------------------------------------
  202.   # * Start Processing
  203.   #--------------------------------------------------------------------------
  204.   def start
  205.     super
  206.     @edit_window  = Window_TextEdit.new(@@title, @@align, @@max_char, @@ltr,
  207.       @@opts)
  208.     @edit_window.set_handler(:ok, method(:on_input_ok))
  209.   end
  210.   #--------------------------------------------------------------------------
  211.   # * Set text when done
  212.   #--------------------------------------------------------------------------
  213.   def on_input_ok
  214.     @@text = @edit_window.text
  215.     @@opts.window.dispose
  216.     return_scene
  217.   end
  218. end
  219.  
  220.  
  221.  
  222. #==============================================================================
  223. # ** Window_TextEdit
  224. #------------------------------------------------------------------------------
  225. #  This window allows to edit a text.
  226. #==============================================================================
  227.  
  228. class Window_TextEdit < Window_Selectable
  229.   include Text_Input
  230.   #--------------------------------------------------------------------------
  231.   # * Public Instance Variables
  232.   #--------------------------------------------------------------------------
  233.   attr_accessor :text
  234.  
  235.   #--------------------------------------------------------------------------
  236.   # * Object Initialization
  237.   #--------------------------------------------------------------------------
  238.   def initialize(title, align = "center", max_char = 104, ltr = true, opts = nil)
  239.     opts = opts.nil? ? Scene_Text_Config.new : opts
  240.     super(opts.x, opts.y, opts.width, opts.height)
  241.     self.opacity = opts.opacity
  242.    
  243.     @text     = ""
  244.     @title    = title
  245.     @align    = align
  246.     @max_char = max_char
  247.     @ltr      = ltr
  248.     @opts     = opts
  249.     @index    = @text.size
  250.     activate
  251.     refresh
  252.   end
  253.   #--------------------------------------------------------------------------
  254.   # * Revert to Default Text
  255.   #--------------------------------------------------------------------------
  256.   def restore_default
  257.     @text = ""
  258.     @index = @text.size
  259.     refresh
  260.     return !@text.empty?
  261.   end
  262.   #--------------------------------------------------------------------------
  263.   # * Get Character Width
  264.   #--------------------------------------------------------------------------
  265.   def char_width
  266.     text_size($game_system.japanese? ? "‚ " : "A").width
  267.   end
  268.   #--------------------------------------------------------------------------
  269.   # * Get Number of Columns
  270.   #--------------------------------------------------------------------------
  271.   def max_col
  272.     [(@opts.width - 32) / char_width, @max_char].min
  273.   end
  274.   #--------------------------------------------------------------------------
  275.   # * Get Left Padding
  276.   #--------------------------------------------------------------------------
  277.   def left(n)
  278.     return 10                                if @align == "left"
  279.     return (width - 32 - n * char_width)     if @align == "right"
  280.     return (width - 32 - n * char_width) / 2 # if align == "center"
  281.   end
  282.   #--------------------------------------------------------------------------
  283.   # * Get Rectangle for Displaying Item
  284.   #--------------------------------------------------------------------------
  285.   def item_rect(index)
  286.     index -= 1 if index == @max_char
  287.     x = index % max_col
  288.     y = index / max_col
  289.     n = [(@max_char - y * max_col), max_col].min
  290.    
  291.     x = left(n) + x * char_width
  292.     x = width   - x - 48 if not @ltr
  293.     y = 24      + y * (line_height + 4)
  294.     Rect.new(x, y, char_width, line_height)
  295.   end
  296.   #--------------------------------------------------------------------------
  297.   # * Get Underline Rectangle
  298.   #--------------------------------------------------------------------------
  299.   def underline_rect(index)
  300.     rect = item_rect(index)
  301.     rect.x += 1
  302.     rect.y += rect.height
  303.     rect.width -= 2
  304.     rect.height = 2
  305.     rect
  306.   end
  307.   #--------------------------------------------------------------------------
  308.   # * Get Underline Color
  309.   #--------------------------------------------------------------------------
  310.   def underline_color
  311.     color = normal_color
  312.     color.alpha = 48
  313.     color
  314.   end
  315.   #--------------------------------------------------------------------------
  316.   # * Draw Underline
  317.   #--------------------------------------------------------------------------
  318.   def draw_underline(index)
  319.     contents.fill_rect(underline_rect(index), underline_color)
  320.   end
  321.   #--------------------------------------------------------------------------
  322.   # * Draw Text
  323.   #--------------------------------------------------------------------------
  324.   def draw_char(index)
  325.     rect       = item_rect(index)
  326.     rect.x     += 4
  327.     rect.width += 4
  328.     change_color(normal_color)
  329.     draw_text(rect, @text[index] || "")
  330.   end
  331.   #--------------------------------------------------------------------------
  332.   # * Draw Title
  333.   #--------------------------------------------------------------------------
  334.   def draw_title
  335.     draw_text(0, 0, self.width, line_height, @title, 1)
  336.   end
  337.   #--------------------------------------------------------------------------
  338.   # * Refresh
  339.   #--------------------------------------------------------------------------
  340.   def refresh
  341.     contents.clear
  342.     draw_title
  343.     @text.size.times {|i| draw_char(i) }
  344.     @max_char.times  {|i| draw_underline(i) }
  345.     cursor_rect.set(item_rect(@index))
  346.   end
  347.   #--------------------------------------------------------------------------
  348.   # * Handle Process
  349.   #--------------------------------------------------------------------------
  350.   def process_handling
  351.     return unless open? && active
  352.     process_delete if Input.repeat?(:kBACKSPACE)
  353.     process_abort  if Input.trigger?(:kESC)
  354.     process_ok     if Input.trigger?(:kENTER)
  355.     process_keyboard
  356.   end
  357.   #--------------------------------------------------------------------------
  358.   # * Check Input From Keyboard
  359.   #--------------------------------------------------------------------------
  360.   def process_keyboard
  361.     ACCEPTED_KEYS.each {|key|
  362.       if Input.repeat?(key[0])
  363.         c = (key[0] != :kSPACE) ? Keyboard.add_char(Ascii::SYM[key[0]]) : " "
  364.         process_add(c)
  365.         Sound.play_ok
  366.       end
  367.     }
  368.   end
  369.   #--------------------------------------------------------------------------
  370.   # * Add One Character
  371.   #--------------------------------------------------------------------------
  372.   def process_add(c)
  373.     return if @index > @max_char
  374.     if @index == @max_char
  375.       @text[@index - 1] = c
  376.     else
  377.       @text  += c
  378.       @index += 1
  379.     end
  380.     refresh
  381.   end
  382.   #--------------------------------------------------------------------------
  383.   # * Delete One Character
  384.   #--------------------------------------------------------------------------
  385.   def process_delete
  386.     return if @index == 0
  387.     @index -= 1
  388.     @text  = @text[0, @index]
  389.     Sound.play_cancel
  390.     refresh
  391.   end
  392.   #--------------------------------------------------------------------------
  393.   # * Abort Text Input
  394.   #--------------------------------------------------------------------------
  395.   def process_abort
  396.     restore_default
  397.     Sound.play_cancel
  398.     call_ok_handler
  399.   end
  400.   #--------------------------------------------------------------------------
  401.   # * Complete Text Input
  402.   #--------------------------------------------------------------------------
  403.   def process_ok
  404.     Sound.play_ok
  405.     call_ok_handler
  406.   end
  407. end
  408.  
  409.  
  410.  
  411.  
  412.  
  413. #==============================================================================
  414. # ** Game_Interpreter
  415. #------------------------------------------------------------------------------
  416. #  An interpreter for executing event commands. This class is used within the
  417. # Game_Map, Game_Troop, and Game_Event classes.
  418. #==============================================================================
  419.  
  420. class Game_Interpreter
  421.   #--------------------------------------------------------------------------
  422.   # * Insert a text
  423.   #--------------------------------------------------------------------------
  424.   def text_input(title, align = "center", max_char = 103, ltr = true, opts = nil)
  425.     Scene_Text.read(title, align, max_char, ltr, opts)
  426.   end
  427. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement