Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Author: TheOriginalBIT
- Version: 2.0.4
- Created: 03 Jan 2013
- Last Update: 17 Feb 2013
- License:
- COPYRIGHT NOTICE
- Copyright © 2013 Joshua Asbury a.k.a TheOriginalBIT [theoriginalbit@gmail.com]
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
- associated documentation files (the "Software"), to deal in the Software without restriction,
- including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
- copies of the Software, and to permit persons to whom the Software is furnished to do so,
- subject to the following conditions:
- -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
- -Visible credit is given to the original author.
- -The software is distributed in a non-profit way.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- ]]--
- --[[ PRIVATE CLASS VARIABLES AND FUNCTIONS ]]--
- local version = 2.0
- local apiIdentifier = string.format( "Loading Bar API v%.2f Object", version )
- local sizeX, sizeY = term.getSize()
- local isAdvanced = term.isColor and term.isColor()
- local usedIds = {}
- local function generateId()
- if #usedIds > 999 then error( "Maximum load bars reached, you have used 999, how?! Tell me on the forum post! Better yet, SHOW ME!" ) end
- local objId = #usedIds
- while usedIds[ objId ] do
- objId = objId + 1
- if objId > 999 then
- objId = 1
- end
- end
- usedIds[ objId ] = true
- return objId
- end
- local function modeToText( mode )
- if mode == STANDARD then
- return "STANDARD"
- elseif mode == BAR_ONLY then
- return "BAR_ONLY"
- elseif mode == ASCII_BAR_ONLY then
- return "ASCII_BAR_ONLY"
- elseif mode == LOGO_IS_LOAD then
- return "LOGO_IS_LOAD"
- elseif mode == LOGO_IS_OVERLAY then
- return "LOGO_IS_OVERLAY"
- elseif mode == ASCII then
- return "ASCII"
- else
- return "UNKNOWN"
- end
- end
- local function hexLookup( char )
- local value = tonumber(char, 16)
- return ( value and math.pow(2, value) or false )
- end
- local function clearScreen( color )
- term.setCursorPos(1,1)
- if isAdvanced then
- term.setBackgroundColor( color or colors.blue )
- end
- term.clear()
- end
- local function isValidMode( mode )
- return mode ~= nil and ( mode >= STANDARD and mode <= ASCII )
- end
- local function isValidParams( mode, tLogo, count, barWidth, y, loadCol, openingMsg, headMsg, footMsg )
- if mode == STANDARD then
- if type( tLogo ) ~= "table" then
- return false, "Logo must be table, got "..type( tLogo )
- elseif type( count ) ~= "number" then
- return false, "Event count must be a number, got "..type( count )
- elseif type( barWidth ) ~= "number" then
- return false, "Bar width must be a number, got "..type( barWidth )
- elseif type( y ) ~= "number" then
- return false, "Y position must be a number, got "..type( y )
- elseif type( loadCol ) ~= "number" then
- return false, "Load bar color must be a number, got "..type( loadCol )
- elseif type( loadCol ) == "number" and ( ( loadCol < 1 ) or ( loadCol > ( 2^16 ) - 1 ) ) then
- return false, "Invalid load bar color, must be in range 1-65535, got "..loadCol
- elseif type( openingMsg ) ~= "string" and type( openingMsg ) ~= "nil" then
- return false, "Invalid opening message, expected string or nil, got "..type( openingMsg )
- elseif type( headMsg ) ~= "string" and type( headMsg ) ~= "nil" then
- return false, "Invalid header message, expected string or nil, got "..type( headMsg )
- elseif type( footMsg ) ~= "string" and type( footMsg ) ~= "nil" then
- return false, "Invalid footer message, expected string or nil, got "..type( footMsg )
- end
- return true, nil
- elseif mode == BAR_ONLY then
- if type( tLogo ) ~= "nil" then
- return false, "Logo must be nil, got "..type( tLogo )
- elseif type( count ) ~= "number" then
- return false, "Event count must be a number, got "..type( count )
- elseif type( barWidth ) ~= "number" then
- return false, "Bar width must be a number, got "..type( barWidth )
- elseif type( y ) ~= "number" then
- return false, "Y position must be a number, got "..type( y )
- elseif type( loadCol ) ~= "number" then
- return false, "Load bar color must be a number, got "..type( loadCol )
- elseif type( loadCol ) == "number" and ( ( loadCol < 1 ) or ( loadCol > ( 2^16 ) - 1 ) ) then
- return false, "Invalid load bar color, must be in range 1-65535, got "..loadCol
- elseif type( openingMsg ) ~= "string" and type( openingMsg ) ~= "nil" then
- return false, "Invalid opening message, expected string or nil, got "..type( openingMsg )
- elseif type( headMsg ) ~= "string" and type( headMsg ) ~= "nil" then
- return false, "Invalid header message, expected string or nil, got "..type( headMsg )
- elseif type( footMsg ) ~= "string" and type( footMsg ) ~= "nil" then
- return false, "Invalid footer message, expected string or nil, got "..type( footMsg )
- end
- return true, nil
- elseif mode == ASCII_BAR_ONLY then
- if type( tLogo ) ~= "nil" then
- return false, "Logo must be nil, got "..type( tLogo )
- elseif type( count ) ~= "number" then
- return false, "Event count must be a number, got "..type( count )
- elseif type( barWidth ) ~= "number" then
- return false, "Bar width must be a number, got "..type( barWidth )
- elseif type( y ) ~= "number" then
- return false, "Y position must be a number, got "..type( y )
- elseif type( loadCol ) ~= "nil" then
- return false, "Load bar color must be nil, got "..type( loadCol )
- elseif type( loadCol ) == "number" and ( ( loadCol < 1 ) or ( loadCol > ( 2^16 ) - 1 ) ) then
- return false, "Invalid load bar color, must be in range 1-65535, got "..loadCol
- elseif type( openingMsg ) ~= "string" and type( openingMsg ) ~= "nil" then
- return false, "Invalid opening message, expected string or nil, got "..type( openingMsg )
- elseif type( headMsg ) ~= "string" and type( headMsg ) ~= "nil" then
- return false, "Invalid header message, expected string or nil, got "..type( headMsg )
- elseif type( footMsg ) ~= "string" and type( footMsg ) ~= "nil" then
- return false, "Invalid footer message, expected string or nil, got "..type( footMsg )
- end
- return true, nil
- elseif mode == LOGO_IS_LOAD or mode == LOGO_IS_OVERLAY then
- if type( tLogo ) ~= "table" then
- return false, "Logo must be table, got "..type( tLogo )
- elseif type( count ) ~= "number" then
- return false, "Event count must be a number, got "..type( count )
- elseif type( barWidth ) ~= "nil" then
- return false, "Bar width must be a nil, got "..type( barWidth )
- elseif type( y ) ~= "number" then
- return false, "Y position must be a number, got "..type( y )
- elseif mode == LOGO_IS_LOAD and type( loadCol ) ~= "number" then
- return false, "Load bar color must be a number, got "..type( loadCol )
- elseif mode == LOGO_IS_OVERLAY and type( loadCol ) ~= "nil" then
- return false, "Load bar color must be nil, got "..type( loadCol )
- elseif type( loadCol ) == "number" and ( ( loadCol < 1 ) or ( loadCol > ( 2^16 ) - 1 ) ) then
- return false, "Invalid load bar color, must be in range 1-65535, got "..loadCol
- elseif type( openingMsg ) ~= "string" and type( openingMsg ) ~= "nil" then
- return false, "Invalid opening message, expected string or nil, got "..type( openingMsg )
- elseif type( headMsg ) ~= "string" and type( headMsg ) ~= "nil" then
- return false, "Invalid header message, expected string or nil, got "..type( headMsg )
- elseif type( footMsg ) ~= "string" and type( footMsg ) ~= "nil" then
- return false, "Invalid footer message, expected string or nil, got "..type( footMsg )
- end
- return true, nil
- elseif mode == ASCII then
- if type( tLogo ) ~= "table" then
- return false, "Logo must be table, got "..type( tLogo )
- elseif type( count ) ~= "number" then
- return false, "Event count must be a number, got "..type( count )
- elseif type( barWidth ) ~= "number" then
- return false, "Bar width must be a number, got "..type( barWidth )
- elseif type( y ) ~= "number" then
- return false, "Y position must be a number, got "..type( y )
- elseif type( loadCol ) ~= "nil" then
- return false, "Load bar color must be a nil, got "..type( loadCol )
- elseif type( loadCol ) == "number" and ( ( loadCol < 1 ) or ( loadCol > ( 2^16 ) - 1 ) ) then
- return false, "Invalid load bar color, must be in range 1-65535, got "..loadCol
- elseif type( openingMsg ) ~= "string" and type( openingMsg ) ~= "nil" then
- return false, "Invalid opening message, expected string or nil, got "..type( openingMsg )
- elseif type( headMsg ) ~= "string" and type( headMsg ) ~= "nil" then
- return false, "Invalid header message, expected string or nil, got "..type( headMsg )
- elseif type( footMsg ) ~= "string" and type( footMsg ) ~= "nil" then
- return false, "Invalid footer message, expected string or nil, got "..type( footMsg )
- end
- return true, nil
- end
- return false, "Something went seriously wrong, please report this bug with the code 169:"..tostring( mode ).." and your call to this api."
- end
- local function getYFromMode( mode, logo, y )
- if mode == STANDARD or mode == BAR_ONLY or mode == ASCII_BAR_ONLY or mode == ASCII then
- return ( y + 1 > sizeY and (y - 1) < 1) and sizeY - 4 or y
- elseif mode == LOGO_IS_LOAD or mode == LOGO_IS_OVERLAY then
- return math.ceil( sizeY / 2 - #logo / 2 )
- end
- end
- local function getWidthFromMode( mode, logo, width )
- if mode == STANDARD or mode == BAR_ONLY or mode == ASCII_BAR_ONLY or mode == ASCII then
- return width or 20
- elseif mode == LOGO_IS_LOAD or mode == LOGO_IS_OVERLAY then
- return logo[1] ~= nil and #logo[1] or 20
- end
- end
- local function draw_header_footer( data )
- if isAdvanced then
- term.setBackgroundColor( colors.white )
- term.setTextColor( colors.black )
- end
- term.setCursorPos( math.ceil( sizeX / 2 ) - math.ceil( string.len( data.headerMessage ) / 2 ), 1 )
- write( data.headerMessage )
- term.setCursorPos( math.ceil( sizeX / 2 ) - math.ceil( string.len( data.footerMessage ) / 2 ), sizeY )
- write( data.footerMessage )
- end
- local function draw_box( data )
- for x = 1, data.barWidth + 2 do
- for y = 1, 3 do
- term.setCursorPos( (sizeX - data.barWidth - 1) / 2 + x - 1, data.yPos + y -2 )
- local char = " "
- if x == 1 and y == 1 or x == data.barWidth + 2 and y == 1 then
- char = "."
- elseif x == 1 and y == 3 or x == data.barWidth + 2 and y == 3 then
- char = "'"
- elseif x == 1 or x == data.barWidth + 2 then
- char = "|"
- elseif y == 1 then
- char = "_"
- elseif y == 3 then
- char = "-"
- end
- write( char )
- end
- end
- end
- local function draw_progress_bar( self )
- if self.mode == ASCII_BAR_ONLY or self.mode == ASCII then
- draw_box( self.data )
- end
- for i = 1, self.data.barWidth do
- term.setCursorPos( (sizeX - self.data.barWidth) / 2 + i, self.data.yPos)
- local char = ' '
- if i < (( self.data.currentEventCount / self.data.totalEventCount ) * self.data.barWidth + 1) then
- if isAdvanced and self.data.barColor then
- term.setBackgroundColor( self.data.barColor )
- else
- char = '|'
- end
- else
- if isAdvanced and self.data.barColor then
- term.setBackgroundColor( colors.gray )
- end
- end
- write( char )
- end
- end
- local function draw_message( self )
- if self.data.progressMessage then
- term.setCursorPos( sizeX / 2 - self.data.progressMessage:len() / 2, sizeY - 3 )
- if isAdvanced then
- term.setTextColor( colors.black )
- term.setBackgroundColor( colors.white )
- end
- term.clearLine()
- term.write( self.data.progressMessage )
- end
- end
- local function drawScreen( self )
- if not ( self.mode == BAR_ONLY or self.mode == ASCII_BAR_ONLY ) then
- draw_header_footer( self.data )
- end
- for row = 1, #self.data.logo do
- for col = 1, self.data.logo[row]:len() do
- term.setCursorPos( math.ceil( sizeX / 2 - #self.data.logo[1] / 2 ) + col, self.data.isLogoLoad and self.data.yPos + row or (math.ceil( sizeY / 2 - #self.data.logo / 2 ) + row) - 2 )
- local char = self.data.logo[row]:sub( col, col )
- if char ~= " " then
- if not self.data.isLogoLoad or col > ( ( self.data.currentEventCount / self.data.totalEventCount ) * self.data.logo[1]:len() + ( self.data.currentEventCount == 0 and self.data.currentEventCount or 1 ) ) then
- if not ( self.mode == LOGO_IS_OVERLAY ) then
- term.setBackgroundColor( hexLookup( char ) )
- else
- term.setBackgroundColor( colors.lightGray )
- end
- else
- if not ( self.mode == LOGO_IS_OVERLAY ) then
- term.setBackgroundColor( self.data.barColor )
- else
- term.setBackgroundColor( hexLookup( char ) )
- end
- end
- write(" ")
- end
- end
- print()
- end
- if not self.data.isLogoLoad then
- draw_progress_bar( self )
- end
- if not ( self.mode == BAR_ONLY or self.mode == ASCII_BAR_ONLY ) then
- draw_message( self )
- end
- end
- local function drawScreenASCII( self )
- if not ( self.mode == BAR_ONLY or self.mode == ASCII_BAR_ONLY ) then
- draw_header_footer( self.data )
- end
- for row = 1, #self.data.logo do
- for col = 1, self.data.logo[row]:len() do
- term.setCursorPos( math.ceil( sizeX / 2 - #self.data.logo[1] / 2 ) + col, (math.ceil( sizeY / 2 - #self.data.logo / 2 ) + row) - 2 )
- local char = self.data.logo[row]:sub( col, col )
- if char ~= " " then
- if col > ( ( self.data.currentEventCount / self.data.totalEventCount ) * self.data.logo[1]:len() + ( self.data.currentEventCount == 0 and self.data.currentEventCount or 1 ) ) then
- write( char )
- end
- end
- end
- print()
- end
- draw_progress_bar( self )
- if not ( self.mode == BAR_ONLY or self.mode == ASCII_BAR_ONLY ) then
- draw_message( self )
- end
- end
- --[[ PUBLIC CLASS VARIABLES AND FUNCTIONS ]]--
- function getVersion() return version end
- function getApiIdentifier() return apiIdentifier end
- --[[ OBJECT ]]--
- load = {}
- load.__index = load
- load.__tostring = function( self ) return apiIdentifier end
- load.__gc = function( self ) usedIds[ self.id ] = nil self.data.logo = nil self.data = nil self = nil end
- --[[ GETTERS ]]--
- function load.getId( self )
- return self.id
- end
- function load.getCurrentProgress( self )
- return self.data.currentEventCount
- end
- function load.getFormattedProgress( self )
- return self.data.currentEventCount.."/"..self.data.totalEventCount
- end
- --[[ SETTERS ]]--
- function load.setMessage( self, msg )
- if not self.data then error( "Object does not exist", 2 ) end
- self.data.progressMessage = msg
- os.queueEvent( "load_update_"..self.id )
- end
- --[[ CONTRUCTORS / DESTRUCTORS ]]--
- function init( lmode, tLogo, count, width, y, loadColor, openingMsg, headMsg, footMsg )
- if not isValidMode( lmode ) then error( "Bad argument: Invalid mode: "..type( lmode ).." : "..tostring( lmode ), 2 ) end
- if not isAdvanced and ( lmode ~= ASCII_BAR_ONLY and lmode ~= ASCII ) then error( "Invalid mode: Can only run in ASCII mode, attempted "..modeToText( lmode ), 2 ) end
- local valid, errorMsg = isValidParams( lmode, tLogo, count, width, y, loadColor, openingMsg, headMsg, footMsg )
- if not valid then error( "Bad argument: Invalid paramters for mode: "..modeToText( lmode ).." : "..errorMsg, 2 ) end
- local loadObject = { id = generateId(), data = {
- isLogoLoad = ( lmode == LOGO_IS_LOAD or lmode == LOGO_IS_OVERLAY ),
- isAscii = ( lmode == ASCII_BAR_ONLY or lmode == ASCII ),
- isBarOnly = ( lmode == BAR_ONLY or lmode == ASCII_BAR_ONLY ),
- logo = type( tLogo ) == "table" and tLogo or {},
- barWidth = getWidthFromMode( lmode, tLogo, width ),
- yPos = getYFromMode( lmode, tLogo, y ),
- barColor = loadColor,
- totalEventCount = count,
- currentEventCount = 0,
- progressMessage = openingMsg or "",
- headerMessage = headMsg or "",
- footerMessage = footMsg or "",
- }, mode = lmode }
- setmetatable( loadObject, load )
- return loadObject
- end
- function load.dealloc( self )
- usedIds[ self.id ] = nil
- self.data.logo = nil
- self.data = nil
- self = nil
- end
- --[[ OBJECT FUNCTIONS ]]--
- function load.reset( self )
- if not self.data then error( "Object does not exist", 2 ) end
- self.data.currentEventCount = 0
- end
- function load.forceStop( self )
- if not self.data then error( "Object does not exist", 2 ) end
- self.data.currentEventCount = self.data.totalEventCount
- os.queueEvent( "load_update_"..self.id )
- end
- function load.triggerUpdate( self, msg )
- if not self.data then error( "Object does not exist", 2 ) end
- self.data.currentEventCount = self.data.currentEventCount + 1
- if msg and msg:len() ~= 0 then self.data.progressMessage = msg end
- os.queueEvent( "load_update_"..self.id )
- end
- function load.removeMessage( self )
- if not self.data then error( "Object does not exist", 2 ) end
- self.data.progressMessage = ""
- os.queueEvent( "load_update_"..self.id )
- end
- function load.forceDraw( self )
- if not self.data then return end
- if not ( self.mode == BAR_ONLY or self.mode == ASCII_BAR_ONLY ) then error( "Object function can only be called in mode: BAR_ONLY and ASCII_BAR_ONLY", 2 ) end
- draw_progress_bar( self )
- end
- function load.run( self, cleanup )
- if not self.data then error( "Object is not initialized", 2 ) end
- if self.mode ~= BAR_ONLY and self.mode ~= ASCII_BAR_ONLY then
- clearScreen( colors.white )
- end
- if self.data.isAscii then
- drawScreenASCII( self )
- else
- drawScreen( self )
- end
- while true do
- if self.data.currentEventCount == self.data.totalEventCount then break end
- event = { os.pullEventRaw( "load_update_"..self.id ) }
- if self.mode == BAR_ONLY or self.mode == ASCII_BAR_ONLY then
- draw_progress_bar( self )
- elseif self.mode == ASCII then
- drawScreenASCII( self )
- else
- drawScreen( self )
- end
- end
- if cleanup == true then self:dealloc() end
- end
- STANDARD = 1 -- Load screen with logo, text and bar
- BAR_ONLY = 2 -- Progress bar only
- ASCII_BAR_ONLY = 3 -- Progress bar only - in ascii
- LOGO_IS_LOAD = 4 -- Load screen with logo and text - no bar, logo is progress indicator
- LOGO_IS_OVERLAY = 5 -- Load screen with logo and text - no bar, logo is progress indicator ( initially greyed out )
- ASCII = 6 -- Load screen with logo, text and bar - in ascii
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement