Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- [API] Object
- @version 1.0, 2014-09-028
- @author TheOddByte
- --]]
- local w, h = term.getSize()
- function load( self, path )
- if not fs.isDir( path ) then
- self[fs.getName( path )] = dofile( path )
- end
- end
- Dropdown = {}
- Dropdown.__index = Dropdown
- Dropdown.new = function( properties )
- local dropdown = {}
- local properties = properties or error( "dropdown: no properties inputted", 2 )
- dropdown.options = properties.options or error( "dropdown: no options inputted", 2 )
- dropdown.centered = properties.centered or false
- dropdown.width = type( properties.width ) == "number" and properties.width or error( "dropdown:width: number expected, got " .. type( properties.width ) )
- if not dropdown.centered then
- dropdown.x = type( properties.x ) == "number" and properties.x or error( "dropdown:x: number expected, got " .. type( properties.x ), 2 )
- else
- dropdown.x = math.ceil( (w-dropdown.width)/2 ) - 1
- end
- dropdown.y = type( properties.y ) == "number" and properties.y or error( "dropdown:y: number expected, got " .. type( properties.y ), 2 )
- dropdown.index = 1;
- dropdown.drop = false;
- dropdown.text_color = properties.text_color or colors.white;
- dropdown.background_color = properties.background_color or colors.gray;
- dropdown.button = properties.button or { background_color = colors.lightGray; text_color = colors.white; }
- dropdown.type = "dropdown"
- return setmetatable( dropdown, Dropdown )
- end
- function Dropdown:draw()
- draw.line( self.x, self.y, self.width, self.text_color, self.background_color )
- draw.setColors( self.button.text_color, self.button.background_color )
- if self.drop then
- term.write( "^" )
- draw.line( self.x, self.y + 1, self.width, self.text_color, self.background_color )
- draw.at( self.x, self.y + 1, string.rep( "-", self.width ) )
- for i = 1, #self.options do
- draw.line( self.x, self.y + i + 1, self.width, self.text_color, self.background_color )
- draw.midpoint( self.x, (self.x + self.width)-1, self.y + i + 1, self.options[i] )
- end
- else
- term.write( "v" )
- end
- draw.setColors( self.text_color, self.background_color )
- draw.midpoint( self.x, (self.x + self.width)-1, self.y, self.options[self.index] )
- end
- function Dropdown:handle( ... )
- local e = { ... }
- if e[1] == "mouse_click" then
- if e[4] == self.y then
- if e[3] >= self.x and e[3] <= self.x + self.width then
- if self.drop then
- self.drop = false
- else
- self.drop = true
- end
- end
- end
- if self.drop then
- if e[4] < self.y or e[4] > self.y + #self.options+1 or e[3] < self.x or e[3] > self.x + self.width then
- self.drop = false
- end
- end
- if self.drop then
- for i = 1, #self.options do
- if e[4] == self.y + i + 1 and e[3] >= self.x and e[3] <= self.x + self.width-1 then
- self.index = i
- self.drop = false
- break
- end
- end
- end
- end
- end
- Textbox = {}
- Textbox.__index = Textbox
- Textbox.new = function( properties )
- local textbox = {}
- local properties = properties or {}
- textbox.type = "textbox"
- textbox.text = ""
- textbox.pos = 0;
- textbox.sPos = 0;
- textbox.fPos = 0;
- textbox.selected = false;
- textbox.mark = false;
- textbox.mx = false;
- textbox.cursor_blink = properties.cursor_blink or true
- textbox.placeholder = properties.placeholder.text and properties.placeholder or nil
- textbox.text_limit = properties.text_limit
- textbox.width = properties.width
- textbox.mask = properties.mask
- textbox.blocked_chars = properties.blocked_chars
- textbox.allowed_chars = properties.allowed_chars
- textbox.marker = properties.marker
- textbox.x = properties.x
- textbox.y = properties.y
- textbox.active = properties.active or false
- textbox.native_text_color = properties.native_text_color
- textbox.native_background_color = properties.native_background_color
- return setmetatable( textbox, Textbox )
- end
- function Textbox:draw()
- --# Format text( remove blocked characters )
- if self.blocked_chars then
- for i = 1, #self.blocked_chars do
- self.text = self.text:gsub( self.blocked_chars:sub( i, i ), "" )
- end
- end
- if self.allowed_chars then
- local _text = ""
- for i = 1, #self.text do
- for k = 1, #self.allowed_chars do
- if self.text:sub( i,i ) == self.allowed_chars:sub( k, k ) then
- _text = _text .. self.text:sub( i,i )
- break
- end
- end
- end
- self.text = _text
- end
- if self.pos > #self.text then
- self.pos = #self.text
- end
- --# Redraw text
- draw.line( self.x, self.y, self.width, self.native_text_color, self.native_background_color )
- term.setCursorPos( self.x + #self.text, self.y )
- term.write( " " )
- term.setCursorPos( self.x + 1, self.y )
- if self.placeholder then
- if #self.text == 0 then
- if self.placeholder.text_color then
- pcall( term.setTextColor, self.placeholder.text_color )
- end
- term.setCursorBlink( self.active and self.placeholder.cursor_blink or true )
- else
- if self.native_text_color then
- pcall( term.setTextColor, self.native_text_color )
- end
- end
- if self.mask then
- term.write( #self.text > 0 and string.rep( self.mask:sub(1,1), #self.text ) or self.placeholder.text )
- else
- term.write( #self.text > 0 and self.text or self.placeholder.text )
- end
- else
- term.write( self.mask and string.rep( self.mask:sub(1,1), #self.text ) or self.text )
- end
- if self.selected then
- term.setCursorBlink( self.active and false )
- pcall( term.setTextColor, self.marker and self.marker.text_color or colors.white )
- pcall( term.setBackgroundColor, self.marker and self.marker.background_color or colors.blue )
- local str = ""
- for i = self.sPos, self.fPos do
- str = str .. self.text:sub( i, i )
- end
- term.setCursorPos( self.x + 1 + (self.sPos-1), self.y )
- term.write( self.mask and string.rep( self.mask, #str ) or str )
- pcall( term.setTextColor, self.native_text_color )
- pcall( term.setBackgroundColor, self.native_background_color )
- else
- term.setCursorBlink( self.active and self.cursor_blink )
- end
- term.setCursorPos( self.placeholder and #self.text > 0 and self.x + 1 + self.pos or self.x + 1 + #self.placeholder.text, self.y )
- end
- function Textbox:handle( ... )
- term.setCursorBlink( self.active and self.cursor_blink )
- local function redraw()
- pcall( term.setTextColor, self.native_text_color )
- pcall( term.setBackgroundColor, self.native_background_color )
- term.setCursorPos( self.x, self.y )
- term.write( string.rep( " ", #self.text + 1 ) )
- end
- --# Handle events
- local e = { ... }
- if self.active then
- if e[1] == "char" then
- if self.placeholder.text and #self.text == 0 then
- for i = 1, #self.placeholder.text do
- term.setCursorPos( self.x + (i-1), self.y )
- term.write( " " )
- end
- end
- if not self.text_limit then
- if not self.selected then
- self.text = self.text:sub( 1, self.pos ) .. e[2] .. self.text:sub( self.pos + 1 )
- self.pos = self.pos + 1
- else
- redraw()
- self.text = self.text:sub( 1, self.sPos - 1 ) .. e[2] .. self.text:sub( self.fPos + 1 )
- self.pos = self.sPos
- self.selected = false
- end
- else
- if #self.text < self.text_limit then
- if not self.selected then
- self.text = self.text:sub( 1, self.pos ) .. e[2] .. self.text:sub( self.pos + 1 )
- self.pos = self.pos + 1
- else
- redraw()
- self.text = self.text:sub( 1, self.sPos - 1 ) .. e[2] .. self.text:sub( self.fPos + 1 )
- self.pos = self.sPos
- self.selected = false
- end
- else
- if self.selected then
- self.text = self.text:sub( 1, self.sPos - 1 ) .. e[2] .. self.text:sub( self.fPos + 1 )
- self.pos = self.pos + 1
- self.selected = false
- end
- end
- end
- elseif e[1] == "key" then
- if e[2] == 14 then
- if self.selected then
- redraw()
- self.text = self.text:sub( 1, self.sPos - 1 ) .. self.text:sub( self.fPos + 1 )
- self.selected = false
- self.pos = self.sPos - 1
- else
- if #self.text > 0 and self.pos > 0 then
- self.text = self.text:sub( 1, self.pos - 1 ) .. self.text:sub( self.pos + 1 )
- self.pos = self.pos - 1
- end
- end
- elseif e[2] == keys.left then
- self.selected = false
- self.pos = self.pos > 0 and self.pos - 1 or self.pos
- elseif e[2] == keys.right then
- self.selected = false
- self.pos = self.pos < #self.text and self.pos + 1 or self.pos
- elseif e[2] == 28 then
- self.active = false
- end
- elseif e[1] == "mouse_click" then
- if e[3] >= self.x + 1 and e[3] <= self.x + 1 + #self.text and e[4] == self.y then
- self.pos = e[3] - (self.x+1)
- self.mark = true
- self.mx = e[3]
- else
- self.mx = nil
- self.mark = false
- end
- if e[4] == self.y and e[3] > self.x + 1 + #self.text and e[3] <= self.x + (self.width-1) then
- self.pos = self.x + 2 + #self.text
- end
- self.selected = false
- if e[4] ~= self.y or e[3] < self.x or e[3] > self.x + ( self.width - 1 ) then
- self.active = false
- end
- elseif e[1] == "mouse_drag" then
- if self.mark then
- self.selected = true;
- if e[3] == self.mx then
- self.selected = false
- else
- self.selected = true
- if e[3] >= self.x + 1 and e[3] <= self.x + 1 + #self.text then
- if e[3] < self.mx then
- self.sPos = (e[3] - (self.x+1)) + 1;
- self.fPos = (self.mx - (self.x+1)) + 1;
- elseif e[3] > self.mx then
- self.sPos = (self.mx - (self.x+1)) + 1;
- self.fPos = (e[3] - (self.x+1)) + 1;
- end
- else
- if self.mx == self.x + #self.text then
- if e[3] > self.x + #self.text then
- self.selected = false;
- end
- end
- end
- end
- end
- end
- else
- if e[1] == "mouse_click" then
- if e[4] == self.y and e[3] >= self.x and e[3] <= self.x + ( self.width - 1 ) then
- self.active = true;
- end
- end
- end
- end
- Button = {}
- Button.__index = Button
- function Button.new( properties )
- local button = {}
- button.text = type( properties.text ) == "string" and properties.text or "Unlabeled"
- button.text_color = type( properties.text_color ) == "number" and properties.text_color or colors.white
- button.background_color = type( properties.background_color ) == "number" and properties.background_color or colors.red
- button.centered = type( properties.centered ) == "boolean" and properties.centered or false
- button.width = type( properties.width ) == "number" and properties.width or #button.text + 2
- button.y = type( properties.y ) == "number" and properties.y or error( "no y coordinate assigned",2 )
- if button.width < #button.text + 2 then
- button.width = #button.text + 2
- end
- button.x = button.centered and math.ceil( (w-button.width)/2 ) or type( properties.x ) == "number" and properties.x or error( "no x coordinate assigned", 2 )
- button.type = "button"
- button.action = type( properties.action ) == "function" and properties.action or nil
- return setmetatable( button, Button )
- end
- function Button:draw()
- draw.line( self.x, self.y, self.width, self.text_color, self.background_color )
- draw.midpoint( self.x, self.x + (self.width-1), self.y, self.text )
- end
- function Button:handle( ... )
- local e = { ... }
- if e[1] == "mouse_click" then
- if e[3] >= self.x and e[3] <= self.x + (self.width-1) and e[4] == self.y then
- if type( self.action ) == "function" then
- self.action( self )
- end
- end
- end
- end
- local function format_body( body, max_width )
- local formatted_body = {}
- for _, text in ipairs( body ) do
- if #text > max_width then
- local txt = ""
- for word in text:gmatch("%S+") do
- local str = txt
- if str ~= "" then
- str = str .. " " .. word
- else
- str = str .. word
- end
- if #str > max_width then
- table.insert( formatted_body, txt )
- txt = ""
- txt = txt .. word
- else
- if txt ~= "" then
- txt = txt .. " " .. word
- else
- txt = txt .. word
- end
- end
- end
- if txt ~= "" then
- table.insert( formatted_body, txt )
- end
- else
- table.insert( formatted_body, text )
- end
- end
- return formatted_body
- end
- Text = {}
- Text.__index = Text
- Text.new = function( properties )
- local text = {}
- local properties = properties or error( "no properties inputted", 2 )
- text.body = properties.body or error( "no body!", 2 )
- text.text_color = properties.text_color
- text.background_color = properties.background_color
- text.width = properties.width or nil
- text.x = properties.x
- text.y = properties.y
- text.centered = properties.centered or false
- if text.width then
- if type( text.body ) == "string" then
- local txt = text.body
- text.body = {}
- table.insert( text.body, txt )
- end
- text.body = format_body( text.body, text.width )
- end
- return setmetatable( text, Text )
- end
- function Text:draw()
- draw.setColors( self.text_color, self.background_color )
- if type( self.body ) == "string" then
- draw.at( self.centered == true and math.ceil( (w-#self.body)/2 ) or self.x, self.y, self.body )
- elseif type( self.body ) == "table" then
- for i = 1, #self.body do
- draw.at( self.centered and math.ceil((w-#self.body[i])/2) or self.x, self.y + (i-1), self.body[i] )
- end
- end
- end
- function Text:handle() end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement