Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Coded By HPWebcamAble
- ==== Description ====
- This is my Screen API
- It allows you to add shapes (called Objects) and Click Areas to Screens
- You can have as many Screens as you want.
- See the CC Forum Post in 'Documentation' for a quick start guide
- ==== Documentation ====
- Computer Craft Forum Post:
- http://www.computercraft.info/forums2/index.php?/topic/22061-screen-api/
- Scroll down to 'Functions and How to Use Them' for info on each function
- Remember, only 'draw' and 'drawObject' actually change anything on the monitor/computer's physical screen
- ==== Installation ====
- Pastebin Code:4j4mJsWw
- This won't do anything on its own. You use this to help write your programs
- You have two options:
- 1. Copy and paste the functions into your program and call them like you would normally call a function
- 2. In your program, call os.loadAPI("filename"), then call functions with filename.functionName()
- ==== Update History ====
- The pastebin will always have the latest version
- |2.0|
- -Each individual screen is an object now
- *You still call the functions with a period (.), not a colon (:)
- *Note that the default elements are universal, they are the same for every screen you make
- -Cleaned up the code
- -Slightly changed how text is centered on objects (again)
- *Should be centered, or 1 pixel to the left if that isn't possible
- -Removed 'state', replaced with 'visble' (objects only) and 'clickable'
- *Added toggleVisible function for Objects
- *Added toggleClickable function for both element types
- *Removed toggleState function
- -Added getObject and getClickArea to allow changing of text, position, etc
- -Updated documentation (See 'Functions and How to Use Them' below)
- |1.3|
- -Changed how object states are stored in preparation for Simple Screen Maker 2!
- -Touched up the documentation section
- -Fixed a few typos
- -toFill function now recognizes false values
- |1.2.5|
- -Fixed a slight bug when drawing text on an object
- *It now centers correctly
- |1.2.4|
- -Fixed text sometimes being drawn off center
- -Added setObjectText
- |1.2.3|
- -Fixed a *kinda* major issue with drawing objects
- *A row of pixels was always missing on the right side
- -The default for 'hasClickArea' for objects is now 'false'
- |1.2.2|
- -Function descriptions are now in 'Functions and How to Use Them' section
- -handleEvents can now trigger 'object' events (Same arguments as Click Areas)
- -checkPos now returns "click_area" or "object" and its name or the result of its action
- -Fixed bug that caused 'off' objects to be triggered when clicked
- *Objects no longer make a click area when created, both object boundries and click area boundries are checked by checkPos
- |1.2.1|
- -Fixed bug that caused the text of a button to be put in weird places
- |1.2|
- -Changed 'checkPos' to 'handleEvents'
- *Use instead of os.pullEvent()
- *If a Click Area is clicked, it triggers the event 'click_area' (if it doens't have a function)
- -Arguments are name,mouse button
- -'toggleObject' enables or disables an object
- -'toggleObjectState' is what makes an object use on or off
- |1.1|
- -Added a default object and clickArea
- *If you leave out something when adding, the values will be filled in
- *You can change the defaults with setDefaultObject and setDefaultClickArea
- -Added much more descriptive errors
- -Added a 'drawObject' function, to draw a single object
- -Fixed a few bugs with the states of Click Areas
- |1.0|
- -Release
- ==== Functions and How to Use Them ====
- API Functions (The API has these):
- new(nBackground)
- Creates a new screen, and returns its pointer
- If you supply a background, the computer's screen will be cleared each time
- you call draw(). Otherwise, the screen will not be cleared.
- Screen Functions (Only screen object have these):
- handleEvents(bUseRaw)
- *Use this in place of os.pullEvent()*
- It will automatically check if mouse_click events are in an Object or Click Area
- If an element has an action, it will return nil
- If not, it returns:
- <type of element>,<name>,<mouse button used>
- If an element wasn't clicked, it returns an event like os.pullEvent would
- Pass true to bUseRaw to use os.pullEventRaw() instead of os.pullEvent()
- checkPos(x,y)
- Called by handleEvents
- Checks if <x> and <y> are in an Object or Click Area
- If something was clicked and it had an action, it returns:
- true,true,<result of action function>
- If it didn't have an action:
- true,false,<element type>,<name>
- If nothing was clicked, it returns false
- draw()
- Clears the screen, if a background was supplied when the screen was created
- Calls 'drawObject' for each object
- Click Areas:
- Example Click Area Info:
- {
- name = "ClickAreaExample", --String, stored by name. If not specified, its name is set to '<x>:<y>'
- minX = 1, --int, the smallest X coordinate, the farthest left side of the button
- maxX = 5, --int, the largest X coordinate, the farthest right side of the button
- minY = 1, --int, the smallest Y coordinate, the highest part of the button
- maxY = 3, --int, the largest Y coordinate, the lowest part of the button
- action = function() print("HI") end --What happens if the area is clicked. Optional
- }
- addClickArea(clickAreaInfo)
- <clickAreaInfo> is a table that describes the Click Area
- Leaving out a value will use the default (See the default table below)
- toggleClickArea(name)
- Enables or disables a Click Area
- Disabled Click Areas aren't triggered when clicked
- Returns the new state (true or false)
- setDefaultClickArea(clickAreaInfo)
- Sets the default Click Area
- Any values that are left out when creating a Click Area
- are filled in with the existing default Click Area
- getClickArea(name)
- Returns the pointer of a Click Area so that its various fields can be
- modified
- Object Functions:
- Example Object Info:
- {
- text = "test", --string, what the object shows, use false or nil for nothing
- name = "Example", --string, the object is stored by its name. Use this to manipulate the object
- minX = 1, --int, the smallest X coordinate, the farthest left side
- maxX = 5, --int, the largest X coordinate, the farthest right side
- minY = 1, --int, the smallest Y coordinate, the highest part
- maxY = 3, --int, the largest Y coordinate, the lowest part
- states = { --table, a list of possible states the object can have
- on = {text = colors.black, back = colors.white}, --table, this state is called 'on', the text will be black and the background of the object will be white
- off = {text = colors.white, back = colors.black} --table, this state is called 'off', it is the opposite of 'on' (though it can be any colors you want)
- },
- hasClickArea = true --boolean, true if the object should be clickable
- action = function() print("HI") end --function, runs if the object is clicked. Only works if hasClickArea is true
- state = "on" --string, what state the object should start in
- }
- addObject(objectInfo)
- <objectInfo> is a table that describes the Object
- Leaving out a value of <objectInfo> will use the default (See default table below)
- drawObject(name)
- Draws a single Object
- Skips objects that aren't visible
- toggleObjectState(name,screen)
- Note that this is NOT toggleObject
- Turns on object on or off
- Leaving <screen> blank will use the default screen
- Returns the new state (true or false)
- toggleObjectState(name)
- Toggles between an Object's states
- NOTE: Only works if the Object has exactly two states
- Returns the new state
- toggleObjectVisible(name)
- Objects that aren't visible will be skipped by 'drawObject'
- Returns new state (true or false)
- toggleObjectClickable(name)
- Objects that aren't clickable will be skipped by 'checkPos'
- Returns new state (true or false)
- setDefaultObject(objectInfo)
- Sets the default object
- Any values that are left out will be filled in with the default object
- getObject(name)
- Returns the pointer of an Object so that its various fields can be
- modified
- ]]
- local default = {
- object = {
- text = nil,
- name = "default",
- minX = 1,minY = 1,
- maxX = 7,maxY = 3,
- states = {
- on = {text = colors.white, back = colors.lime},
- off = {text = colors.white, back = colors.red}
- },
- clickable = false,
- visible = true,
- state = "off",
- action = nil
- },
- clickArea = {
- name = "default",
- minX = 1,minY = 1,
- maxX = 5,maxY = 3,
- clickable = true,
- action = nil
- }
- }
- local function fillTable(toFill,fillWith) --Used by the API
- if toFill == nil then toFill = {} end
- for a,b in pairs(fillWith) do
- if type(b) == "table" then
- toFill[a] = fillTable(toFill[a],b)
- else
- toFill[a] = toFill[a]==nil and b or toFill[a]
- end
- end
- return toFill
- end
- local function countIndexes(tbl) --Also used by API
- local total = 0
- for a,b in pairs(tbl) do total = total+1 end
- return total
- end
- local function assert(check,err,lvl)
- lvl = lvl or 2
- if not check then error(err,lvl+1) end
- return check
- end
- function new(nBackground)
- local api = {}
- local objects = {}
- local clickAreas = {}
- local background = nBackground
- function api.checkPos(x,y)
- x,y = tonumber(x),tonumber(y)
- assert(x and y,"expected number,number")
- for name,data in pairs(clickAreas) do
- if x >= data.minX and x <= data.maxX and y >= data.minY and y <= data.maxY and data.clickable then
- if type(data.action)=="function" then return true,true,data.action()
- else return true,false,"click_area",name end
- end
- end
- for name,data in pairs(objects) do
- if data.clickable and data.visible and x >= data.minX and x <= data.maxX and y >= data.minY and y <= data.maxY then
- if type(data.action)=="function" then return true,true,data.action()
- else return true,false,"object",name end
- end
- end
- return false
- end
- function api.handleEvents(bUseRaw)
- local pull = bUseRaw and os.pullEventRaw or os.pullEvent
- local event = {pull()}
- if event[1] == "mouse_click" then
- local wasElement,hadFunction,elementType,name = api.checkPos(event[3],event[4])
- if wasElement then
- if not hadFunction then
- return elementType,name,event[2]
- else return nil
- end
- end
- end
- return unpack(event)
- end
- function api.setDefaultObject(newDefaultObject)
- assert(type(newDefaultObject)=="table","expected table, got "..type(newDefaultObject))
- default.object = fillTable(newDefaultObject,default.object)
- end
- function api.setDefaultClickArea(newDefaultClickArea)
- assert(type(newDefaultClickArea)=="table","expected table, got "..type(newDefaultClickArea))
- default.clickArea = fillTable(newDefaultClickArea,default.clickArea)
- end
- function api.draw()
- if background then term.setBackgroundColor(background) term.clear() end
- for name,data in pairs(objects) do
- api.drawObject(name)
- end
- end
- function api.addClickArea(clickAreaInfo)
- assert(type(clickAreaInfo)=="table","expected table, got "..type(clickAreaInfo))
- fillTable(clickAreaInfo,default.clickArea)
- assert(clickAreas[clickAreaInfo.name]==nil,"an object with the name '"..clickAreaInfo.name.."' already exists")
- clickAreas[clickAreaInfo.name] = clickAreaInfo
- end
- function api.toggleClickArea(name)
- assert(clickAreas[name]~=nil,"Click Area '"..name.."' doesn't exist")
- clickAreas[name].clickable = not clickAreas[name].clickable
- return clickAreas[name].clickable
- end
- function api.getClickArea(name)
- assert(clickAreas[name]~=nil,"Click Area '"..name.."' doesn't exist")
- return clickAreas[name]
- end
- function api.addObject(objectInfo)
- assert(type(objectInfo)=="table","expected table, got "..type(objectInfo))
- objectInfo = fillTable(objectInfo,default.object)
- assert(objects[objectInfo.name]==nil,"an object with the name '"..objectInfo.name.."' already exists")
- objects[objectInfo.name] = objectInfo
- end
- function api.drawObject(name)
- assert(objects[name]~=nil,"Object '"..name.."' doesn't exsist")
- local objData = objects[name]
- if objData.visible == false then return end
- assert(objData.states~=nil,"Object '"..name.."' has no states!")
- assert(objData.states[objData.state],"Object '"..name.."' doesn't have state '"..objData.state.."'")
- term.setBackgroundColor(objData.states[objData.state].back)
- term.setTextColor(objData.states[objData.state].text)
- for i = 0, objData.maxY-objData.minY do
- term.setCursorPos(objData.minX,objData.minY+i)
- term.write(string.rep(" ",objData.maxX-objData.minX+1))
- end
- if objData.text then
- local xPos = objData.minX+math.floor(((objData.maxX-objData.minX+1)-#objData.text)/2)
- local yPos = objData.minY+(objData.maxY-objData.minY)/2
- term.setCursorPos(xPos,yPos) term.write(objData.text)
- end
- end
- function api.toggleObjectState(name) -- Only works if an object has two states
- assert(objects[name]~=nil,"Object '"..name.."' doesn't exist")
- assert(countIndexes(objects[name].states)==2,"Object '"..name.."' can't be toggled, it doesn't have two states")
- curState = objects[name].state
- for a,b in pairs(objects[name].states) do
- if a ~= curState then
- objects[name].state = a
- end
- end
- return objects[name].state
- end
- function api.setObjectState(name,state)
- assert(objects[name] ~= nil,"Object '"..name.."' doesn't exist")
- assert(objects[name].states[state],"Object '"..name.."' doesn't have state '"..state.."'")
- objects[name].state = state
- end
- function api.getObject(name)
- assert(objects[name] ~= nil,"Object '"..name.."' doesn't exist")
- return objects[name]
- end
- function api.toggleObjectVisible(name)
- assert(objects[name] ~= nil,"Object '"..name.."' doesn't exist")
- objects[name].visible = not objects[name].visible
- return objects[name].visible
- end
- function api.toggleObjectClickable(name)
- assert(objects[name] ~= nil,"Object '"..name.."' doesn't exist")
- objects[name].clickable = not objects[name].clickable
- return objects[name].clickable
- end
- return api
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement