TheOddByte

[ComputerCraft][Code Snippet] Modified Reading Function

Sep 1st, 2014
359
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.84 KB | None | 0 0
  1. --[[
  2.     [Code Snippet] Modified Reading Function
  3.     @version 0.9, 2014-09-01
  4.     @author TheOddByte
  5.  
  6.  
  7.  
  8.     Features:
  9.         Placeholder text
  10.         Text limit
  11.         Ability to mark text
  12.         Block unwanted characters
  13.  
  14.     Todo:
  15.         Add keyboard support for CTRL+A, CTRL+C etc. kinda obvious what it's for right?
  16.         Scrollable text, ( fooba > oobar )
  17. --]]
  18.  
  19. local function mRead( properties )
  20.    
  21.     local placeholder, text_limit, width, mask, cursor_blink, blocked_chars, allowed_chars, marker
  22.     local properties = properties or {}
  23.     placeholder   = properties.placeholder.text and properties.placeholder or nil
  24.     text_limit    = properties.text_limit
  25.     width         = properties.width
  26.     mask          = properties.mask
  27.     blocked_chars = properties.blocked_chars
  28.     allowed_chars = properties.allowed_chars
  29.     cursor_blink  = properties.cursor_blink or true
  30.     marker        = properties.marker
  31.  
  32.    
  33.     term.setCursorBlink( cursor_blink )
  34.     local x, y = term.getCursorPos()
  35.     local text, pos, sPos, fPos, selected, mark, mx = "", 0, 0, 0, false, false
  36.    
  37.     local function redraw()
  38.         pcall( term.setTextColor, properties.native_text_color )
  39.         pcall( term.setBackgroundColor, properties.native_background_color )
  40.         term.setCursorPos( x, y )
  41.         term.write( string.rep( " ", #text + 1 ) )
  42.     end
  43.    
  44.    
  45.    
  46.    
  47.     while true do
  48.    
  49.         --# Format text( remove blocked characters )
  50.         if blocked_chars then
  51.             for i = 1, #blocked_chars do
  52.                 text = text:gsub( blocked_chars:sub( i, i ), "" )
  53.             end
  54.         end
  55.         if allowed_chars then
  56.             local _text = ""
  57.             for i = 1, #text do
  58.                 for k = 1, #allowed_chars do
  59.                     if text:sub( i,i ) == allowed_chars:sub( k, k ) then
  60.                         _text = _text .. text:sub( i,i )
  61.                         break
  62.                     end
  63.                 end
  64.             end
  65.             text = _text
  66.         end
  67.         if pos > #text then
  68.             pos = #text
  69.         end
  70.                
  71.        
  72.         --# Redraw text
  73.         term.setCursorPos( x + #text, y )
  74.         term.write( " " )
  75.         term.setCursorPos( x, y )
  76.         if placeholder then
  77.             if #text == 0 then
  78.                 if placeholder.text_color then
  79.                     pcall( term.setTextColor, placeholder.text_color )
  80.                 end
  81.                 term.setCursorBlink( placeholder.cursor_blink or true )
  82.             else
  83.                 if properties.native_text_color then
  84.                     pcall( term.setTextColor, properties.native_text_color )
  85.                 end
  86.             end
  87.             if mask then
  88.                 term.write( #text > 0 and string.rep( mask:sub(1,1), #text ) or placeholder.text )
  89.             else
  90.                 term.write( #text > 0 and text or placeholder.text )
  91.             end
  92.         else
  93.             term.write( mask and string.rep( mask:sub(1,1), #text ) or text )
  94.         end
  95.         if selected then
  96.             term.setCursorBlink( false )
  97.             pcall( term.setTextColor, marker.text_color )
  98.             pcall( term.setBackgroundColor, marker.background_color )
  99.             local str = ""
  100.             for i = sPos, fPos do
  101.                 str = str .. text:sub( i, i )
  102.             end
  103.             term.setCursorPos( x + (sPos-1), y )
  104.             term.write( mask and string.rep( mask, #str ) or str )
  105.             pcall( term.setTextColor, properties.native_text_color )
  106.             pcall( term.setBackgroundColor, properties.native_background_color )
  107.         else
  108.             term.setCursorBlink( cursor_blink )
  109.         end
  110.         term.setCursorPos( placeholder and #text > 0 and x + pos or x + #placeholder.text, y )
  111.    
  112.    
  113.    
  114.         --# Handle events
  115.         local e = { os.pullEvent() }
  116.         if e[1] == "char" then
  117.             if placeholder.text and #text == 0 then
  118.                 for i = 1, #placeholder.text do
  119.                     term.setCursorPos( x + (i-1), y )
  120.                     term.write( " " )
  121.                 end
  122.             end
  123.             if not text_limit then
  124.                 if not selected then
  125.                     text = text:sub( 1, pos ) .. e[2] .. text:sub( pos + 1 )
  126.                     pos = pos + 1
  127.                 else
  128.                     redraw()
  129.                     text = text:sub( 1, sPos - 1 ) .. e[2] .. text:sub( fPos + 1 )
  130.                     pos = sPos
  131.                     selected = false
  132.                 end                
  133.             else
  134.                 if #text < text_limit then
  135.                     if not selected then
  136.                         text = text:sub( 1, pos ) .. e[2] .. text:sub( pos + 1 )
  137.                         pos = pos + 1
  138.                     else
  139.                         redraw()
  140.                         text = text:sub( 1, sPos - 1 ) .. e[2] .. text:sub( fPos + 1 )
  141.                         pos = sPos
  142.                         selected = false
  143.                     end
  144.                 end
  145.             end
  146.        
  147.         elseif e[1] == "key" then
  148.             if e[2] == 14 then
  149.                 if selected then
  150.                     redraw()
  151.                     text = text:sub( 1, sPos - 1 ) .. text:sub( fPos + 1 )
  152.                     selected = false
  153.                     pos = sPos - 1
  154.                 else
  155.                     if #text > 0 and pos > 0 then
  156.                         text = text:sub( 1, pos - 1 ) .. text:sub( pos + 1 )
  157.                         pos = pos - 1
  158.                     end
  159.                 end
  160.            
  161.             elseif e[2] == keys.left then
  162.                 selected = false
  163.                 pos = pos > 0 and pos - 1 or pos
  164.                
  165.             elseif e[2] == keys.right then
  166.                 selected = false
  167.                 pos = pos < #text and pos + 1 or pos
  168.            
  169.             elseif e[2] == 28 then
  170.                 return text
  171.             end
  172.            
  173.         elseif e[1] == "mouse_click" then
  174.             if e[3] >= x and e[3] <= x + #text and e[4] == y then
  175.                 pos = e[3] - x
  176.                 mark = true
  177.                 mx = e[3]
  178.             else
  179.                 mx = nil
  180.                 mark = false
  181.             end
  182.             selected = false
  183.            
  184.         elseif e[1] == "mouse_drag" then
  185.             if mark then
  186.                 selected = true;
  187.                 if e[3] == mx then
  188.                     selected = false
  189.                 else
  190.                     selected = true
  191.                     if e[3] >= x and e[3] <= x + #text then
  192.                         if e[3] < mx then
  193.                             sPos = (e[3] - x) + 1;
  194.                             fPos = (mx - x) + 1;
  195.                         elseif e[3] > mx then
  196.                             sPos = (mx - x) + 1;
  197.                             fPos = (e[3] - x) + 1;
  198.                         end
  199.                     else
  200.                         if mx == x + #text then
  201.                             if e[3] > x + #text then
  202.                                 selected = false;
  203.                             end
  204.                         end
  205.                     end
  206.                 end
  207.             end
  208.         end
  209.     end
  210. end
  211.  
  212.  
  213.  
  214. --[[
  215.     Example usage
  216.    
  217.     local text = mRead({ native_text_color = colors.white, native_background_color = colors.black, placeholder = { text = "Input numbers", text_color = colors.lightGray}, text_limit = 10, allowed_chars = "0123456789", marker = { text_color = colors.white, background_color = colors.blue } })
  218.  
  219. --]]
Advertisement
Add Comment
Please, Sign In to add comment