Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- [Code Snippet] Modified Reading Function
- @version 0.9, 2014-09-01
- @author TheOddByte
- Features:
- Placeholder text
- Text limit
- Ability to mark text
- Block unwanted characters
- Todo:
- Add keyboard support for CTRL+A, CTRL+C etc. kinda obvious what it's for right?
- Scrollable text, ( fooba > oobar )
- --]]
- local function mRead( properties )
- local placeholder, text_limit, width, mask, cursor_blink, blocked_chars, allowed_chars, marker
- local properties = properties or {}
- placeholder = properties.placeholder.text and properties.placeholder or nil
- text_limit = properties.text_limit
- width = properties.width
- mask = properties.mask
- blocked_chars = properties.blocked_chars
- allowed_chars = properties.allowed_chars
- cursor_blink = properties.cursor_blink or true
- marker = properties.marker
- term.setCursorBlink( cursor_blink )
- local x, y = term.getCursorPos()
- local text, pos, sPos, fPos, selected, mark, mx = "", 0, 0, 0, false, false
- local function redraw()
- pcall( term.setTextColor, properties.native_text_color )
- pcall( term.setBackgroundColor, properties.native_background_color )
- term.setCursorPos( x, y )
- term.write( string.rep( " ", #text + 1 ) )
- end
- while true do
- --# Format text( remove blocked characters )
- if blocked_chars then
- for i = 1, #blocked_chars do
- text = text:gsub( blocked_chars:sub( i, i ), "" )
- end
- end
- if allowed_chars then
- local _text = ""
- for i = 1, #text do
- for k = 1, #allowed_chars do
- if text:sub( i,i ) == allowed_chars:sub( k, k ) then
- _text = _text .. text:sub( i,i )
- break
- end
- end
- end
- text = _text
- end
- if pos > #text then
- pos = #text
- end
- --# Redraw text
- term.setCursorPos( x + #text, y )
- term.write( " " )
- term.setCursorPos( x, y )
- if placeholder then
- if #text == 0 then
- if placeholder.text_color then
- pcall( term.setTextColor, placeholder.text_color )
- end
- term.setCursorBlink( placeholder.cursor_blink or true )
- else
- if properties.native_text_color then
- pcall( term.setTextColor, properties.native_text_color )
- end
- end
- if mask then
- term.write( #text > 0 and string.rep( mask:sub(1,1), #text ) or placeholder.text )
- else
- term.write( #text > 0 and text or placeholder.text )
- end
- else
- term.write( mask and string.rep( mask:sub(1,1), #text ) or text )
- end
- if selected then
- term.setCursorBlink( false )
- pcall( term.setTextColor, marker.text_color )
- pcall( term.setBackgroundColor, marker.background_color )
- local str = ""
- for i = sPos, fPos do
- str = str .. text:sub( i, i )
- end
- term.setCursorPos( x + (sPos-1), y )
- term.write( mask and string.rep( mask, #str ) or str )
- pcall( term.setTextColor, properties.native_text_color )
- pcall( term.setBackgroundColor, properties.native_background_color )
- else
- term.setCursorBlink( cursor_blink )
- end
- term.setCursorPos( placeholder and #text > 0 and x + pos or x + #placeholder.text, y )
- --# Handle events
- local e = { os.pullEvent() }
- if e[1] == "char" then
- if placeholder.text and #text == 0 then
- for i = 1, #placeholder.text do
- term.setCursorPos( x + (i-1), y )
- term.write( " " )
- end
- end
- if not text_limit then
- if not selected then
- text = text:sub( 1, pos ) .. e[2] .. text:sub( pos + 1 )
- pos = pos + 1
- else
- redraw()
- text = text:sub( 1, sPos - 1 ) .. e[2] .. text:sub( fPos + 1 )
- pos = sPos
- selected = false
- end
- else
- if #text < text_limit then
- if not selected then
- text = text:sub( 1, pos ) .. e[2] .. text:sub( pos + 1 )
- pos = pos + 1
- else
- redraw()
- text = text:sub( 1, sPos - 1 ) .. e[2] .. text:sub( fPos + 1 )
- pos = sPos
- selected = false
- end
- end
- end
- elseif e[1] == "key" then
- if e[2] == 14 then
- if selected then
- redraw()
- text = text:sub( 1, sPos - 1 ) .. text:sub( fPos + 1 )
- selected = false
- pos = sPos - 1
- else
- if #text > 0 and pos > 0 then
- text = text:sub( 1, pos - 1 ) .. text:sub( pos + 1 )
- pos = pos - 1
- end
- end
- elseif e[2] == keys.left then
- selected = false
- pos = pos > 0 and pos - 1 or pos
- elseif e[2] == keys.right then
- selected = false
- pos = pos < #text and pos + 1 or pos
- elseif e[2] == 28 then
- return text
- end
- elseif e[1] == "mouse_click" then
- if e[3] >= x and e[3] <= x + #text and e[4] == y then
- pos = e[3] - x
- mark = true
- mx = e[3]
- else
- mx = nil
- mark = false
- end
- selected = false
- elseif e[1] == "mouse_drag" then
- if mark then
- selected = true;
- if e[3] == mx then
- selected = false
- else
- selected = true
- if e[3] >= x and e[3] <= x + #text then
- if e[3] < mx then
- sPos = (e[3] - x) + 1;
- fPos = (mx - x) + 1;
- elseif e[3] > mx then
- sPos = (mx - x) + 1;
- fPos = (e[3] - x) + 1;
- end
- else
- if mx == x + #text then
- if e[3] > x + #text then
- selected = false;
- end
- end
- end
- end
- end
- end
- end
- end
- --[[
- Example usage
- 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 } })
- --]]
Advertisement
Add Comment
Please, Sign In to add comment