diff --git a/Basalt/Frame.lua b/Basalt/Frame.lua index ad57199..6ba3875 100644 --- a/Basalt/Frame.lua +++ b/Basalt/Frame.lua @@ -1,12 +1,12 @@ local Object = require("Object") local _OBJECTS = require("loadObjects") - local BasaltDraw = require("basaltDraw") local utils = require("utils") local layout = require("layout") local uuid = utils.uuid local rpairs = utils.rpairs local xmlValue = utils.getValueFromXML +local tableCount = utils.tableCount local sub,min,max = string.sub,math.min,math.max @@ -17,6 +17,8 @@ return function(name, parent, pTerm, basalt) local objects = {} local objZIndex = {} local object = {} + local events = {} + local eventZIndex = {} local variables = {} local theme = {} local dynamicValues = {} @@ -29,15 +31,20 @@ return function(name, parent, pTerm, basalt) local dragXOffset = 0 local dragYOffset = 0 local isScrollable = false - local minScroll = 0 - local maxScroll = 10 + local scrollAmount = 0 local mirrorActive = false local mirrorAttached = false local mirrorSide = "" - local importantScroll = false + local isMovable = false + local isDragging =false - local focusedOBjectCache + local focusedObjectCache local focusedObject + local autoSize = true + local autoScroll = true + local initialized = false + + local activeEvents = {} base:setZIndex(10) @@ -70,17 +77,6 @@ return function(name, parent, pTerm, basalt) end end - if (parent ~= nil) then - base.parent = parent - base.width, base.height = parent:getSize() - base.bgColor = parent:getTheme("FrameBG") - base.fgColor = parent:getTheme("FrameText") - else - base.width, base.height = termObject.getSize() - base.bgColor = basalt.getTheme("BasaltBG") - base.fgColor = basalt.getTheme("BasaltText") - end - local function getObject(name) for _, value in pairs(objects) do for _, b in pairs(value) do @@ -135,11 +131,94 @@ return function(name, parent, pTerm, basalt) return obj end + local function removeEvents(self, obj) + for a, b in pairs(events) do + for c, d in pairs(b) do + for key, value in pairs(d) do + if (value == obj) then + table.remove(events[a][c], key) + if(self.parent~=nil)then + if(tableCount(events[event])<=0)then + self.parent:removeEvent(a, self) + end + end + end + end + end + end + end + local function removeObject(obj) for a, b in pairs(objects) do for key, value in pairs(b) do if (value == obj) then table.remove(objects[a], key) + removeEvents(object, obj) + return true; + end + end + end + return false + end + + local function getEvent(self, event, name) + for _, value in pairs(events[event]) do + for _, b in pairs(value) do + if (b:getName() == name) then + return b + end + end + end + end + + local function addEvent(self, event, obj) + local zIndex = obj:getZIndex() + if(events[event]==nil)then events[event] = {} end + if(eventZIndex[event]==nil)then eventZIndex[event] = {} end + if (getEvent(self, event, obj.name) ~= nil) then + return nil + end + if(self.parent~=nil)then + self.parent:addEvent(event, self) + end + activeEvents[event] = true + if (events[event][zIndex] == nil) then + for x = 1, #eventZIndex[event] + 1 do + if (eventZIndex[event][x] ~= nil) then + if (zIndex == eventZIndex[event][x]) then + break + end + if (zIndex > eventZIndex[event][x]) then + table.insert(eventZIndex[event], x, zIndex) + break + end + else + table.insert(eventZIndex[event], zIndex) + end + end + if (#eventZIndex[event] <= 0) then + table.insert(eventZIndex[event], zIndex) + end + events[event][zIndex] = {} + end + table.insert(events[event][zIndex], obj) + return obj + end + + local function removeEvent(self, event, obj) + for a, b in pairs(events[event]) do + for key, value in pairs(b) do + if (value == obj) then + table.remove(events[event][a], key) + if(#events[event][a]<=0)then + events[event][a] = nil + if(self.parent~=nil)then + if(tableCount(events[event])<=0)then + activeEvents[event] = false + self.parent:removeEvent(event, self) + end + end + end return true; end end @@ -217,7 +296,7 @@ return function(name, parent, pTerm, basalt) end - local function recalculateDynamicValues() + local function recalculateDynamicValues(self) if(#dynamicValues>0)then for n=1,dynValueId do if(dynamicValues[n]~=nil)then @@ -225,6 +304,18 @@ return function(name, parent, pTerm, basalt) if(#dynamicValues[n][3]<=0)then dynamicValues[n][3] = dynValueGetObjects(dynamicValues[n][4], dynamicValues[n][2]) end numberStr = dynValueObjectToNumber(dynamicValues[n][2], dynamicValues[n][3]) dynamicValues[n][1] = stringToNumber(numberStr) + if(dynamicValues[n][4]:getType()=="Frame")then + dynamicValues[n][4]:recalculateDynamicValues() + end + end + end + for _, index in pairs(objZIndex) do + if (objects[index] ~= nil) then + for _, value in pairs(objects[index]) do + if (value.eventHandler ~= nil) then + value:eventHandler("dynamicValueEvent", self) + end + end end end end @@ -234,6 +325,30 @@ return function(name, parent, pTerm, basalt) return dynamicValues[id][1] end + local function calculateMaxScroll(self) + for _, value in pairs(objects) do + for _, b in pairs(value) do + if(b.getHeight~=nil)and(b.getY~=nil)then + local h, y = b:getHeight(), b:getY() + if (h + y - self:getHeight() > scrollAmount) then + scrollAmount = max(h + y - self:getHeight(), 0) + end + end + end + end + end + + local function focusSystem(self) + if(focusedObject~=focusedObjectCache)then + if(focusedObject~=nil)then + focusedObject:loseFocusHandler() + end + if(focusedObjectCache~=nil)then + focusedObjectCache:getFocusHandler() + end + focusedObject = focusedObjectCache + end + end object = { barActive = false, @@ -241,7 +356,11 @@ return function(name, parent, pTerm, basalt) barTextcolor = colors.black, barText = "New Frame", barTextAlign = "left", - isMoveable = false, + + addEvent = addEvent, + removeEvent = removeEvent, + removeEvents = removeEvents, + getEvent = getEvent, newDynamicValue = newDynamicValue, recalculateDynamicValues = recalculateDynamicValues, @@ -252,7 +371,7 @@ return function(name, parent, pTerm, basalt) end; setFocusedObject = function(self, obj) - focusedOBjectCache = obj + focusedObjectCache = obj return self end; @@ -262,25 +381,35 @@ return function(name, parent, pTerm, basalt) setSize = function(self, w, h, rel) base.setSize(self, w, h, rel) + if(self.parent==nil)then + basaltDraw = BasaltDraw(termObject) + end for _, index in pairs(objZIndex) do if (objects[index] ~= nil) then for _, value in pairs(objects[index]) do if (value.eventHandler ~= nil) then - value:sendEvent("basalt_resize", value, self) + value:eventHandler("basalt_resize", value, self) end end end end + self:recalculateDynamicValues() + autoSize = false return self end; - setTheme = function(self, _theme) - theme = _theme + setTheme = function(self, _theme, col) + if(type(_theme)=="table")then + theme = _theme + elseif(type(_theme)=="string")then + theme[_theme] = col + end + self:updateDraw() return self end, getTheme = function(self, name) - return (theme and theme[name]) or (self.parent~=nil and self.parent:getTheme(name) or basalt.getTheme(name)) + return theme[name] or (self.parent~=nil and self.parent:getTheme(name) or basalt.getTheme(name)) end, setPosition = function(self, x, y, rel) @@ -289,11 +418,12 @@ return function(name, parent, pTerm, basalt) if (objects[index] ~= nil) then for _, value in pairs(objects[index]) do if (value.eventHandler ~= nil) then - value:sendEvent("basalt_reposition", value, self) + value:eventHandler("basalt_reposition", value, self) end end end end + self:recalculateDynamicValues() return self end; @@ -304,6 +434,7 @@ return function(name, parent, pTerm, basalt) setOffset = function(self, xO, yO) xOffset = xO ~= nil and math.floor(xO < 0 and math.abs(xO) or -xO) or xOffset yOffset = yO ~= nil and math.floor(yO < 0 and math.abs(yO) or -yO) or yOffset + self:updateDraw() return self end; @@ -311,12 +442,12 @@ return function(name, parent, pTerm, basalt) return xOffset, yOffset end; - getOffset = function(self) -- internal + getOffset = function(self) return xOffset < 0 and math.abs(xOffset) or -xOffset, yOffset < 0 and math.abs(yOffset) or -yOffset end; removeFocusedObject = function(self) - focusedOBjectCache = nil + focusedObjectCache = nil return self end; @@ -338,43 +469,48 @@ return function(name, parent, pTerm, basalt) yCursor = oby + _yCursor - 1 end cursorColor = color or cursorColor - self:setVisualChanged() + if (cursorBlink) then + termObject.setTextColor(cursorColor) + termObject.setCursorPos(xCursor, yCursor) + termObject.setCursorBlink(cursorBlink) + else + termObject.setCursorBlink(false) + end end return self end; - setMoveable = function(self, moveable) - self.isMoveable = moveable or not self.isMoveable - self:setVisualChanged() + setMovable = function(self, movable) + if(self.parent~=nil)then + isMovable = movable or not isMovable + self.parent:addEvent("mouse_click", self) + activeEvents["mouse_click"] = true + self.parent:addEvent("mouse_up", self) + activeEvents["mouse_up"] = true + self.parent:addEvent("mouse_drag", self) + activeEvents["mouse_drag"] = true + end return self; end; setScrollable = function(self, scrollable) isScrollable = scrollable and true or false + if(self.parent~=nil)then + self.parent:addEvent("mouse_scroll", self) + end + activeEvents["mouse_scroll"] = true return self end, - setImportantScroll = function(self, imp) - importantScroll = imp and true or false + setScrollAmount = function(self, max) + scrollAmount = max or scrollAmount + autoScroll = false return self end, - setMaxScroll = function(self, max) - maxScroll = max or maxScroll - return self - end, - setMinScroll = function(self, min) - minScroll = min or minScroll - return self - end, - - getMaxScroll = function(self) - return maxScroll - end, - - getMinScroll = function(self) - return minScroll + getScrollAmount = function(self) + return scrollAmount end, show = function(self) @@ -434,7 +570,7 @@ return function(name, parent, pTerm, basalt) setValuesByXMLData = function(self, data) base.setValuesByXMLData(self, data) - if(xmlValue("moveable", data)~=nil)then if(xmlValue("moveable", data))then self:setMoveable(true) end end + if(xmlValue("movable", data)~=nil)then if(xmlValue("movable", data))then self:setMovable(true) end end if(xmlValue("scrollable", data)~=nil)then if(xmlValue("scrollable", data))then self:setScrollable(true) end end if(xmlValue("monitor", data)~=nil)then self:setMonitor(xmlValue("monitor", data)):show() end if(xmlValue("mirror", data)~=nil)then self:setMirror(xmlValue("mirror", data)) end @@ -446,9 +582,7 @@ return function(name, parent, pTerm, basalt) if(xmlValue("layout", data)~=nil)then self:addLayout(xmlValue("layout", data)) end if(xmlValue("xOffset", data)~=nil)then self:setOffset(xmlValue("xOffset", data), yOffset) end if(xmlValue("yOffset", data)~=nil)then self:setOffset(yOffset, xmlValue("yOffset", data)) end - if(xmlValue("maxScroll", data)~=nil)then self:setMaxScroll(xmlValue("maxScroll", data)) end - if(xmlValue("minScroll", data)~=nil)then self:setMaxScroll(xmlValue("minScroll", data)) end - if(xmlValue("importantScroll", data)~=nil)then self:setImportantScroll(xmlValue("importantScroll", data)) end + if(xmlValue("scrollAmount", data)~=nil)then self:setScrollAmount(xmlValue("scrollAmount", data)) end local objectList = data:children() @@ -466,27 +600,28 @@ return function(name, parent, pTerm, basalt) return self end, - showBar = function(self, showIt) + showBar = function(self, showIt) -- deprecated self.barActive = showIt or not self.barActive - self:setVisualChanged() + self:updateDraw() return self end; - setBar = function(self, text, bgCol, fgCol) + setBar = function(self, text, bgCol, fgCol) -- deprecated self.barText = text or "" self.barBackground = bgCol or self.barBackground self.barTextcolor = fgCol or self.barTextcolor - self:setVisualChanged() + self:updateDraw() return self end; - setBarTextAlign = function(self, align) + setBarTextAlign = function(self, align) -- deprecated self.barTextAlign = align or "left" - self:setVisualChanged() + self:updateDraw() return self end; setMirror = function(self, side) + if(self.parent~=nil)then error("Frame has to be a base frame in order to attach a mirror.") end mirrorSide = side if(mirror~=nil)then basaltDraw.setMirror(mirror) @@ -507,11 +642,13 @@ return function(name, parent, pTerm, basalt) if(peripheral.getType(side)=="monitor")then termObject = peripheral.wrap(side) monitorAttached = true + end if(self.parent~=nil)then self.parent:removeObject(self) end isMonitor = true + basalt.setMonitorFrame(side, self) else termObject = parentTerminal isMonitor = false @@ -520,85 +657,73 @@ return function(name, parent, pTerm, basalt) end end basaltDraw = BasaltDraw(termObject) + self:setSize(termObject.getSize()) + autoSize = true monSide = side or nil + self:updateDraw() return self; end; - getVisualChanged = function(self) - local changed = base.getVisualChanged(self) - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.getVisualChanged ~= nil and value:getVisualChanged()) then - changed = true - end - end - end - end - return changed - end; - loseFocusHandler = function(self) base.loseFocusHandler(self) - if(focusedOBjectCache~=nil)then - focusedOBjectCache:loseFocusHandler() - focusedOBjectCache = nil - end + if(focusedObject~=nil)then focusedObject:loseFocusHandler() focusedObject = nil end end; getFocusHandler = function(self) base.getFocusHandler(self) if (self.parent ~= nil) then - self.parent:removeObject(self) - self.parent:addObject(self) - end - end; - - keyHandler = function(self, event, key) - if (focusedObject ~= nil) then - if(focusedObject~=self)then - if (focusedObject.keyHandler ~= nil) then - if (focusedObject:keyHandler(event, key)) then - return true - end - end - else - base.keyHandler(self, event, key) - end - end - return false - end; - - backgroundKeyHandler = function(self, event, key) - base.backgroundKeyHandler(self, event, key) - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.backgroundKeyHandler ~= nil) then - value:backgroundKeyHandler(event, key) + if(isMovable)then + self.parent:removeEvents(self) + self.parent:removeObject(self) + self.parent:addObject(self) + for k,v in pairs(activeEvents)do + if(v)then + self.parent:addEvent(k, self) end end + self:updateDraw() end end + if(focusedObject~=nil)then focusedObject:getFocusHandler() end end; eventHandler = function(self, event, p1, p2, p3, p4) base.eventHandler(self, event, p1, p2, p3, p4) - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.eventHandler ~= nil) then - value:eventHandler(event, p1, p2, p3, p4) + if(events["other_event"]~=nil)then + for _, index in ipairs(eventZIndex["other_event"]) do + if (events["other_event"][index] ~= nil) then + for _, value in rpairs(events["other_event"][index]) do + if (value.eventHandler ~= nil) then + if (value:eventHandler(event, p1, p2, p3, p4)) then + return true + end + end end end end end + if(autoSize)and not(isMonitor)then + if(self.parent==nil)then + if(event=="term_resize")then + self:setSize(termObject.getSize()) + autoSize = true + end + end + end if(isMonitor)then + if(autoSize)then + if(event=="monitor_resize")and(p1==monSide)then + self:setSize(termObject.getSize()) + autoSize = true + self:updateDraw() + end + end if(event == "peripheral")and(p1==monSide)then if(peripheral.getType(monSide)=="monitor")then monitorAttached = true termObject = peripheral.wrap(monSide) basaltDraw = BasaltDraw(termObject) + self:updateDraw() end end if(event == "peripheral_detach")and(p1==monSide)then @@ -613,82 +738,199 @@ return function(name, parent, pTerm, basalt) if(event == "peripheral_detach")and(p1==mirrorSide)then monitorAttached = false end - if(event=="monitor_touch")then - self:mouseHandler(event, p1, p2, p3, p4) + if(event=="monitor_touch")and(mirrorSide==p1)then + self:mouseHandler(1, p2, p3, true) end end - if (event == "terminate") then - termObject.setCursorPos(1, 1) - termObject.clear() + if (event == "terminate")and(self.parent==nil)then basalt.stop() end - end; + end, - mouseHandler = function(self, event, button, x, y) - if (self.drag) then - local xO, yO = self.parent:getOffsetInternal() - xO = xO < 0 and math.abs(xO) or -xO - yO = yO < 0 and math.abs(yO) or -yO - if (event == "mouse_drag") then - local parentX = 1 - local parentY = 1 - if (self.parent ~= nil) then - parentX, parentY = self.parent:getAbsolutePosition(self.parent:getAnchorPosition()) - end - self:setPosition(x + dragXOffset - (parentX - 1) + xO, y + dragYOffset - (parentY - 1) + yO) - end - if (event == "mouse_up") then - self.drag = false - end - return true - end - - local fx, fy = self:getAbsolutePosition(self:getAnchorPosition()) - local yOff = false - if(fy-1 == y)and(self:getBorder("top"))then - y = y+1 - yOff = true - end - - if (base.mouseHandler(self, event, button, x, y)) then - fx = fx + xOffset;fy = fy + yOffset; - if(isScrollable)and(importantScroll)then - if(event=="mouse_scroll")then - if(button>0)or(button<0)then - yOffset = max(min(yOffset-button, -minScroll),-maxScroll) - end - end - end - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in rpairs(objects[index]) do + mouseHandler = function(self, button, x, y) + if(base.mouseHandler(self, button, x, y))then + if(events["mouse_click"]~=nil)then + self:setCursor(false) + for _, index in ipairs(eventZIndex["mouse_click"]) do + if (events["mouse_click"][index] ~= nil) then + for _, value in rpairs(events["mouse_click"][index]) do if (value.mouseHandler ~= nil) then - if (value:mouseHandler(event, button, x, y)) then + if (value:mouseHandler(button, x, y)) then + focusSystem(self) return true end end end end end - self:removeFocusedObject() - if (self.isMoveable) then - if (x >= fx) and (x <= fx + self:getWidth() - 1) and (y == fy) and (event == "mouse_click") then - self.drag = true - dragXOffset = fx - x - dragYOffset = yOff and 1 or 0 - end - end - if(isScrollable)and(not importantScroll)then - if(event=="mouse_scroll")then - if(button>0)or(button<0)then - yOffset = max(min(yOffset-button, -minScroll),-maxScroll) - end - end + end + if (isMovable) then + local fx, fy = self:getAbsolutePosition(self:getAnchorPosition()) + if (x >= fx) and (x <= fx + self:getWidth() - 1) and (y == fy)then + isDragging = true + dragXOffset = fx - x + dragYOffset = yOff and 1 or 0 end + end + self:removeFocusedObject() + focusSystem(self) return true end return false - end; + end, + + mouseUpHandler = function(self, button, x, y) + if (isDragging) then + isDragging = false + end + if(base.mouseUpHandler(self, button, x, y))then + if(events["mouse_up"]~=nil)then + for _, index in ipairs(eventZIndex["mouse_up"]) do + if (events["mouse_up"][index] ~= nil) then + for _, value in rpairs(events["mouse_up"][index]) do + if (value.mouseUpHandler ~= nil) then + if (value:mouseUpHandler(button, x, y)) then + focusSystem(self) + return true + end + end + end + end + end + end + focusSystem(self) + return true + end + return false + end, + + scrollHandler = function(self, dir, x, y) + if(base.scrollHandler(self, dir, x, y))then + if(events["mouse_scroll"]~=nil)then + for _, index in pairs(eventZIndex["mouse_scroll"]) do + if (events["mouse_scroll"][index] ~= nil) then + for _, value in rpairs(events["mouse_scroll"][index]) do + if (value.scrollHandler ~= nil) then + if (value:scrollHandler(dir, x, y)) then + focusSystem(self) + return true + end + end + end + end + end + end + local cache = yOffset + if(isScrollable)then + calculateMaxScroll(self) + if(dir>0)or(dir<0)then + yOffset = max(min(yOffset-dir, 0),-scrollAmount) + self:updateDraw() + end + end + self:removeFocusedObject() + focusSystem(self) + if(yOffset==cache)then return false end + return true + end + return false + end, + + dragHandler = function(self, button, x, y) + if (isDragging) then + local xO, yO = self.parent:getOffsetInternal() + xO = xO < 0 and math.abs(xO) or -xO + yO = yO < 0 and math.abs(yO) or -yO + local parentX = 1 + local parentY = 1 + if (self.parent ~= nil) then + parentX, parentY = self.parent:getAbsolutePosition(self.parent:getAnchorPosition()) + end + self:setPosition(x + dragXOffset - (parentX - 1) + xO, y + dragYOffset - (parentY - 1) + yO) + self:updateDraw() + return true + end + if(events["mouse_drag"]~=nil)then + for _, index in ipairs(eventZIndex["mouse_drag"]) do + if (events["mouse_drag"][index] ~= nil) then + for _, value in rpairs(events["mouse_drag"][index]) do + if (value.dragHandler ~= nil) then + if (value:dragHandler(button, x, y)) then + focusSystem(self) + return true + end + end + end + end + end + end + focusSystem(self) + base.dragHandler(self, button, x, y) + return false + end, + + keyHandler = function(self, key, isHolding) + if (self:isFocused())or(self.parent==nil)then + local val = self:getEventSystem():sendEvent("key", self, "key", key) + if(val==false)then return false end + if(events["key"]~=nil)then + for _, index in pairs(eventZIndex["key"]) do + if (events["key"][index] ~= nil) then + for _, value in rpairs(events["key"][index]) do + if (value.keyHandler ~= nil) then + if (value:keyHandler(key, isHolding)) then + return true + end + end + end + end + end + end + end + return false + end, + + keyUpHandler = function(self, key) + if (self:isFocused())or(self.parent==nil)then + local val = self:getEventSystem():sendEvent("key_up", self, "key_up", key) + if(val==false)then return false end + if(events["key_up"]~=nil)then + for _, index in pairs(eventZIndex["key_up"]) do + if (events["key_up"][index] ~= nil) then + for _, value in rpairs(events["key_up"][index]) do + if (value.keyUpHandler ~= nil) then + if (value:keyUpHandler(key)) then + return true + end + end + end + end + end + end + end + return false + end, + + charHandler = function(self, char) + if (self:isFocused())or(self.parent==nil)then + local val = self:getEventSystem():sendEvent("char", self, "char", char) + if(val==false)then return false end + if(events["char"]~=nil)then + for _, index in pairs(eventZIndex["char"]) do + if (events["char"][index] ~= nil) then + for _, value in rpairs(events["char"][index]) do + if (value.charHandler ~= nil) then + if (value:charHandler(char)) then + return true + end + end + end + end + end + end + end + return false + end, setText = function(self, x, y, text) local obx, oby = self:getAnchorPosition() @@ -768,84 +1010,54 @@ return function(name, parent, pTerm, basalt) end end; - draw = function(self) + draw = function(self, force) if(isMonitor)and not(monitorAttached)then return false end; - if (self:getVisualChanged()) then - if (base.draw(self)) then - - if(focusedObject~=focusedOBjectCache)then - if(focusedOBjectCache~=nil)then - focusedOBjectCache:getFocusHandler() - end - if(focusedObject~=nil)then - focusedObject:loseFocusHandler() - end - focusedObject = focusedOBjectCache + if(self.parent==nil)then if(self:getDraw()==false)then return false end end + if (base.draw(self))then + local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) + local anchx, anchy = self:getAnchorPosition() + local w,h = self:getSize() + if (self.parent == nil) then + if(self.bgColor~=false)then + basaltDraw.drawBackgroundBox(anchx, anchy, w, h, self.bgColor) + basaltDraw.drawTextBox(anchx, anchy, w, h, " ") end - - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - local anchx, anchy = self:getAnchorPosition() - local w,h = self:getSize() + if(self.fgColor~=false)then basaltDraw.drawForegroundBox(anchx, anchy, w, h, self.fgColor) end + end + if (self.barActive) then if (self.parent ~= nil) then - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(anchx, anchy, w, h, self.bgColor) - self.parent:drawTextBox(anchx, anchy, w, h, " ") - end - if(self.bgColor~=false)then self.parent:drawForegroundBox(anchx, anchy, w, h, self.fgColor) end + self.parent:writeText(anchx, anchy, utils.getTextHorizontalAlign(self.barText, w, self.barTextAlign), self.barBackground, self.barTextcolor) else - if(self.bgColor~=false)then - basaltDraw.drawBackgroundBox(anchx, anchy, w, h, self.bgColor) - basaltDraw.drawTextBox(anchx, anchy, w, h, " ") - end - if(self.fgColor~=false)then basaltDraw.drawForegroundBox(anchx, anchy, w, h, self.fgColor) end + basaltDraw.writeText(anchx, anchy, utils.getTextHorizontalAlign(self.barText, w, self.barTextAlign), self.barBackground, self.barTextcolor) end - termObject.setCursorBlink(false) - if (self.barActive) then + if(self:getBorder("left"))then if (self.parent ~= nil) then - self.parent:writeText(anchx, anchy, utils.getTextHorizontalAlign(self.barText, w, self.barTextAlign), self.barBackground, self.barTextcolor) - else - basaltDraw.writeText(anchx, anchy, utils.getTextHorizontalAlign(self.barText, w, self.barTextAlign), self.barBackground, self.barTextcolor) - end - if(self:getBorder("left"))then - if (self.parent ~= nil) then - self.parent:drawBackgroundBox(anchx-1, anchy, 1, 1, self.barBackground) - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(anchx-1, anchy+1, 1, h-1, self.bgColor) - end - end - end - if(self:getBorder("top"))then - if (self.parent ~= nil) then - self.parent:drawBackgroundBox(anchx-1, anchy-1, w+1, 1, self.barBackground) + self.parent:drawBackgroundBox(anchx-1, anchy, 1, 1, self.barBackground) + if(self.bgColor~=false)then + self.parent:drawBackgroundBox(anchx-1, anchy+1, 1, h-1, self.bgColor) end end end - - for _, index in rpairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.draw ~= nil) then - value:draw() - end - end - end - end - - if (cursorBlink) then - termObject.setTextColor(cursorColor) - termObject.setCursorPos(xCursor, yCursor) + if(self:getBorder("top"))then if (self.parent ~= nil) then - termObject.setCursorBlink(self:isFocused()) - else - termObject.setCursorBlink(cursorBlink) + self.parent:drawBackgroundBox(anchx-1, anchy-1, w+1, 1, self.barBackground) + end + end + end + + for _, index in rpairs(objZIndex) do + if (objects[index] ~= nil) then + for _, value in pairs(objects[index]) do + if (value.draw ~= nil) then + value:draw() + end end end - self:setVisualChanged(false) end end end; - drawUpdate = function(self) + updateTerm = function(self) if(isMonitor)and not(monitorAttached)then return false end; basaltDraw.update() end; @@ -868,7 +1080,22 @@ return function(name, parent, pTerm, basalt) addFrame = function(self, name) local obj = basalt.newFrame(name or uuid(), self, nil, basalt) return addObject(obj) - end; + end, + + init = function(self) + if not(initialized)then + if (parent ~= nil) then + base.width, base.height = parent:getSize() + self:setBackground(parent:getTheme("FrameBG")) + self:setForeground(parent:getTheme("FrameText")) + else + base.width, base.height = termObject.getSize() + self:setBackground(basalt.getTheme("BasaltBG")) + self:setForeground(basalt.getTheme("BasaltText")) + end + initialized = true + end + end, } for k,v in pairs(_OBJECTS)do object["add"..k] = function(self, name) @@ -877,4 +1104,4 @@ return function(name, parent, pTerm, basalt) end setmetatable(object, base) return object -end +end \ No newline at end of file diff --git a/Basalt/Object.lua b/Basalt/Object.lua index f532d9e..a64d3f0 100644 --- a/Basalt/Object.lua +++ b/Basalt/Object.lua @@ -13,20 +13,23 @@ return function(name) local anchor = "topLeft" local ignOffset = false local isVisible = true + local initialized = false local shadow = false - local borderLeft = false - local borderTop = false - local borderRight = false - local borderBottom = false + local borderColors = { + left = false, + right = false, + top = false, + bottom = false + } local shadowColor = colors.black - local borderColor = colors.black local isEnabled = true local isDragging = false local dragStartX, dragStartY, dragXOffset, dragYOffset = 0, 0, 0, 0 - local visualsChanged = true + local draw = true + local activeEvents = {} local eventSystem = basaltEvent() @@ -36,19 +39,22 @@ return function(name) width = 1, height = 1, bgColor = colors.black, + bgSymbol = " ", + bgSymbolColor = colors.black, fgColor = colors.white, + transparentColor = false, name = name or "Object", parent = nil, show = function(self) isVisible = true - visualsChanged = true + self:updateDraw() return self end; hide = function(self) isVisible = false - visualsChanged = true + self:updateDraw() return self end; @@ -96,13 +102,12 @@ return function(name) if(xmlValue("enabled", data)~=nil)then if(xmlValue("enabled", data))then self:enable() else self:disable() end end if(xmlValue("zIndex", data)~=nil)then self:setZIndex(xmlValue("zIndex", data)) end if(xmlValue("anchor", data)~=nil)then self:setAnchor(xmlValue("anchor", data)) end - if(xmlValue("shadow", data)~=nil)then if(xmlValue("shadow", data))then self:showShadow(true) end end if(xmlValue("shadowColor", data)~=nil)then self:setShadow(colors[xmlValue("shadowColor", data)]) end - if(xmlValue("border", data)~=nil)then if(xmlValue("border", data))then borderLeft,borderTop,borderRight,borderBottom = true,true,true,true end end - if(xmlValue("borderLeft", data)~=nil)then if(xmlValue("borderLeft", data))then borderLeft = true else borderLeft = false end end - if(xmlValue("borderTop", data)~=nil)then if(xmlValue("borderTop", data))then borderTop = true else borderTop = false end end - if(xmlValue("borderRight", data)~=nil)then if(xmlValue("borderRight", data))then borderRight = true else borderRight = false end end - if(xmlValue("borderBottom", data)~=nil)then if(xmlValue("borderBottom", data))then borderBottom = true else borderBottom = false end end + if(xmlValue("border", data)~=nil)then self:setBorder(colors[xmlValue("border", data)]) end + if(xmlValue("borderLeft", data)~=nil)then borderColors["left"] = xmlValue("borderLeft", data) end + if(xmlValue("borderTop", data)~=nil)then borderColors["top"] = xmlValue("borderTop", data) end + if(xmlValue("borderRight", data)~=nil)then borderColors["right"] = xmlValue("borderRight", data) end + if(xmlValue("borderBottom", data)~=nil)then borderColors["bottom"] = xmlValue("borderBottom", data) end if(xmlValue("borderColor", data)~=nil)then self:setBorder(colors[xmlValue("borderColor", data)]) end if(xmlValue("ignoreOffset", data)~=nil)then if(xmlValue("ignoreOffset", data))then self:ignoreOffset(true) end end if(xmlValue("onClick", data)~=nil)then self:generateXMLEventFunction(self.onClick, xmlValue("onClick", data)) end @@ -117,9 +122,7 @@ return function(name) if(xmlValue("onEvent", data)~=nil)then self:generateXMLEventFunction(self.onEvent, xmlValue("onEvent", data)) end if(xmlValue("onGetFocus", data)~=nil)then self:generateXMLEventFunction(self.onGetFocus, xmlValue("onGetFocus", data)) end if(xmlValue("onLoseFocus", data)~=nil)then self:generateXMLEventFunction(self.onLoseFocus, xmlValue("onLoseFocus", data)) end - if(xmlValue("onBackgroundKey", data)~=nil)then self:generateXMLEventFunction(self.onBackgroundKey, xmlValue("onBackgroundKey", data)) end - if(xmlValue("onBackgroundKeyUp", data)~=nil)then self:generateXMLEventFunction(self.onBackgroundKeyUp, xmlValue("onBackgroundKeyUp", data)) end - + self:updateDraw() return self end, @@ -139,9 +142,19 @@ return function(name) if (self.parent ~= nil) then self.parent:removeObject(self) self.parent:addObject(self) + self:updateEventHandlers() end + return self - end; + end, + + updateEventHandlers = function(self) + for k,v in pairs(activeEvents)do + if(v)then + self.parent:addEvent(k, self) + end + end + end, getZIndex = function(self) return zIndex; @@ -159,6 +172,7 @@ return function(name) if (self.parent ~= nil) then self.parent:removeObject(self) end + self:updateDraw() return self end; @@ -176,7 +190,7 @@ return function(name) setValue = function(self, _value) if (value ~= _value) then value = _value - visualsChanged = true + self:updateDraw() self:valueChangedHandler() end return self @@ -186,13 +200,14 @@ return function(name) return value end; - getVisualChanged = function(self) - return visualsChanged + getDraw = function(self) + return draw end; - setVisualChanged = function(self, change) - visualsChanged = change or true - if(change == nil)then visualsChanged = true end + updateDraw = function(self, change) + draw = change + if(change == nil)then draw = true end + if(draw)then if(self.parent~=nil)then self.parent:updateDraw() end end return self end; @@ -206,10 +221,6 @@ return function(name) return self.parent end; - getObjectReferencesForDynVal = function(self, str) - - end, - setPosition = function(self, xPos, yPos, rel) if(type(xPos)=="number")then self.x = rel and self:getX()+xPos or xPos @@ -227,7 +238,7 @@ return function(name) self.parent:recalculateDynamicValues() end eventSystem:sendEvent("basalt_reposition", self) - visualsChanged = true + self:updateDraw() return self end; @@ -249,7 +260,7 @@ return function(name) setVisibility = function(self, _isVisible) isVisible = _isVisible or not isVisible - visualsChanged = true + self:updateDraw() return self end; @@ -270,7 +281,7 @@ return function(name) self.parent:recalculateDynamicValues() end eventSystem:sendEvent("basalt_resize", self) - visualsChanged = true + self:updateDraw() return self end; @@ -291,12 +302,23 @@ return function(name) if(type(self.height)=="table")then self.height:calculate() end if(type(self.x)=="table")then self.x:calculate() end if(type(self.y)=="table")then self.y:calculate() end + self:updateDraw() return self end, - setBackground = function(self, color) + setBackground = function(self, color, symbol, symbolCol) self.bgColor = color or false - visualsChanged = true + self.bgSymbol = symbol or (self.bgColor~=false and self.bgSymbol or false) + self.bgSymbolColor = symbolCol or self.bgSymbolColor + self:updateDraw() + return self + end; + + setTransparent = function(self, color) + self.transparentColor = color or false + self.bgSymbol = false + self.bgSymbolColor = false + self:updateDraw() return self end; @@ -306,7 +328,7 @@ return function(name) setForeground = function(self, color) self.fgColor = color or false - visualsChanged = true + self:updateDraw() return self end; @@ -314,13 +336,14 @@ return function(name) return self.fgColor end; - showShadow = function(self, show) - shadow = show or (not shadow) - return self - end; - setShadow = function(self, color) - shadowColor = color + if(color==false)then + shadow = false + else + shadowColor = color + shadow = true + end + self:updateDraw() return self end; @@ -328,26 +351,25 @@ return function(name) return shadow; end; - showBorder = function(self, ...) - for _,v in pairs(table.pack(...))do - if(v=="left")then - borderLeft = true - end - if(v=="top")then - borderTop = true - end - if(v=="right")then - borderRight = true - end - if(v=="bottom")then - borderBottom = true + setBorder = function(self, ...) + if(...~=nil)then + local t = {...} + for k,v in pairs(t)do + if(v=="left")or(#t==1)then + borderColors["left"] = t[1] + end + if(v=="top")or(#t==1)then + borderColors["top"] = t[1] + end + if(v=="right")or(#t==1)then + borderColors["right"] = t[1] + end + if(v=="bottom")or(#t==1)then + borderColors["bottom"] = t[1] + end end end - return self - end; - - setBorder = function(self, color) - borderColor = color + self:updateDraw() return self end; @@ -367,52 +389,68 @@ return function(name) end; draw = function(self) - if (isVisible) then + if (isVisible)then if(self.parent~=nil)then local x, y = self:getAnchorPosition() local w,h = self:getSize() + local wP,hP = self.parent:getSize() + if(x+w<1)or(x>wP)or(y+h<1)or(y>hP)then return false end + if(self.transparentColor~=false)then + self.parent:drawForegroundBox(x, y, w, h, self.transparentColor) + end + if(self.bgColor~=false)then + self.parent:drawBackgroundBox(x, y, w, h, self.bgColor) + end + if(self.bgSymbol~=false)then + self.parent:drawTextBox(x, y, w, h, self.bgSymbol) + if(self.bgSymbol~=" ")then + self.parent:drawForegroundBox(x, y, w, h, self.bgSymbolColor) + end + end if(shadow)then self.parent:drawBackgroundBox(x+1, y+h, w, 1, shadowColor) self.parent:drawBackgroundBox(x+w, y+1, 1, h, shadowColor) self.parent:drawForegroundBox(x+1, y+h, w, 1, shadowColor) self.parent:drawForegroundBox(x+w, y+1, 1, h, shadowColor) end - if(borderLeft)then + if(borderColors["left"]~=false)then self.parent:drawTextBox(x-1, y, 1, h, "\149") - self.parent:drawForegroundBox(x-1, y, 1, h, borderColor) - if(self.bgColor~=false)then self.parent:drawBackgroundBox(x-1, y, 1, h, self.bgColor) end + self.parent:drawBackgroundBox(x-1, y, 1, h, borderColors["left"]) + self.parent:drawForegroundBox(x-1, y, 1, h, self.parent.bgColor) end - if(borderLeft)and(borderTop)then + if(borderColors["left"]~=false)and(borderColors["top"]~=false)then self.parent:drawTextBox(x-1, y-1, 1, 1, "\151") - self.parent:drawForegroundBox(x-1, y-1, 1, 1, borderColor) - if(self.bgColor~=false)then self.parent:drawBackgroundBox(x-1, y-1, 1, 1, self.bgColor) end + self.parent:drawBackgroundBox(x-1, y-1, 1, 1, borderColors["left"]) + self.parent:drawForegroundBox(x-1, y-1, 1, 1, self.parent.bgColor) end - if(borderTop)then + if(borderColors["top"]~=false)then + self.parent:drawTextBox(x, y-1, w, 1, "\131") - self.parent:drawForegroundBox(x, y-1, w, 1, borderColor) - if(self.bgColor~=false)then self.parent:drawBackgroundBox(x, y-1, w, 1, self.bgColor) end + self.parent:drawBackgroundBox(x, y-1, w, 1, borderColors["top"]) + self.parent:drawForegroundBox(x, y-1, w, 1, self.parent.bgColor) end - if(borderTop)and(borderRight)then - self.parent:drawTextBox(x+w, y-1, 1, 1, "\149") - self.parent:drawForegroundBox(x+w, y-1, 1, 1, borderColor) + if(borderColors["top"]~=false)and(borderColors["right"]~=false)then + self.parent:drawTextBox(x+w, y-1, 1, 1, "\148") + self.parent:drawForegroundBox(x+w, y-1, 1, 1, borderColors["right"]) end - if(borderRight)then + if(borderColors["right"]~=false)then self.parent:drawTextBox(x+w, y, 1, h, "\149") - self.parent:drawForegroundBox(x+w, y, 1, h, borderColor) + self.parent:drawForegroundBox(x+w, y, 1, h, borderColors["right"]) end - if(borderRight)and(borderBottom)then + if(borderColors["right"]~=false)and(borderColors["bottom"]~=false)then self.parent:drawTextBox(x+w, y+h, 1, 1, "\129") - self.parent:drawForegroundBox(x+w, y+h, 1, 1, borderColor) + self.parent:drawForegroundBox(x+w, y+h, 1, 1, borderColors["right"]) end - if(borderBottom)then + if(borderColors["bottom"]~=false)then self.parent:drawTextBox(x, y+h, w, 1, "\131") - self.parent:drawForegroundBox(x, y+h, w, 1, borderColor) + self.parent:drawForegroundBox(x, y+h, w, 1, borderColors["bottom"]) end - if(borderBottom)and(borderLeft)then - self.parent:drawTextBox(x-1, y+h, 1, 1, "\131") - self.parent:drawForegroundBox(x-1, y+h, 1, 1, borderColor) + if(borderColors["bottom"]~=false)and(borderColors["left"]~=false)then + self.parent:drawTextBox(x-1, y+h, 1, 1, "\130") + self.parent:drawForegroundBox(x-1, y+h, 1, 1, borderColors["left"]) end end + draw = false return true end return false @@ -487,7 +525,7 @@ return function(name) setAnchor = function(self, newAnchor) anchor = newAnchor - visualsChanged = true + self:updateDraw() return self end; @@ -505,59 +543,86 @@ return function(name) end; onClick = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("mouse_click", v) - self:registerEvent("monitor_touch", v) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("mouse_click", v) + end + end + if(self.parent~=nil)then + self.parent:addEvent("mouse_click", self) + activeEvents["mouse_click"] = true end - end return self end; onClickUp = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("mouse_up", v) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("mouse_up", v) + end + end + if(self.parent~=nil)then + self.parent:addEvent("mouse_up", self) + activeEvents["mouse_up"] = true end - end return self end; onScroll = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("mouse_scroll", v) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("mouse_scroll", v) + end + end + if(self.parent~=nil)then + self.parent:addEvent("mouse_scroll", self) + activeEvents["mouse_scroll"] = true end - end return self end; onDrag = function(self, ...) - if(isEnabled)then - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("mouse_drag", v) - end + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("mouse_drag", v) end end + self.parent:addEvent("mouse_drag", self) + activeEvents["mouse_drag"] = true + self.parent:addEvent("mouse_click", self) + activeEvents["mouse_click"] = true + self.parent:addEvent("mouse_up", self) + activeEvents["mouse_up"] = true return self end; onEvent = function(self, ...) for _,v in pairs(table.pack(...))do if(type(v)=="function")then - self:registerEvent("custom_event_handler", v) + self:registerEvent("other_event", v) end end + if(self.parent~=nil)then + self.parent:addEvent("other_event", self) + activeEvents["other_event"] = true + end return self end; onKey = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("key", v) - self:registerEvent("char", v) + if(isEnabled)then + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("key", v) + self:registerEvent("char", v) + end + end + if(self.parent~=nil)then + self.parent:addEvent("key", self) + self.parent:addEvent("char", self) + activeEvents["key"] = true + activeEvents["char"] = true end end return self @@ -582,30 +647,15 @@ return function(name) end; onKeyUp = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("key_up", v) + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("key_up", v) + end end - end - return self - end; - - onBackgroundKey = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("background_key", v) - self:registerEvent("background_char", v) + if(self.parent~=nil)then + self.parent:addEvent("key_up", self) + activeEvents["key_up"] = true end - end - return self - end; - - onBackgroundKeyUp = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("background_key_up", v) - end - end return self end; @@ -622,6 +672,10 @@ return function(name) self:registerEvent("get_focus", v) end end + if(self.parent~=nil)then + self.parent:addEvent("mouse_click", self) + activeEvents["mouse_click"] = true + end return self end; @@ -631,6 +685,10 @@ return function(name) self:registerEvent("lose_focus", v) end end + if(self.parent~=nil)then + self.parent:addEvent("mouse_click", self) + activeEvents["mouse_click"] = true + end return self end; @@ -646,79 +704,122 @@ return function(name) return eventSystem:sendEvent(event, self, ...) end; - mouseHandler = function(self, event, button, x, y) - if(isEnabled)and(isVisible)then + isCoordsInObject = function(self, x, y) + if(isVisible)and(isEnabled)then local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) - local w, h = self:getSize() - local yOff = false - - if(objY-1 == y)and(self:getBorder("top"))then - y = y+1 - yOff = true - end - if(event=="mouse_up")then - isDragging = false - end - - if(isDragging)and(event=="mouse_drag")then - local xO, yO, parentX, parentY = 0, 0, 1, 1 - if (self.parent ~= nil) then - xO, yO = self.parent:getOffsetInternal() - xO = xO < 0 and math.abs(xO) or -xO - yO = yO < 0 and math.abs(yO) or -yO - parentX, parentY = self.parent:getAbsolutePosition(self.parent:getAnchorPosition()) - end - local dX, dY = x + dragXOffset - (parentX - 1) + xO, y + dragYOffset - (parentY - 1) + yO - local val = eventSystem:sendEvent(event, self, event, button, dX, dY, dragStartX, dragStartY, x, y) - end - - + local w, h = self:getSize() if (objX <= x) and (objX + w > x) and (objY <= y) and (objY + h > y) then - if(event=="mouse_click")then - isDragging = true - dragStartX, dragStartY = x, y - dragXOffset, dragYOffset = objX - x, objY - y - end - if(event~="mouse_drag")then - if(event~="mouse_up")then - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) - end - end - local val = eventSystem:sendEvent(event, self, event, button, x, y) - if(val~=nil)then return val end - end return true end end return false - end; + end, - keyHandler = function(self, event, key) - if(isEnabled)then - if (self:isFocused()) then - local val = eventSystem:sendEvent(event, self, event, key) - if(val~=nil)then return val end - return true + mouseHandler = function(self, button, x, y, isMon) + if(self:isCoordsInObject(x, y))then + local val = eventSystem:sendEvent("mouse_click", self, "mouse_click", button, x, y, isMon) + if(val==false)then return false end + if(self.parent~=nil)then + self.parent:setFocusedObject(self) end + isDragging = true + dragStartX, dragStartY = x, y + return true end return false - end; + end, - backgroundKeyHandler = function(self, event, key) - if(isEnabled)then - local val = eventSystem:sendEvent("background_"..event, self, event, key) + mouseUpHandler = function(self, button, x, y) + isDragging = false + if(self:isCoordsInObject(x, y))then + local val = eventSystem:sendEvent("mouse_up", self, "mouse_up", button, x, y) + if(val==false)then return false end + return true + end + return false + end, + + dragHandler = function(self, button, x, y) + if(isDragging)then + local xO, yO, parentX, parentY = 0, 0, 1, 1 + if (self.parent ~= nil) then + xO, yO = self.parent:getOffsetInternal() + xO = xO < 0 and math.abs(xO) or -xO + yO = yO < 0 and math.abs(yO) or -yO + parentX, parentY = self.parent:getAbsolutePosition(self.parent:getAnchorPosition()) + end + local dX, dY = x + dragXOffset - (parentX - 1) + xO, y + dragYOffset - (parentY - 1) + yO + local val = eventSystem:sendEvent("mouse_drag", self, button, dX, dY, dragStartX-x, dragStartY-y, x, y) + local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) + dragStartX, dragStartY = x, y if(val~=nil)then return val end + if(self.parent~=nil)then + self.parent:setFocusedObject(self) + end + return true end - return true + + if(self:isCoordsInObject(x, y))then + local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) + dragStartX, dragStartY = x, y + dragXOffset, dragYOffset = objX - x, objY - y + end + return false + end, + + scrollHandler = function(self, dir, x, y) + if(self:isCoordsInObject(x, y))then + local val = eventSystem:sendEvent("mouse_scroll", self, "mouse_scroll", dir, x, y) + if(val==false)then return false end + if(self.parent~=nil)then + self.parent:setFocusedObject(self) + end + return true + end + return false + end, + + keyHandler = function(self, key, isHolding) + if(isEnabled)and(isVisible)then + if (self:isFocused()) then + local val = eventSystem:sendEvent("key", self, "key", key, isHolding) + if(val==false)then return false end + return true + end + end + return false end; + keyUpHandler = function(self, key) + if(isEnabled)and(isVisible)then + if (self:isFocused()) then + local val = eventSystem:sendEvent("key_up", self, "key_up", key) + if(val==false)then return false end + return true + end + end + return false + end; + + charHandler = function(self, char) + if(isEnabled)and(isVisible)then + if (self:isFocused()) then + local val = eventSystem:sendEvent("char", self, "char", char) + if(val==false)then return false end + return true + end + end + return false + end, + valueChangedHandler = function(self) - eventSystem:sendEvent("value_changed", self) + eventSystem:sendEvent("value_changed", self, value) end; eventHandler = function(self, event, p1, p2, p3, p4) - eventSystem:sendEvent("custom_event_handler", self, event, p1, p2, p3, p4) + local val = eventSystem:sendEvent("other_event", self, event, p1, p2, p3, p4) + if(val~=nil)then return val end + return true end; getFocusHandler = function(self) @@ -728,11 +829,25 @@ return function(name) end; loseFocusHandler = function(self) + isDragging = false local val = eventSystem:sendEvent("lose_focus", self) if(val~=nil)then return val end return true end; + init = function(self) + if(self.parent~=nil)then + for k,v in pairs(activeEvents)do + if(v)then + self.parent:addEvent(k, self) + end + end + end + if not(initialized)then + initialized = true + return true + end + end } diff --git a/Basalt/libraries/basaltDraw.lua b/Basalt/libraries/basaltDraw.lua index 9054793..62ce41e 100644 --- a/Basalt/libraries/basaltDraw.lua +++ b/Basalt/libraries/basaltDraw.lua @@ -28,6 +28,7 @@ return function(drawTerm) createEmptyLines() local function recreateWindowArray() + createEmptyLines() local emptyText = emptySpaceLine local emptyFG = emptyColorLines[colors.white] local emptyBG = emptyColorLines[colors.black] @@ -126,6 +127,11 @@ return function(drawTerm) end local drawHelper = { + setSize = function(w, h) + width, height = w, h + recreateWindowArray() + end, + setMirror = function(mirror) mirrorTerm = mirror end, @@ -157,11 +163,15 @@ return function(drawTerm) end end; writeText = function(x, y, text, bgCol, fgCol) - bgCol = bgCol or terminal.getBackgroundColor() - fgCol = fgCol or terminal.getTextColor() - setText(x, y, text) - setBG(x, y, rep(tHex[bgCol], text:len())) - setFG(x, y, rep(tHex[fgCol], text:len())) + if(text~=nil)then + setText(x, y, text) + if(bgCol~=nil)and(bgCol~=false)then + setBG(x, y, rep(tHex[bgCol], text:len())) + end + if(fgCol~=nil)and(fgCol~=false)then + setFG(x, y, rep(tHex[fgCol], text:len())) + end + end end; update = function() diff --git a/Basalt/libraries/basaltLogs.lua b/Basalt/libraries/basaltLogs.lua new file mode 100644 index 0000000..4edcd5a --- /dev/null +++ b/Basalt/libraries/basaltLogs.lua @@ -0,0 +1,20 @@ +local logDir = "" +local logFileName = "basaltLog.txt" + +local defaultLogType = "Debug" + +fs.delete(logDir~="" and logDir.."/"..logFileName or logFileName) + +local mt = { + __call = function(_,text, typ) + if(text==nil)then return end + local dirStr = logDir~="" and logDir.."/"..logFileName or logFileName + local handle = fs.open(dirStr, fs.exists(dirStr) and "a" or "w") + handle.writeLine("[Basalt]["..(typ and typ or defaultLogType).."]: "..tostring(text)) + handle.close() + end, +} + +return setmetatable({}, mt) + +--Work in progress \ No newline at end of file diff --git a/Basalt/libraries/process.lua b/Basalt/libraries/process.lua index 63c459a..2de4672 100644 --- a/Basalt/libraries/process.lua +++ b/Basalt/libraries/process.lua @@ -3,12 +3,12 @@ local process = {} local processId = 0 function process:new(path, window, ...) - local args = table.pack(...) + local args = {...} local newP = setmetatable({ path = path }, { __index = self }) newP.window = window newP.processId = processId newP.coroutine = coroutine.create(function() - os.run({ }, path, table.unpack(args)) + shell.execute(path, table.unpack(args)) end) processes[processId] = newP processId = processId + 1 @@ -17,12 +17,16 @@ end function process:resume(event, ...) term.redirect(self.window) + if(self.filter~=nil)then + if(event~=self.filter)then return end + self.filter=nil + end local ok, result = coroutine.resume(self.coroutine, event, ...) self.window = term.current() if ok then self.filter = result else - basalt.debug(result) + error(result) end end diff --git a/Basalt/libraries/utils.lua b/Basalt/libraries/utils.lua index 5791eaa..f9844ce 100644 --- a/Basalt/libraries/utils.lua +++ b/Basalt/libraries/utils.lua @@ -48,6 +48,16 @@ rpairs = function(t) end, t, #t + 1 end, +tableCount = function(t) + local n = 0 + if(t~=nil)then + for k,v in pairs(t)do + n = n + 1 + end + end + return n +end, + splitString = splitString, createText = function(str, width) diff --git a/Basalt/main.lua b/Basalt/main.lua index 4d6e352..baac265 100644 --- a/Basalt/main.lua +++ b/Basalt/main.lua @@ -5,8 +5,9 @@ local utils = require("utils") local uuid = utils.uuid local createText = utils.createText + local baseTerm = term.current() -local version = "1.5.0" +local version = "1.6.0" local debugger = true local projectDirectory = fs.getDir(table.pack(...)[2] or "") @@ -14,12 +15,16 @@ local projectDirectory = fs.getDir(table.pack(...)[2] or "") local activeKey, frames, monFrames, variables, schedules = {}, {}, {}, {}, {} local mainFrame, activeFrame, focusedObject, updaterActive +local basalt = {} + if not term.isColor or not term.isColor() then error('Basalt requires an advanced (golden) computer to run.', 0) end local function stop() - updaterActive = false + updaterActive = false + baseTerm.clear() + baseTerm.setCursorPos(1, 1) end local setVariable = function(name, var) @@ -72,6 +77,7 @@ local bInstance = { end, setMonitorFrame = function(name, frame) + if(mainFrame == frame)then mainFrame = nil end monFrames[name] = frame end, @@ -92,34 +98,19 @@ local basaltError = function(errMsg) baseTerm.setBackgroundColor(colors.black) baseTerm.setTextColor(colors.red) local w,h = baseTerm.getSize() - - local splitString = function(str, sep) - if sep == nil then - sep = "%s" - end - local t={} - for v in string.gmatch(str, "([^"..sep.."]+)") do - table.insert(t, v) - end - return t - end - local words = splitString(errMsg, " ") - local line = "Basalt error: " - local yPos = 1 - for n=1,#words do - baseTerm.setCursorPos(1,yPos) - if(#line+#words[n]=d-0.01)then + if(activeAnimations[typ][name]==self)then + activeAnimations[typ][name] = nil + end + end + end end) end end; @@ -274,19 +307,19 @@ return function(name) move = function(self, x, y, duration, timer, obj) _OBJ = obj or _OBJ - predefinedLerp(x,y,duration,timer or 0,_OBJ.getPosition,_OBJ.setPosition) + predefinedLerp(x,y,duration,timer or 0,_OBJ.getPosition,_OBJ.setPosition, "position", self) return self end, offset = function(self, x, y, duration, timer, obj) _OBJ = obj or _OBJ - predefinedLerp(x,y,duration,timer or 0,_OBJ.getOffset,_OBJ.setOffset) + predefinedLerp(x,y,duration,timer or 0,_OBJ.getOffset,_OBJ.setOffset, "offset", self) return self end, size = function(self, w, h, duration, timer, obj) _OBJ = obj or _OBJ - predefinedLerp(w,h,duration,timer or 0,_OBJ.getSize,_OBJ.setSize) + predefinedLerp(w,h,duration,timer or 0,_OBJ.getSize,_OBJ.setSize, "size", self) return self end, @@ -363,6 +396,7 @@ return function(name) animationDoneHandler = function(self) eventSystem:sendEvent("animation_done", self) + self.parent:removeEvent("other_event", self) if(autoDestroy)then self.parent:removeObject(self) self = nil @@ -398,6 +432,7 @@ return function(name) else self:animationDoneHandler() end + self.parent:addEvent("other_event", self) return self end; @@ -407,6 +442,7 @@ return function(name) infinitePlay = false end animationActive = false + self.parent:removeEvent("other_event", self) return self end; diff --git a/Basalt/objects/Button.lua b/Basalt/objects/Button.lua index 5c030d9..577f593 100644 --- a/Basalt/objects/Button.lua +++ b/Basalt/objects/Button.lua @@ -1,6 +1,7 @@ local Object = require("Object") local utils = require("utils") local xmlValue = utils.getValueFromXML +local tHex = require("tHex") return function(name) -- Button @@ -24,14 +25,19 @@ return function(name) end; setHorizontalAlign = function(self, pos) textHorizontalAlign = pos + self:updateDraw() + return self end; setVerticalAlign = function(self, pos) textVerticalAlign = pos + self:updateDraw() + return self end; setText = function(self, text) base:setValue(text) + self:updateDraw() return self end; @@ -50,20 +56,15 @@ return function(name) local w,h = self:getSize() local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign) - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) - self.parent:drawTextBox(obx, oby, w, h, " ") - end - if(self.fgColor~=false)then self.parent:drawForegroundBox(obx, oby, w, h, self.fgColor) end for n = 1, h do if (n == verticalAlign) then self.parent:setText(obx, oby + (n - 1), utils.getTextHorizontalAlign(self:getValue(), w, textHorizontalAlign)) + self.parent:setFG(obx, oby + (n - 1), utils.getTextHorizontalAlign(tHex[self.fgColor]:rep(self:getValue():len()), w, textHorizontalAlign)) end end end - self:setVisualChanged(false) end - end; + end, } return setmetatable(object, base) diff --git a/Basalt/objects/Checkbox.lua b/Basalt/objects/Checkbox.lua index 15335b3..5ef5834 100644 --- a/Basalt/objects/Checkbox.lua +++ b/Basalt/objects/Checkbox.lua @@ -12,31 +12,38 @@ return function(name) base.width = 1 base.height = 1 - local object = { - symbol = "\42", + local symbol = "\42" - init = function(self) - self.bgColor = self.parent:getTheme("CheckboxBG") - self.fgColor = self.parent:getTheme("CheckboxText") - end, + local object = { getType = function(self) return objectType end; - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - if ((event == "mouse_click") and (button == 1)) or (event == "monitor_touch") then + setSymbol = function(self, sym) + symbol = sym + self:updateDraw() + return self + end, + + mouseHandler = function(self, button, x, y) + if (base.mouseHandler(self, button, x, y)) then + if(button == 1)then if (self:getValue() ~= true) and (self:getValue() ~= false) then self:setValue(false) else self:setValue(not self:getValue()) end - end + self:updateDraw() return true + end end return false - end; + end, + + touchHandler = function(self, x, y) + return self:mouseHandler(1, x, y) + end, setValuesByXMLData = function(self, data) base.setValuesByXMLData(self, data) @@ -54,17 +61,22 @@ return function(name) for n = 1, h do if (n == verticalAlign) then if (self:getValue() == true) then - self.parent:writeText(obx, oby + (n - 1), utils.getTextHorizontalAlign(self.symbol, w, "center"), self.bgColor, self.fgColor) + self.parent:writeText(obx, oby + (n - 1), utils.getTextHorizontalAlign(symbol, w, "center"), self.bgColor, self.fgColor) else self.parent:writeText(obx, oby + (n - 1), utils.getTextHorizontalAlign(" ", w, "center"), self.bgColor, self.fgColor) end end end end - self:setVisualChanged(false) end - end; - + end, + + init = function(self) + base.init(self) + self.bgColor = self.parent:getTheme("CheckboxBG") + self.fgColor = self.parent:getTheme("CheckboxText") + self.parent:addEvent("mouse_click", self) + end, } return setmetatable(object, base) diff --git a/Basalt/objects/Dropdown.lua b/Basalt/objects/Dropdown.lua index 3c288d6..29706fd 100644 --- a/Basalt/objects/Dropdown.lua +++ b/Basalt/objects/Dropdown.lua @@ -26,12 +26,6 @@ return function(name) getType = function(self) return objectType end; - init = function(self) - self.bgColor = self.parent:getTheme("DropdownBG") - self.fgColor = self.parent:getTheme("DropdownText") - itemSelectedBG = self.parent:getTheme("SelectionBG") - itemSelectedFG = self.parent:getTheme("SelectionText") - end, setValuesByXMLData = function(self, data) base.setValuesByXMLData(self, data) @@ -51,6 +45,7 @@ return function(name) setOffset = function(self, yOff) yOffset = yOff + self:updateDraw() return self end; @@ -60,6 +55,7 @@ return function(name) addItem = function(self, text, bgCol, fgCol, ...) table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) + self:updateDraw() return self end; @@ -69,6 +65,7 @@ return function(name) removeItem = function(self, index) table.remove(list, index) + self:updateDraw() return self end; @@ -88,6 +85,7 @@ return function(name) clear = function(self) list = {} self:setValue({}) + self:updateDraw() return self end; @@ -98,11 +96,13 @@ return function(name) editItem = function(self, index, text, bgCol, fgCol, ...) table.remove(list, index) table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) + self:updateDraw() return self end; selectItem = function(self, index) self:setValue(list[index] or {}) + self:updateDraw() return self end; @@ -110,55 +110,90 @@ return function(name) itemSelectedBG = bgCol or self.bgColor itemSelectedFG = fgCol or self.fgColor selectionColorActive = active + self:updateDraw() return self end; setDropdownSize = function(self, width, height) dropdownW, dropdownH = width, height + self:updateDraw() return self - end; + end, - mouseHandler = function(self, event, button, x, y) + mouseHandler = function(self, button, x, y) if (isOpened) then local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if ((event == "mouse_click") and (button == 1)) or (event == "monitor_touch") then - + if(button==1)then if (#list > 0) then for n = 1, dropdownH do if (list[n + yOffset] ~= nil) then if (obx <= x) and (obx + dropdownW > x) and (oby + n == y) then self:setValue(list[n + yOffset]) + self:updateDraw() + local val = self:getEventSystem():sendEvent("mouse_click", self, "mouse_click", dir, x, y) + if(val==false)then return val end return true end end end end end + end + if (base.mouseHandler(self, button, x, y)) then + isOpened = (not isOpened) + self:updateDraw() + return true + else + if(isOpened)then + self:updateDraw() + isOpened = false + end + return false + end + end, - if (event == "mouse_scroll") then - yOffset = yOffset + button - if (yOffset < 0) then - yOffset = 0 - end - if (button == 1) then - if (#list > dropdownH) then - if (yOffset > #list - dropdownH) then - yOffset = #list - dropdownH + mouseUpHandler = function(self, button, x, y) + if (isOpened) then + local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) + if(button==1)then + if (#list > 0) then + for n = 1, dropdownH do + if (list[n + yOffset] ~= nil) then + if (obx <= x) and (obx + dropdownW > x) and (oby + n == y) then + isOpened = false + self:updateDraw() + local val = self:getEventSystem():sendEvent("mouse_up", self, "mouse_up", dir, x, y) + if(val==false)then return val end + return true + end end - else - yOffset = math.min(#list - 1, 0) end end - return true end - self:setVisualChanged() end - if (base.mouseHandler(self, event, button, x, y)) then - isOpened = true - else - isOpened = false + end, + + scrollHandler = function(self, dir, x, y) + if (isOpened)and(self:isFocused()) then + yOffset = yOffset + dir + if (yOffset < 0) then + yOffset = 0 + end + if (dir == 1) then + if (#list > dropdownH) then + if (yOffset > #list - dropdownH) then + yOffset = #list - dropdownH + end + else + yOffset = math.min(#list - 1, 0) + end + end + local val = self:getEventSystem():sendEvent("mouse_scroll", self, "mouse_scroll", dir, x, y) + if(val==false)then return val end + self:updateDraw() + return true end - end; + end, draw = function(self) if (base.draw(self)) then @@ -186,9 +221,20 @@ return function(name) end end end - self:setVisualChanged(false) end - end; + end, + + init = function(self) + self.bgColor = self.parent:getTheme("DropdownBG") + self.fgColor = self.parent:getTheme("DropdownText") + itemSelectedBG = self.parent:getTheme("SelectionBG") + itemSelectedFG = self.parent:getTheme("SelectionText") + if(self.parent~=nil)then + self.parent:addEvent("mouse_click", self) + self.parent:addEvent("mouse_up", self) + self.parent:addEvent("mouse_scroll", self) + end + end, } return setmetatable(object, base) diff --git a/Basalt/objects/Image.lua b/Basalt/objects/Image.lua index b088755..24ff76e 100644 --- a/Basalt/objects/Image.lua +++ b/Basalt/objects/Image.lua @@ -142,6 +142,7 @@ return function(name) loadImage = function(self, path) image = paintutils.loadImage(path) imageGotShrinked = false + self:updateDraw() return self end; @@ -149,6 +150,7 @@ return function(name) shrink = function(self) shrink() imageGotShrinked = true + self:updateDraw() return self end; @@ -192,9 +194,8 @@ return function(name) end end end - self:setVisualChanged(false) end - end; + end, } return setmetatable(object, base) diff --git a/Basalt/objects/Input.lua b/Basalt/objects/Input.lua index c476339..654481c 100644 --- a/Basalt/objects/Input.lua +++ b/Basalt/objects/Input.lua @@ -1,5 +1,6 @@ local Object = require("Object") local utils = require("utils") +local log = require("basaltLogs") local xmlValue = utils.getValueFromXML return function(name) @@ -24,10 +25,6 @@ return function(name) local internalValueChange = false local object = { - init = function(self) - self.bgColor = self.parent:getTheme("InputBG") - self.fgColor = self.parent:getTheme("InputFG") - end, getType = function(self) return objectType end; @@ -36,6 +33,7 @@ return function(name) if (iType == "password") or (iType == "number") or (iType == "text") then inputType = iType end + self:updateDraw() return self end; @@ -48,6 +46,7 @@ return function(name) else showingText = defaultText end + self:updateDraw() return self end; @@ -58,8 +57,14 @@ return function(name) setValue = function(self, val) base.setValue(self, tostring(val)) if not (internalValueChange) then - textX = tostring(val):len() + 1 + if(self:isFocused())then + textX = tostring(val):len() + 1 + wIndex = math.max(1, textX-self:getWidth()+1) + local obx, oby = self:getAnchorPosition() + self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self.height/2), self.fgColor) + end end + self:updateDraw() return self end; @@ -70,6 +75,7 @@ return function(name) setInputLimit = function(self, limit) inputLimit = tonumber(limit) or inputLimit + self:updateDraw() return self end; @@ -93,25 +99,28 @@ return function(name) if (self.parent ~= nil) then local obx, oby = self:getAnchorPosition() showingText = "" - if (self.parent ~= nil) then - self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self.height/2), self.fgColor) + if(defaultText~="")then + self:updateDraw() end + self.parent:setCursor(true, obx + textX - wIndex, oby+math.max(math.ceil(self:getHeight()/2-1, 1)), self.fgColor) end end; loseFocusHandler = function(self) base.loseFocusHandler(self) if (self.parent ~= nil) then - self.parent:setCursor(false) showingText = defaultText + if(defaultText~="")then + self:updateDraw() + end + self.parent:setCursor(false) end end; - keyHandler = function(self, event, key) - if (base.keyHandler(self, event, key)) then + keyHandler = function(self, key) + if (base.keyHandler(self, key)) then local w,h = self:getSize() internalValueChange = true - if (event == "key") then if (key == keys.backspace) then -- on backspace local text = tostring(base.getValue()) @@ -167,29 +176,6 @@ return function(name) wIndex = 1 end end - end - - if (event == "char") then - local text = base.getValue() - if (text:len() < inputLimit or inputLimit <= 0) then - if (inputType == "number") then - local cache = text - if (key == ".") or (tonumber(key) ~= nil) then - self:setValue(text:sub(1, textX - 1) .. key .. text:sub(textX, text:len())) - textX = textX + 1 - end - if (tonumber(base.getValue()) == nil) then - self:setValue(cache) - end - else - self:setValue(text:sub(1, textX - 1) .. key .. text:sub(textX, text:len())) - textX = textX + 1 - end - if (textX >= w + wIndex) then - wIndex = wIndex + 1 - end - end - end local obx, oby = self:getAnchorPosition() local val = tostring(base.getValue()) local cursorX = (textX <= val:len() and textX - 1 or val:len()) - (wIndex - 1) @@ -198,21 +184,117 @@ return function(name) cursorX = self.x + w - 1 end if (self.parent ~= nil) then - self.parent:setCursor(true, obx + cursorX, oby+math.floor(h/2), self.fgColor) + self.parent:setCursor(true, obx + cursorX, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor) end internalValueChange = false - end - end; - - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - if (event == "mouse_click") and (button == 1) then - - end return true end return false - end; + end, + + charHandler = function(self, char) + if (base.charHandler(self, char)) then + internalValueChange = true + local w,h = self:getSize() + local text = base.getValue() + if (text:len() < inputLimit or inputLimit <= 0) then + if (inputType == "number") then + local cache = text + if (char == ".") or (tonumber(char) ~= nil) then + self:setValue(text:sub(1, textX - 1) .. char .. text:sub(textX, text:len())) + textX = textX + 1 + end + if (tonumber(base.getValue()) == nil) then + self:setValue(cache) + end + else + self:setValue(text:sub(1, textX - 1) .. char .. text:sub(textX, text:len())) + textX = textX + 1 + end + if (textX >= w + wIndex) then + wIndex = wIndex + 1 + end + end + local obx, oby = self:getAnchorPosition() + local val = tostring(base.getValue()) + local cursorX = (textX <= val:len() and textX - 1 or val:len()) - (wIndex - 1) + + local x = self:getX() + if (cursorX > x + w - 1) then + cursorX = x + w - 1 + end + if (self.parent ~= nil) then + self.parent:setCursor(true, obx + cursorX, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor) + end + internalValueChange = false + self:updateDraw() + return true + end + return false + end, + + mouseHandler = function(self, button, x, y) + if(base.mouseHandler(self, button, x, y))then + local ax, ay = self:getAnchorPosition() + local obx, oby = self:getAbsolutePosition(ax, ay) + local w, h = self:getSize() + textX = x - obx + wIndex + local text = base.getValue() + if (textX > text:len()) then + textX = text:len() + 1 + end + if (textX < wIndex) then + wIndex = textX - 1 + if (wIndex < 1) then + wIndex = 1 + end + end + self.parent:setCursor(true, obx + textX-1, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor) + return true + end + end, + + eventHandler = function(self, event, paste, p2, p3, p4) + if(base.eventHandler(self, event, paste, p2, p3, p4))then + if(event=="paste")then + if(self:isFocused())then + local text = base.getValue() + local w, h = self:getSize() + internalValueChange = true + if (inputType == "number") then + local cache = text + if (paste == ".") or (tonumber(paste) ~= nil) then + self:setValue(text:sub(1, textX - 1) .. paste .. text:sub(textX, text:len())) + textX = textX + paste:len() + end + if (tonumber(base.getValue()) == nil) then + self:setValue(cache) + end + else + self:setValue(text:sub(1, textX - 1) .. paste .. text:sub(textX, text:len())) + textX = textX + paste:len() + end + if (textX >= w + wIndex) then + wIndex = (textX+1)-w + end + + local obx, oby = self:getAnchorPosition() + local val = tostring(base.getValue()) + local cursorX = (textX <= val:len() and textX - 1 or val:len()) - (wIndex - 1) + + local x = self:getX() + if (cursorX > x + w - 1) then + cursorX = x + w - 1 + end + if (self.parent ~= nil) then + self.parent:setCursor(true, obx + cursorX, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor) + end + self:updateDraw() + internalValueChange = false + end + end + end + end, draw = function(self) if (base.draw(self)) then @@ -246,14 +328,24 @@ return function(name) if (inputType == "password") and (val ~= "") then text = string.rep("*", text:len()) end - text = text .. string.rep(" ", space) + text = text .. string.rep(self.bgSymbol, space) self.parent:writeText(obx, oby + (n - 1), text, bCol, fCol) end end end - self:setVisualChanged(false) end - end; + end, + + init = function(self) + self.bgColor = self.parent:getTheme("InputBG") + self.fgColor = self.parent:getTheme("InputText") + if(self.parent~=nil)then + self.parent:addEvent("mouse_click", self) + self.parent:addEvent("key", self) + self.parent:addEvent("char", self) + self.parent:addEvent("other_event", self) + end + end, } return setmetatable(object, base) diff --git a/Basalt/objects/Label.lua b/Basalt/objects/Label.lua index 8ac9765..b4bc53e 100644 --- a/Basalt/objects/Label.lua +++ b/Basalt/objects/Label.lua @@ -33,27 +33,28 @@ return function(name) if (autoSize) then self.width = text:len() end - if not(fgColChanged)then self.fgColor = self.parent:getForeground() or colors.white end - if not(bgColChanged)then self.bgColor = self.parent:getBackground() or colors.black end + self:updateDraw() return self end; setBackground = function(self, col) base.setBackground(self, col) bgColChanged = true + self:updateDraw() return self end, setForeground = function(self, col) base.setForeground(self, col) fgColChanged = true + self:updateDraw() return self end, setTextAlign = function(self, hor, vert) textHorizontalAlign = hor or textHorizontalAlign textVerticalAlign = vert or textVerticalAlign - self:setVisualChanged() + self:updateDraw() return self end; @@ -61,6 +62,7 @@ return function(name) if(size>0)and(size<=4)then fontsize = size-1 or 0 end + self:updateDraw() return self end; @@ -77,10 +79,10 @@ return function(name) return self end, - setSize = function(self, width, height) - base.setSize(self, width, height) + setSize = function(self, width, height, rel) + base.setSize(self, width, height, rel) autoSize = false - self:setVisualChanged() + self:updateDraw() return self end; @@ -90,47 +92,43 @@ return function(name) local obx, oby = self:getAnchorPosition() local w,h = self:getSize() local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign) - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) - self.parent:drawTextBox(obx, oby, w, h, " ") end - if(self.fgColor~=false)then self.parent:drawForegroundBox(obx, oby, w, h, self.fgColor) end if(fontsize==0)then if not(autoSize)then local text = createText(self:getValue(), self:getWidth()) for k,v in pairs(text)do - self.parent:setText(obx, oby+k-1, v) + self.parent:writeText(obx, oby+k-1, v, self.bgColor, self.fgColor) end else - for n = 1, h do - if (n == verticalAlign) then - self.parent:setText(obx, oby + (n - 1), utils.getTextHorizontalAlign(self:getValue(), w, textHorizontalAlign)) - end - end + self.parent:writeText(obx, oby, self:getValue(), self.bgColor, self.fgColor) end else - local tData = bigFont(fontsize, self:getValue(), self.fgColor, self.bgColor or colors.black) + local tData = bigFont(fontsize, self:getValue(), self.fgColor, self.bgColor or colors.lightGray) if(autoSize)then self:setSize(#tData[1][1], #tData[1]-1) end - for n = 1, h do - if (n == verticalAlign) then - local oX, oY = self.parent:getSize() - local cX, cY = #tData[1][1], #tData[1] - obx = obx or math.floor((oX - cX) / 2) + 1 - oby = oby or math.floor((oY - cY) / 2) + 1 - - for i = 1, cY do - self.parent:setFG(obx, oby + i + n - 2, utils.getTextHorizontalAlign(tData[2][i], w, textHorizontalAlign)) - self.parent:setBG(obx, oby + i + n - 2, utils.getTextHorizontalAlign(tData[3][i], w, textHorizontalAlign, tHex[self.bgColor or colors.black])) - self.parent:setText(obx, oby + i + n - 2, utils.getTextHorizontalAlign(tData[1][i], w, textHorizontalAlign)) - end + local oX, oY = self.parent:getSize() + local cX, cY = #tData[1][1], #tData[1] + obx = obx or math.floor((oX - cX) / 2) + 1 + oby = oby or math.floor((oY - cY) / 2) + 1 + + for i = 1, cY do + self.parent:setFG(obx, oby + i - 2, tData[2][i]) + self.parent:setBG(obx, oby + i - 2, tData[3][i]) + self.parent:setText(obx, oby + i - 2, tData[1][i]) end - end end end - self:setVisualChanged(false) end - end; + end, + init = function(self) + if(base.init(self))then + self.bgColor = self.parent:getTheme("LabelBG") + self.fgColor = self.parent:getTheme("LabelText") + if(self.parent.bgColor==colors.black)and(self.fgColor==colors.black)then + self.fgColor = colors.lightGray + end + end + end } diff --git a/Basalt/objects/List.lua b/Basalt/objects/List.lua index f42c7fd..b89683b 100644 --- a/Basalt/objects/List.lua +++ b/Basalt/objects/List.lua @@ -18,12 +18,6 @@ return function(name) local scrollable = true local object = { - init = function(self) - self.bgColor = self.parent:getTheme("ListBG") - self.fgColor = self.parent:getTheme("ListText") - itemSelectedBG = self.parent:getTheme("SelectionBG") - itemSelectedFG = self.parent:getTheme("SelectionText") - end, getType = function(self) return objectType end; @@ -33,11 +27,13 @@ return function(name) if (#list == 1) then self:setValue(list[1]) end + self:updateDraw() return self end; setOffset = function(self, yOff) yOffset = yOff + self:updateDraw() return self end; @@ -47,6 +43,7 @@ return function(name) removeItem = function(self, index) table.remove(list, index) + self:updateDraw() return self end; @@ -70,6 +67,7 @@ return function(name) clear = function(self) list = {} self:setValue({}) + self:updateDraw() return self end; @@ -80,23 +78,28 @@ return function(name) editItem = function(self, index, text, bgCol, fgCol, ...) table.remove(list, index) table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) + self:updateDraw() return self end; selectItem = function(self, index) self:setValue(list[index] or {}) + self:updateDraw() return self end; setSelectedItem = function(self, bgCol, fgCol, active) itemSelectedBG = bgCol or self.bgColor itemSelectedFG = fgCol or self.fgColor - selectionColorActive = active + selectionColorActive = active~=nil and active or true + self:updateDraw() return self end; setScrollable = function(self, scroll) scrollable = scroll + if(scroll==nil)then scrollable = true end + self:updateDraw() return self end; @@ -116,29 +119,15 @@ return function(name) return self end, - mouseHandler = function(self, event, button, x, y) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - local w,h = self:getSize() - if (obx <= x) and (obx + w > x) and (oby <= y) and (oby + h > y) and (self:isVisible()) then - if (((event == "mouse_click") or (event == "mouse_drag"))and(button==1))or(event=="monitor_touch") then - if (#list > 0) then - for n = 1, h do - if (list[n + yOffset] ~= nil) then - if (obx <= x) and (obx + w > x) and (oby + n - 1 == y) then - self:setValue(list[n + yOffset]) - self:getEventSystem():sendEvent("mouse_click", self, "mouse_click", 0, x, y, list[n + yOffset]) - end - end - end - end - end - - if (event == "mouse_scroll") and (scrollable) then - yOffset = yOffset + button + scrollHandler = function(self, dir, x, y) + if(base.scrollHandler(self, dir, x, y))then + if(scrollable)then + local w,h = self:getSize() + yOffset = yOffset + dir if (yOffset < 0) then yOffset = 0 end - if (button >= 1) then + if (dir >= 1) then if (#list > h) then if (yOffset > #list - h) then yOffset = #list - h @@ -150,11 +139,39 @@ return function(name) yOffset = yOffset - 1 end end + self:updateDraw() end - self:setVisualChanged() return true end - end; + return false + end, + + mouseHandler = function(self, button, x, y) + if(base.mouseHandler(self, button, x, y))then + local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) + local w,h = self:getSize() + if (#list > 0) then + for n = 1, h do + if (list[n + yOffset] ~= nil) then + if (obx <= x) and (obx + w > x) and (oby + n - 1 == y) then + self:setValue(list[n + yOffset]) + self:updateDraw() + end + end + end + end + return true + end + return false + end, + + dragHandler = function(self, button, x, y) + return self:mouseHandler(button, x, y) + end, + + touchHandler = function(self, x, y) + return self:mouseHandler(1, x, y) + end, draw = function(self) if (base.draw(self)) then @@ -178,9 +195,18 @@ return function(name) end end end - self:setVisualChanged(false) end - end; + end, + + init = function(self) + self.bgColor = self.parent:getTheme("ListBG") + self.fgColor = self.parent:getTheme("ListText") + itemSelectedBG = self.parent:getTheme("SelectionBG") + itemSelectedFG = self.parent:getTheme("SelectionText") + self.parent:addEvent("mouse_click", self) + self.parent:addEvent("mouse_drag", self) + self.parent:addEvent("mouse_scroll", self) + end, } return setmetatable(object, base) diff --git a/Basalt/objects/Menubar.lua b/Basalt/objects/Menubar.lua index 80dade1..0e28f5a 100644 --- a/Basalt/objects/Menubar.lua +++ b/Basalt/objects/Menubar.lua @@ -40,13 +40,6 @@ return function(name) end object = { - init = function(self) - self.bgColor = self.parent:getTheme("MenubarBG") - self.fgColor = self.parent:getTheme("MenubarText") - itemSelectedBG = self.parent:getTheme("SelectionBG") - itemSelectedFG = self.parent:getTheme("SelectionText") - end, - getType = function(self) return objectType end; @@ -56,6 +49,7 @@ return function(name) if (#list == 1) then self:setValue(list[1]) end + self:updateDraw() return self end; @@ -75,11 +69,13 @@ return function(name) clear = function(self) list = {} self:setValue({}) + self:updateDraw() return self end; setSpace = function(self, _space) space = _space or space + self:updateDraw() return self end; @@ -93,6 +89,7 @@ return function(name) if (itemOffset > mScroll) then itemOffset = mScroll end + self:updateDraw() return self end; @@ -125,6 +122,7 @@ return function(name) removeItem = function(self, index) table.remove(list, index) + self:updateDraw() return self end; @@ -139,11 +137,13 @@ return function(name) editItem = function(self, index, text, bgCol, fgCol, ...) table.remove(list, index) table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) + self:updateDraw() return self end; selectItem = function(self, index) self:setValue(list[index] or {}) + self:updateDraw() return self end; @@ -151,48 +151,49 @@ return function(name) itemSelectedBG = bgCol or self.bgColor itemSelectedFG = fgCol or self.fgColor selectionColorActive = active + self:updateDraw() return self end; - mouseHandler = function(self, event, button, x, y) - if(base.mouseHandler(self, event, button, x, y))then + mouseHandler = function(self, button, x, y) + if(base.mouseHandler(self, button, x, y))then local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) local w,h = self:getSize() - if (objX <= x) and (objX + w > x) and (objY <= y) and (objY + h > y) and (self:isVisible()) then - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) - end - if (event == "mouse_click") or (event == "monitor_touch") then - local xPos = 0 - for n = 1, #list do - if (list[n] ~= nil) then - if (objX + xPos <= x + itemOffset) and (objX + xPos + list[n].text:len() + (space*2) > x + itemOffset) and (objY == y) then - self:setValue(list[n]) - self:getEventSystem():sendEvent(event, self, event, 0, x, y, list[n]) - end - xPos = xPos + list[n].text:len() + space * 2 + local xPos = 0 + for n = 1, #list do + if (list[n] ~= nil) then + if (objX + xPos <= x + itemOffset) and (objX + xPos + list[n].text:len() + (space*2) > x + itemOffset) and (objY == y) then + self:setValue(list[n]) + self:getEventSystem():sendEvent(event, self, event, 0, x, y, list[n]) end - end - - end - if (event == "mouse_scroll") and (scrollable) then - itemOffset = itemOffset + button - if (itemOffset < 0) then - itemOffset = 0 - end - - local mScroll = maxScroll() - - if (itemOffset > mScroll) then - itemOffset = mScroll + xPos = xPos + list[n].text:len() + space * 2 end end - self:setVisualChanged(true) - return true - end + self:updateDraw() + return true end return false - end; + end, + + scrollHandler = function(self, dir, x, y) + if(base.scrollHandler(self, dir, x, y))then + if(scrollable)then + itemOffset = itemOffset + dir + if (itemOffset < 0) then + itemOffset = 0 + end + + local mScroll = maxScroll() + + if (itemOffset > mScroll) then + itemOffset = mScroll + end + self:updateDraw() + end + return true + end + return false + end, draw = function(self) if (base.draw(self)) then @@ -221,9 +222,19 @@ return function(name) self.parent:setBG(obx, oby, textBGCol:sub(itemOffset+1, w+itemOffset)) self.parent:setFG(obx, oby, textFGCol:sub(itemOffset+1, w+itemOffset)) end - self:setVisualChanged(false) end - end; + end, + + init = function(self) + self.bgColor = self.parent:getTheme("MenubarBG") + self.fgColor = self.parent:getTheme("MenubarText") + itemSelectedBG = self.parent:getTheme("SelectionBG") + itemSelectedFG = self.parent:getTheme("SelectionText") + + self.parent:addEvent("mouse_click", self) + self.parent:addEvent("mouse_scroll", self) + + end, } return setmetatable(object, base) diff --git a/Basalt/objects/Pane.lua b/Basalt/objects/Pane.lua index 1719fc7..cfe33b7 100644 --- a/Basalt/objects/Pane.lua +++ b/Basalt/objects/Pane.lua @@ -1,4 +1,5 @@ local Object = require("Object") +local log = require("basaltLogs") return function(name) -- Pane @@ -6,26 +7,21 @@ return function(name) local objectType = "Pane" local object = { - init = function(self) - self.bgColor = self.parent:getTheme("PaneBG") - self.fgColor = self.parent:getTheme("PaneBG") - end, getType = function(self) return objectType end; - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - local w,h = self:getSize() - self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) - self.parent:drawForegroundBox(obx, oby, w, h, self.fgColor) - end - self:setVisualChanged(false) - end - end; + setBackground = function(self, col, sym, symC) + base.setBackground(self, col, sym, symC) + return self + end, + init = function(self) + if(base.init(self))then + self.bgColor = self.parent:getTheme("PaneBG") + self.fgColor = self.parent:getTheme("PaneBG") + end + end, } return setmetatable(object, base) diff --git a/Basalt/objects/Program.lua b/Basalt/objects/Program.lua index 92cc44c..6a5df05 100644 --- a/Basalt/objects/Program.lua +++ b/Basalt/objects/Program.lua @@ -2,6 +2,7 @@ local Object = require("Object") local tHex = require("tHex") local process = require("process") local xmlValue = require("utils").getValueFromXML +local log = require("basaltLogs") local sub = string.sub @@ -12,7 +13,7 @@ return function(name, parent) local object local cachedPath - local function createBasaltWindow(x, y, width, height) + local function createBasaltWindow(x, y, width, height, self) local xCursor, yCursor = 1, 1 local bgColor, fgColor = colors.black, colors.white local cursorBlink = false @@ -51,6 +52,7 @@ return function(name, parent) cacheFG[n] = sub(cacheFG[n] == nil and emptyFG or cacheFG[n] .. emptyFG:sub(1, width - cacheFG[n]:len()), 1, width) cacheBG[n] = sub(cacheBG[n] == nil and emptyBG or cacheBG[n] .. emptyBG:sub(1, width - cacheBG[n]:len()), 1, width) end + base.updateDraw(base) end recreateWindowArray() @@ -118,6 +120,7 @@ return function(name, parent) cacheFG[yCursor] = sNewTextColor cacheBG[yCursor] = sNewBackgroundColor end + object:updateDraw() end xCursor = nEnd + 1 if (visible) then @@ -133,6 +136,7 @@ return function(name, parent) cacheT[_y] = sub(gText:sub(1, _x - 1) .. text .. gText:sub(_x + (text:len()), width), 1, width) end end + object:updateDraw() end local function setBG(_x, _y, colorStr) @@ -142,6 +146,7 @@ return function(name, parent) cacheBG[_y] = sub(gBG:sub(1, _x - 1) .. colorStr .. gBG:sub(_x + (colorStr:len()), width), 1, width) end end + object:updateDraw() end local function setFG(_x, _y, colorStr) @@ -151,6 +156,7 @@ return function(name, parent) cacheFG[_y] = sub(gFG:sub(1, _x - 1) .. colorStr .. gFG:sub(_x + (colorStr:len()), width), 1, width) end end + object:updateDraw() end local setTextColor = function(color) @@ -417,10 +423,43 @@ return function(name, parent) local paused = false local queuedEvent = {} + local function updateCursor(self) + local xCur, yCur = pWindow.getCursorPos() + local obx, oby = self:getAnchorPosition() + local w,h = self:getSize() + if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then + self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor()) + end + end + + local function mouseEvent(self, event, p1, x, y) + if (curProcess == nil) then + return false + end + if not (curProcess:isDead()) then + if not (paused) then + local absX, absY = self:getAbsolutePosition(self:getAnchorPosition(nil, nil, true)) + curProcess:resume(event, p1, x-absX+1, y-absY+1) + updateCursor(self) + end + end + end + + local function keyEvent(self, event, key, isHolding) + if (curProcess == nil) then + return false + end + if not (curProcess:isDead()) then + if not (paused) then + if (self.draw) then + curProcess:resume(event, key, isHolding) + updateCursor(self) + end + end + end + end + object = { - init = function(self) - self.bgColor = self.parent:getTheme("ProgramBG") - end, getType = function(self) return objectType end; @@ -461,7 +500,7 @@ return function(name, parent) setSize = function(self, width, height, rel) base.setSize(self, width, height, rel) - pWindow.basalt_resize(self:getSize()) + pWindow.basalt_resize(self:getWidth(), self:getHeight()) return self end; @@ -484,6 +523,16 @@ return function(name, parent) pWindow.basalt_setVisible(true) curProcess:resume() paused = false + if(self.parent~=nil)then + self.parent:addEvent("mouse_click", self) + self.parent:addEvent("mouse_up", self) + self.parent:addEvent("mouse_drag", self) + self.parent:addEvent("mouse_scroll", self) + self.parent:addEvent("key", self) + self.parent:addEvent("key_up", self) + self.parent:addEvent("char", self) + self.parent:addEvent("other_event", self) + end return self end; @@ -498,6 +547,7 @@ return function(name, parent) end end end + self.parent:removeEvents(self) return self end; @@ -551,36 +601,61 @@ return function(name, parent) return self end; - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - if (curProcess == nil) then - return false - end - if not (curProcess:isDead()) then - if not (paused) then - local absX, absY = self:getAbsolutePosition(self:getAnchorPosition(nil, nil, true)) - curProcess:resume(event, button, x-absX+1, y-absY+1) - end - end + mouseHandler = function(self, button, x, y) + if (base.mouseHandler(self, button, x, y)) then + mouseEvent(self, "mouse_click", button, x, y) return true end - end; + return false + end, - keyHandler = function(self, event, key) - base.keyHandler(self, event, key) - if (self:isFocused()) then - if (curProcess == nil) then - return false - end - if not (curProcess:isDead()) then - if not (paused) then - if (self.draw) then - curProcess:resume(event, key) - end - end - end + mouseUpHandler = function(self, button, x, y) + if (base.mouseUpHandler(self, button, x, y)) then + mouseEvent(self, "mouse_up", button, x, y) + return true end - end; + return false + end, + + scrollHandler = function(self, dir, x, y) + if (base.scrollHandler(self, dir, x, y)) then + mouseEvent(self, "mouse_scroll", dir, x, y) + return true + end + return false + end, + + dragHandler = function(self, button, x, y) + if (base.dragHandler(self, button, x, y)) then + mouseEvent(self, "mouse_drag", button, x, y) + return true + end + return false + end, + + keyHandler = function(self, key, isHolding) + if(base.keyHandler(self, key, isHolding))then + keyEvent(self, "key", key, isHolding) + return true + end + return false + end, + + keyUpHandler = function(self, key) + if(base.keyUpHandler(self, key))then + keyEvent(self, "key_up", key) + return true + end + return false + end, + + charHandler = function(self, char) + if(base.charHandler(self, char))then + keyEvent(self, "char", char) + return true + end + return false + end, getFocusHandler = function(self) base.getFocusHandler(self) @@ -600,7 +675,7 @@ return function(name, parent) end end end - end; + end, loseFocusHandler = function(self) base.loseFocusHandler(self) @@ -611,38 +686,54 @@ return function(name, parent) end end end - end; + end, eventHandler = function(self, event, p1, p2, p3, p4) - if (curProcess == nil) then - return - end - if not (curProcess:isDead()) then - if not (paused) then - if (event ~= "mouse_click") and (event ~= "monitor_touch") and (event ~= "mouse_up") and (event ~= "mouse_scroll") and (event ~= "mouse_drag") and (event ~= "key_up") and (event ~= "key") and (event ~= "char") and (event ~= "terminate") then - curProcess:resume(event, p1, p2, p3, p4) + if(base.eventHandler(self, event, p1, p2, p3, p4))then + if (curProcess == nil) then + return + end + if(event=="dynamicValueEvent")then + local w, h = pWindow.getSize() + local pW, pH = self:getSize() + if(w~=pW)or(h~=pH)then + pWindow.basalt_resize(pW, pH) + if not (curProcess:isDead()) then + curProcess:resume("term_resize") + end end - if (self:isFocused()) then - local obx, oby = self:getAnchorPosition() - local xCur, yCur = pWindow.getCursorPos() - if (self.parent ~= nil) then - local w,h = self:getSize() - if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then - self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor()) + pWindow.basalt_reposition(self:getAnchorPosition()) + + end + if not (curProcess:isDead()) then + if not (paused) then + if(event ~= "terminate") then + curProcess:resume(event, p1, p2, p3, p4) + end + if (self:isFocused()) then + local obx, oby = self:getAnchorPosition() + local xCur, yCur = pWindow.getCursorPos() + if (self.parent ~= nil) then + local w,h = self:getSize() + if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then + self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor()) + end + end + + if (event == "terminate") then + log(self:isFocused()) + curProcess:resume(event) + self.parent:setCursor(false) + return true end end - - if (event == "terminate") and (self:isFocused()) then - self:stop() - end - end - else - if (event ~= "mouse_click") and (event ~= "monitor_touch") and (event ~= "mouse_up") and (event ~= "mouse_scroll") and (event ~= "mouse_drag") and (event ~= "key_up") and (event ~= "key") and (event ~= "char") and (event ~= "terminate") then + else table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } }) end end + return false end - end; + end, draw = function(self) if (base.draw(self)) then @@ -650,14 +741,14 @@ return function(name, parent) local obx, oby = self:getAnchorPosition() local w,h = self:getSize() pWindow.basalt_reposition(obx, oby) - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) - end pWindow.basalt_update() end - self:setVisualChanged(false) end - end; + end, + + init = function(self) + self.bgColor = self.parent:getTheme("ProgramBG") + end, } diff --git a/Basalt/objects/Progressbar.lua b/Basalt/objects/Progressbar.lua index 390ca7b..ab5974c 100644 --- a/Basalt/objects/Progressbar.lua +++ b/Basalt/objects/Progressbar.lua @@ -42,6 +42,7 @@ return function(name) setDirection = function(self, dir) direction = dir + self:updateDraw() return self end; @@ -49,11 +50,13 @@ return function(name) activeBarColor = color or activeBarColor activeBarSymbol = symbol or activeBarSymbol activeBarSymbolCol = symbolcolor or activeBarSymbolCol + self:updateDraw() return self end; setBackgroundSymbol = function(self, symbol) bgBarSymbol = symbol:sub(1, 1) + self:updateDraw() return self end; @@ -65,6 +68,7 @@ return function(name) self:progressDoneHandler() end end + self:updateDraw() return self end; @@ -107,9 +111,8 @@ return function(name) self.parent:drawTextBox(obx, oby, w / 100 * progress, h, activeBarSymbol) end end - self:setVisualChanged(false) end - end; + end, } diff --git a/Basalt/objects/Radio.lua b/Basalt/objects/Radio.lua index 0b5f8e6..82854b1 100644 --- a/Basalt/objects/Radio.lua +++ b/Basalt/objects/Radio.lua @@ -20,16 +20,6 @@ return function(name) local align = "left" local object = { - - init = function(self) - self.bgColor = self.parent:getTheme("MenubarBG") - self.fgColor = self.parent:getTheme("MenubarFG") - itemSelectedBG = self.parent:getTheme("SelectionBG") - itemSelectedFG = self.parent:getTheme("SelectionText") - boxSelectedBG = self.parent:getTheme("MenubarBG") - boxSelectedFG = self.parent:getTheme("MenubarText") - end, - getType = function(self) return objectType end; @@ -58,6 +48,7 @@ return function(name) if (#list == 1) then self:setValue(list[1]) end + self:updateDraw() return self end; @@ -67,6 +58,7 @@ return function(name) removeItem = function(self, index) table.remove(list, index) + self:updateDraw() return self end; @@ -86,6 +78,7 @@ return function(name) clear = function(self) list = {} self:setValue({}) + self:updateDraw() return self end; @@ -96,16 +89,19 @@ return function(name) editItem = function(self, index, text, x, y, bgCol, fgCol, ...) table.remove(list, index) table.insert(list, index, { x = x or 1, y = y or 1, text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) + self:updateDraw() return self end; selectItem = function(self, index) self:setValue(list[index] or {}) + self:updateDraw() return self end; setActiveSymbol = function(self, sym) symbol = sym:sub(1,1) + self:updateDraw() return self end, @@ -115,23 +111,23 @@ return function(name) boxSelectedBG = boxBG or boxSelectedBG boxSelectedFG = boxFG or boxSelectedFG selectionColorActive = active~=nil and active or true + self:updateDraw() return self end; - mouseHandler = function(self, event, button, x, y) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if ((event == "mouse_click")and(button==1))or(event=="monitor_touch") then - if (#list > 0) then - for _, value in pairs(list) do - if (obx + value.x - 1 <= x) and (obx + value.x - 1 + value.text:len() + 2 >= x) and (oby + value.y - 1 == y) then - self:setValue(value) - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) - end - self:getEventSystem():sendEvent(event, self, event, button, x, y) - self:setVisualChanged() - return true + mouseHandler = function(self, button, x, y) + if (#list > 0) then + local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) + for _, value in pairs(list) do + if (obx + value.x - 1 <= x) and (obx + value.x - 1 + value.text:len() + 1 >= x) and (oby + value.y - 1 == y) then + self:setValue(value) + local val = self:getEventSystem():sendEvent("mouse_click", self, "mouse_click", button, x, y) + if(val==false)then return val end + if(self.parent~=nil)then + self.parent:setFocusedObject(self) end + self:updateDraw() + return true end end end @@ -139,24 +135,32 @@ return function(name) end; draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - for _, value in pairs(list) do - if (value == self:getValue()) then - if (align == "left") then - self.parent:writeText(value.x + obx - 1, value.y + oby - 1, symbol, boxSelectedBG, boxSelectedFG) - self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, itemSelectedBG, itemSelectedFG) - end - else - self.parent:drawBackgroundBox(value.x + obx - 1, value.y + oby - 1, 1, 1, boxNotSelectedBG or self.bgColor) - self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, value.bgCol, value.fgCol) + if (self.parent ~= nil) then + local obx, oby = self:getAnchorPosition() + for _, value in pairs(list) do + if (value == self:getValue()) then + if (align == "left") then + self.parent:writeText(value.x + obx - 1, value.y + oby - 1, symbol, boxSelectedBG, boxSelectedFG) + self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, itemSelectedBG, itemSelectedFG) end + else + self.parent:drawBackgroundBox(value.x + obx - 1, value.y + oby - 1, 1, 1, boxNotSelectedBG or self.bgColor) + self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, value.bgCol, value.fgCol) end end - self:setVisualChanged(false) + return true end - end; + end, + + init = function(self) + self.bgColor = self.parent:getTheme("MenubarBG") + self.fgColor = self.parent:getTheme("MenubarFG") + itemSelectedBG = self.parent:getTheme("SelectionBG") + itemSelectedFG = self.parent:getTheme("SelectionText") + boxSelectedBG = self.parent:getTheme("MenubarBG") + boxSelectedFG = self.parent:getTheme("MenubarText") + self.parent:addEvent("mouse_click", self) + end, } return setmetatable(object, base) diff --git a/Basalt/objects/Scrollbar.lua b/Basalt/objects/Scrollbar.lua index e03e4d4..dbe46ed 100644 --- a/Basalt/objects/Scrollbar.lua +++ b/Basalt/objects/Scrollbar.lua @@ -18,19 +18,37 @@ return function(name) local index = 1 local symbolSize = 1 + local function mouseEvent(self, button, x, y) + local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) + local w,h = self:getSize() + if (barType == "horizontal") then + for _index = 0, w do + if (obx + _index == x) and (oby <= y) and (oby + h > y) then + index = math.min(_index + 1, w - (symbolSize - 1)) + self:setValue(maxValue / w * (index)) + self:updateDraw() + end + end + end + if (barType == "vertical") then + for _index = 0, h do + if (oby + _index == y) and (obx <= x) and (obx + w > x) then + index = math.min(_index + 1, h - (symbolSize - 1)) + self:setValue(maxValue / h * (index)) + self:updateDraw() + end + end + end + end + local object = { - init = function(self) - self.bgColor = self.parent:getTheme("ScrollbarBG") - self.fgColor = self.parent:getTheme("ScrollbarText") - symbolColor = self.parent:getTheme("ScrollbarSymbolColor") - end, getType = function(self) return objectType end; setSymbol = function(self, _symbol) symbol = _symbol:sub(1, 1) - self:setVisualChanged() + self:updateDraw() return self end; @@ -53,6 +71,7 @@ return function(name) local w,h = self:getSize() index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1)) self:setValue(maxValue / (barType == "vertical" and h or w) * index) + self:updateDraw() return self end, @@ -68,67 +87,62 @@ return function(name) elseif (barType == "horizontal") then self:setValue(index - 1 * (maxValue / (w - (symbolSize - 1))) - (maxValue / (w - (symbolSize - 1)))) end - self:setVisualChanged() + self:updateDraw() return self end; setMaxValue = function(self, val) maxValue = val + self:updateDraw() return self end; setBackgroundSymbol = function(self, _bgSymbol) bgSymbol = string.sub(_bgSymbol, 1, 1) - self:setVisualChanged() + self:updateDraw() return self end; setSymbolColor = function(self, col) symbolColor = col - self:setVisualChanged() + self:updateDraw() return self end; setBarType = function(self, _typ) barType = _typ:lower() + self:updateDraw() return self end; - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - local w,h = self:getSize() - if (((event == "mouse_click") or (event == "mouse_drag")) and (button == 1))or(event=="monitor_touch") then - if (barType == "horizontal") then - for _index = 0, w do - if (obx + _index == x) and (oby <= y) and (oby + h > y) then - index = math.min(_index + 1, w - (symbolSize - 1)) - self:setValue(maxValue / w * (index)) - self:setVisualChanged() - end - end - end - if (barType == "vertical") then - for _index = 0, h do - if (oby + _index == y) and (obx <= x) and (obx + w > x) then - index = math.min(_index + 1, h - (symbolSize - 1)) - self:setValue(maxValue / h * (index)) - self:setVisualChanged() - end - end - end - end - if (event == "mouse_scroll") then - index = index + button - if (index < 1) then - index = 1 - end - index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1)) - self:setValue(maxValue / (barType == "vertical" and h or w) * index) - end + mouseHandler = function(self, button, x, y) + if (base.mouseHandler(self, button, x, y)) then + mouseEvent(self, button, x, y) return true end - end; + return false + end, + + dragHandler = function(self, button, x, y) + if (base.dragHandler(self, button, x, y)) then + mouseEvent(self, button, x, y) + return true + end + return false + end, + + scrollHandler = function(self, dir, x, y) + if(base.scrollHandler(self, dir, x, y))then + local w,h = self:getSize() + index = index + dir + if (index < 1) then + index = 1 + end + index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1)) + self:setValue(maxValue / (barType == "vertical" and h or w) * index) + self:updateDraw() + end + end, draw = function(self) if (base.draw(self)) then @@ -155,9 +169,17 @@ return function(name) end end end - self:setVisualChanged(false) end - end; + end, + + init = function(self) + self.bgColor = self.parent:getTheme("ScrollbarBG") + self.fgColor = self.parent:getTheme("ScrollbarText") + symbolColor = self.parent:getTheme("ScrollbarSymbolColor") + self.parent:addEvent("mouse_click", self) + self.parent:addEvent("mouse_drag", self) + self.parent:addEvent("mouse_scroll", self) + end, } return setmetatable(object, base) diff --git a/Basalt/objects/Slider.lua b/Basalt/objects/Slider.lua index f2b4499..4a71c6a 100644 --- a/Basalt/objects/Slider.lua +++ b/Basalt/objects/Slider.lua @@ -1,4 +1,5 @@ local Object = require("Object") +local log = require("basaltLogs") local xmlValue = require("utils").getValueFromXML return function(name) @@ -17,19 +18,37 @@ return function(name) local index = 1 local symbolSize = 1 + local function mouseEvent(self, button, x, y) + local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) + local w,h = self:getSize() + if (barType == "horizontal") then + for _index = 0, w do + if (obx + _index == x) and (oby <= y) and (oby + h > y) then + index = math.min(_index + 1, w - (symbolSize - 1)) + self:setValue(maxValue / w * (index)) + self:updateDraw() + end + end + end + if (barType == "vertical") then + for _index = 0, h do + if (oby + _index == y) and (obx <= x) and (obx + w > x) then + index = math.min(_index + 1, h - (symbolSize - 1)) + self:setValue(maxValue / h * (index)) + self:updateDraw() + end + end + end + end + local object = { - init = function(self) - self.bgColor = self.parent:getTheme("SliderBG") - self.fgColor = self.parent:getTheme("SliderText") - symbolColor = self.parent:getTheme("SliderSymbolColor") - end, getType = function(self) return objectType end; setSymbol = function(self, _symbol) symbol = _symbol:sub(1, 1) - self:setVisualChanged() + self:updateDraw() return self end; @@ -52,6 +71,7 @@ return function(name) local w,h = self:getSize() index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1)) self:setValue(maxValue / (barType == "vertical" and h or w) * index) + self:updateDraw() return self end, @@ -66,7 +86,7 @@ return function(name) elseif (barType == "horizontal") then self:setValue(index - 1 * (maxValue / (w - (symbolSize - 1))) - (maxValue / (w - (symbolSize - 1)))) end - self:setVisualChanged() + self:updateDraw() return self end; @@ -77,56 +97,52 @@ return function(name) setBackgroundSymbol = function(self, _bgSymbol) bgSymbol = string.sub(_bgSymbol, 1, 1) - self:setVisualChanged() + self:updateDraw() return self end; setSymbolColor = function(self, col) symbolColor = col - self:setVisualChanged() + self:updateDraw() return self end; setBarType = function(self, _typ) barType = _typ:lower() + self:updateDraw() return self end; - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - local w,h = self:getSize() - if (((event == "mouse_click") or (event == "mouse_drag")) and (button == 1))or(event=="monitor_touch") then - if (barType == "horizontal") then - for _index = 0, w do - if (obx + _index == x) and (oby <= y) and (oby + h > y) then - index = math.min(_index + 1, w - (symbolSize - 1)) - self:setValue(maxValue / w * (index)) - self:setVisualChanged() - end - end - end - if (barType == "vertical") then - for _index = 0, h do - if (oby + _index == y) and (obx <= x) and (obx + w > x) then - index = math.min(_index + 1, h - (symbolSize - 1)) - self:setValue(maxValue / h * (index)) - self:setVisualChanged() - end - end - end - end - if (event == "mouse_scroll") then - index = index + button - if (index < 1) then - index = 1 - end - index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1)) - self:setValue(maxValue / (barType == "vertical" and h or w) * index) - end + mouseHandler = function(self, button, x, y) + if (base.mouseHandler(self, button, x, y)) then + mouseEvent(self, button, x, y) return true end - end; + return false + end, + + dragHandler = function(self, button, x, y) + if (base.dragHandler(self, button, x, y)) then + mouseEvent(self, button, x, y) + return true + end + return false + end, + + scrollHandler = function(self, dir, x, y) + if(base.scrollHandler(self, dir, x, y))then + local w,h = self:getSize() + index = index + dir + if (index < 1) then + index = 1 + end + index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1)) + self:setValue(maxValue / (barType == "vertical" and h or w) * index) + self:updateDraw() + return true + end + return false + end, draw = function(self) if (base.draw(self)) then @@ -141,7 +157,6 @@ return function(name) if (barType == "vertical") then for n = 0, h - 1 do - if (index == n + 1) then for curIndexOffset = 0, math.min(symbolSize - 1, h) do self.parent:writeText(obx, oby + n + curIndexOffset, symbol, symbolColor, symbolColor) @@ -154,9 +169,17 @@ return function(name) end end end - self:setVisualChanged(false) end - end; + end, + + init = function(self) + self.bgColor = self.parent:getTheme("SliderBG") + self.fgColor = self.parent:getTheme("SliderText") + symbolColor = self.parent:getTheme("SliderSymbolColor") + self.parent:addEvent("mouse_click", self) + self.parent:addEvent("mouse_drag", self) + self.parent:addEvent("mouse_scroll", self) + end, } return setmetatable(object, base) diff --git a/Basalt/objects/Switch.lua b/Basalt/objects/Switch.lua index 5d0aaed..8eb4603 100644 --- a/Basalt/objects/Switch.lua +++ b/Basalt/objects/Switch.lua @@ -17,32 +17,25 @@ return function(name) local activeBG = colors.green local object = { - init = function(self) - self.bgColor = self.parent:getTheme("SwitchBG") - self.fgColor = self.parent:getTheme("SwitchText") - bgSymbol = self.parent:getTheme("SwitchBGSymbol") - inactiveBG = self.parent:getTheme("SwitchInactive") - activeBG = self.parent:getTheme("SwitchActive") - end, getType = function(self) return objectType end; setSymbolColor = function(self, symbolColor) bgSymbol = symbolColor - self:setVisualChanged() + self:updateDraw() return self end; setActiveBackground = function(self, bgcol) activeBG = bgcol - self:setVisualChanged() + self:updateDraw() return self end; setInactiveBackground = function(self, bgcol) inactiveBG = bgcol - self:setVisualChanged() + self:updateDraw() return self end; @@ -54,12 +47,11 @@ return function(name) end, - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then + mouseHandler = function(self, button, x, y) + if (base.mouseHandler(self, button, x, y)) then local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if ((event == "mouse_click") and (button == 1))or(event=="monitor_touch") then - self:setValue(not self:getValue()) - end + self:setValue(not self:getValue()) + self:updateDraw() return true end end; @@ -78,9 +70,17 @@ return function(name) self.parent:drawBackgroundBox(obx+1, oby, 1, h, inactiveBG) end end - self:setVisualChanged(false) end - end; + end, + + init = function(self) + self.bgColor = self.parent:getTheme("SwitchBG") + self.fgColor = self.parent:getTheme("SwitchText") + bgSymbol = self.parent:getTheme("SwitchBGSymbol") + inactiveBG = self.parent:getTheme("SwitchInactive") + activeBG = self.parent:getTheme("SwitchActive") + self.parent:addEvent("mouse_click", self) + end, } return setmetatable(object, base) diff --git a/Basalt/objects/Textfield.lua b/Basalt/objects/Textfield.lua index 19dbc76..c9c59ba 100644 --- a/Basalt/objects/Textfield.lua +++ b/Basalt/objects/Textfield.lua @@ -1,7 +1,10 @@ local Object = require("Object") local tHex = require("tHex") +local log = require("basaltLogs") local xmlValue = require("utils").getValueFromXML +local rep = string.rep + return function(name) local base = Object(name) local objectType = "Textfield" @@ -65,6 +68,7 @@ return function(name) end fgLines[l] = fgLine bgLines[l] = bgLine + self:updateDraw() end local function updateAllColors(self) @@ -74,10 +78,6 @@ return function(name) end local object = { - init = function(self) - self.bgColor = self.parent:getTheme("TextfieldBG") - self.fgColor = self.parent:getTheme("TextfieldText") - end, getType = function(self) return objectType end; @@ -144,6 +144,7 @@ return function(name) editLine = function(self, index, text) lines[index] = text or lines[index] + self:updateDraw() return self end; @@ -152,6 +153,7 @@ return function(name) bgLines = {""} fgLines = {""} hIndex, wIndex, textX, textY = 1, 1, 1, 1 + self:updateDraw() return self end, @@ -173,6 +175,7 @@ return function(name) table.insert(fgLines, tHex[self.fgColor]:rep(text:len())) end end + self:updateDraw() return self end; @@ -183,11 +186,13 @@ return function(name) for k,v in pairs(tab)do table.insert(keyWords[color], v) end + self:updateDraw() return self end; addRule = function(self, rule, fg, bg) table.insert(rules, {rule, fg, bg}) + self:updateDraw() return self end; @@ -198,6 +203,7 @@ return function(name) rules[k][3] = bg end end + self:updateDraw() return self end; @@ -207,11 +213,13 @@ return function(name) table.remove(rules, k) end end + self:updateDraw() return self end; setKeywords = function(self, color, tab) keyWords[color] = tab + self:updateDraw() return self end; @@ -220,6 +228,7 @@ return function(name) if (#lines <= 0) then table.insert(lines, "") end + self:updateDraw() return self end; @@ -244,11 +253,10 @@ return function(name) end end; - keyHandler = function(self, event, key) + keyHandler = function(self, key) if (base.keyHandler(self, event, key)) then local obx, oby = self:getAnchorPosition() local w,h = self:getSize() - if (event == "key") then if (key == keys.backspace) then -- on backspace if (lines[textY] == "") then @@ -361,7 +369,14 @@ return function(name) if (textX > lines[textY]:len() + 1) then textX = lines[textY]:len() + 1 end - + if (wIndex > 1) then + if (textX < wIndex) then + wIndex = textX - w + 1 + if (wIndex < 1) then + wIndex = 1 + end + end + end if (textY >= hIndex + h) then hIndex = hIndex + 1 end @@ -411,19 +426,6 @@ return function(name) wIndex = 1 end end - end - - if (event == "char") then - lines[textY] = lines[textY]:sub(1, textX - 1) .. key .. lines[textY]:sub(textX, lines[textY]:len()) - fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[self.fgColor] .. fgLines[textY]:sub(textX, fgLines[textY]:len()) - bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self.bgColor] .. bgLines[textY]:sub(textX, bgLines[textY]:len()) - textX = textX + 1 - if (textX >= w + wIndex) then - wIndex = wIndex + 1 - end - updateColors(self) - self:setValue("") - end local cursorX = (textX <= lines[textY]:len() and textX - 1 or lines[textY]:len()) - (wIndex - 1) if (cursorX > self.x + w - 1) then @@ -434,17 +436,46 @@ return function(name) cursorX = 0 end self.parent:setCursor(true, obx + cursorX, oby + cursorY, self.fgColor) + self:updateDraw() return true end - end; + end, - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then + charHandler = function(self, char) + if(base.charHandler(self, char))then + local obx, oby = self:getAnchorPosition() + local w,h = self:getSize() + lines[textY] = lines[textY]:sub(1, textX - 1) .. char .. lines[textY]:sub(textX, lines[textY]:len()) + fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[self.fgColor] .. fgLines[textY]:sub(textX, fgLines[textY]:len()) + bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self.bgColor] .. bgLines[textY]:sub(textX, bgLines[textY]:len()) + textX = textX + 1 + if (textX >= w + wIndex) then + wIndex = wIndex + 1 + end + updateColors(self) + self:setValue("") + + local cursorX = (textX <= lines[textY]:len() and textX - 1 or lines[textY]:len()) - (wIndex - 1) + if (cursorX > self.x + w - 1) then + cursorX = self.x + w - 1 + end + local cursorY = (textY - hIndex < h and textY - hIndex or textY - hIndex - 1) + if (cursorX < 1) then + cursorX = 0 + end + self.parent:setCursor(true, obx + cursorX, oby + cursorY, self.fgColor) + self:updateDraw() + return true + end + end, + + dragHandler = function(self, button, x, y) + if (base.dragHandler(self, button, x, y)) then local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) local anchx, anchy = self:getAnchorPosition() local w,h = self:getSize() - if (event == "mouse_click")or(event=="monitor_touch") then - if (lines[y - oby + hIndex] ~= nil) then + if (lines[y - oby + hIndex] ~= nil) then + if(anchx+w > anchx + x - (obx+1)+ wIndex)and(anchx < anchx + x - obx+ wIndex)then textX = x - obx + wIndex textY = y - oby + hIndex if (textX > lines[textY]:len()) then @@ -459,61 +490,89 @@ return function(name) if (self.parent ~= nil) then self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor) end + self:updateDraw() end end - if (event == "mouse_drag") then - if (lines[y - oby + hIndex] ~= nil) then - textX = x - obx + wIndex - textY = y - oby + hIndex - if (textX > lines[textY]:len()) then - textX = lines[textY]:len() + 1 - end - if (textX < wIndex) then - wIndex = textX - 1 - if (wIndex < 1) then - wIndex = 1 - end - end - if (self.parent ~= nil) then - self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor) - end - end - end - - if (event == "mouse_scroll") then - hIndex = hIndex + button - if (hIndex > #lines - (h - 1)) then - hIndex = #lines - (h - 1) - end - - if (hIndex < 1) then - hIndex = 1 - end - - if (self.parent ~= nil) then - if (obx + textX - wIndex >= obx and obx + textX - wIndex < obx + w) and (oby + textY - hIndex >= oby and oby + textY - hIndex < oby + h) then - self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor) - else - self.parent:setCursor(false) - end - end - end - self:setVisualChanged() return true end - end; + end, + + scrollHandler = function(self, dir, x, y) + if (base.scrollHandler(self, dir, x, y)) then + local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) + local anchx, anchy = self:getAnchorPosition() + local w,h = self:getSize() + hIndex = hIndex + dir + if (hIndex > #lines - (h - 1)) then + hIndex = #lines - (h - 1) + end + + if (hIndex < 1) then + hIndex = 1 + end + + if (self.parent ~= nil) then + if (obx + textX - wIndex >= obx and obx + textX - wIndex < obx + w) and (oby + textY - hIndex >= oby and oby + textY - hIndex < oby + h) then + self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor) + else + self.parent:setCursor(false) + end + end + self:updateDraw() + return true + end + end, + + mouseHandler = function(self, button, x, y) + if (base.mouseHandler(self, button, x, y)) then + local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) + local anchx, anchy = self:getAnchorPosition() + if (lines[y - oby + hIndex] ~= nil) then + textX = x - obx + wIndex + textY = y - oby + hIndex + if (textX > lines[textY]:len()) then + textX = lines[textY]:len() + 1 + end + if (textX < wIndex) then + wIndex = textX - 1 + if (wIndex < 1) then + wIndex = 1 + end + end + end + if (self.parent ~= nil) then + self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor) + end + return true + end + end, + + eventHandler = function(self, event, paste, p2, p3, p4) + if(base.eventHandler(self, event, paste, p2, p3, p4))then + if(event=="paste")then + if(self:isFocused())then + local w, h = self:getSize() + lines[textY] = lines[textY]:sub(1, textX - 1) .. paste .. lines[textY]:sub(textX, lines[textY]:len()) + fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[self.fgColor]:rep(paste:len()) .. fgLines[textY]:sub(textX, fgLines[textY]:len()) + bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self.bgColor]:rep(paste:len()) .. bgLines[textY]:sub(textX, bgLines[textY]:len()) + textX = textX + paste:len() + if (textX >= w + wIndex) then + wIndex = (textX+1)-w + end + local anchx, anchy = self:getAnchorPosition() + self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor) + updateColors(self) + self:updateDraw() + end + end + end + end, draw = function(self) if (base.draw(self)) then if (self.parent ~= nil) then local obx, oby = self:getAnchorPosition() local w,h = self:getSize() - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) - end - if(self.fgColor~=false)then - self.parent:drawForegroundBox(obx, oby, w, h, self.fgColor) - end for n = 1, h do local text = "" local bg = "" @@ -530,17 +589,27 @@ return function(name) if (space < 0) then space = 0 end - text = text .. string.rep(" ", space) - bg = bg .. string.rep(tHex[self.bgColor], space) - fg = fg .. string.rep(tHex[self.fgColor], space) + text = text .. rep(self.bgSymbol, space) + bg = bg .. rep(tHex[self.bgColor], space) + fg = fg .. rep(tHex[self.fgColor], space) self.parent:setText(obx, oby + n - 1, text) self.parent:setBG(obx, oby + n - 1, bg) self.parent:setFG(obx, oby + n - 1, fg) end end - self:setVisualChanged(false) end - end; + end, + + init = function(self) + self.bgColor = self.parent:getTheme("TextfieldBG") + self.fgColor = self.parent:getTheme("TextfieldText") + self.parent:addEvent("mouse_click", self) + self.parent:addEvent("mouse_scroll", self) + self.parent:addEvent("mouse_drag", self) + self.parent:addEvent("key", self) + self.parent:addEvent("char", self) + self.parent:addEvent("other_event", self) + end, } return setmetatable(object, base) diff --git a/Basalt/objects/Thread.lua b/Basalt/objects/Thread.lua index b7e4d54..8dd3f6f 100644 --- a/Basalt/objects/Thread.lua +++ b/Basalt/objects/Thread.lua @@ -59,6 +59,7 @@ return function(name) error("Thread Error Occurred - " .. result) end end + self.parent:addEvent("other_event", self) return self end; @@ -71,6 +72,7 @@ return function(name) stop = function(self, f) isActive = false + self.parent:removeEvent("other_event", self) return self end; diff --git a/Basalt/objects/Timer.lua b/Basalt/objects/Timer.lua index 62ca3ee..3e0c2a6 100644 --- a/Basalt/objects/Timer.lua +++ b/Basalt/objects/Timer.lua @@ -74,6 +74,7 @@ return function(name) repeats = savedRepeats timerObj = os.startTimer(timer) timerIsActive = true + self.parent:addEvent("other_event", self) return self end; @@ -86,6 +87,7 @@ return function(name) os.cancelTimer(timerObj) end timerIsActive = false + self.parent:removeEvent("other_event", self) return self end; diff --git a/Basalt/theme.lua b/Basalt/theme.lua index def7755..6c0e1be 100644 --- a/Basalt/theme.lua +++ b/Basalt/theme.lua @@ -31,7 +31,7 @@ return { -- The default main theme for basalt! ScrollbarBG = colors.lightGray, ScrollbarText = colors.gray, ScrollbarSymbolColor = colors.black, - SliderBG = colors.lightGray, + SliderBG = false, SliderText = colors.gray, SliderSymbolColor = colors.black, SwitchBG = colors.lightGray, @@ -39,5 +39,7 @@ return { -- The default main theme for basalt! SwitchBGSymbol = colors.black, SwitchInactive = colors.red, SwitchActive = colors.green, + LabelBG = false, + LabelText = colors.black } \ No newline at end of file