From f2e2e773f54dc70811eba39dc3c6185844f0eebf Mon Sep 17 00:00:00 2001 From: Robert Jelic <36573031+NoryiE@users.noreply.github.com> Date: Mon, 25 Jul 2022 21:09:37 +0200 Subject: [PATCH] bugfix + changes - added getMinScroll and getMaxScroll for frames - fixed a small bug with dynamicvalues - textfield got a :clear() function - improved the focus system - fixed a bug with dynamic values getting into a infinite loop --- Basalt/Frame.lua | 67 +++++++++++++++++----------- Basalt/Object.lua | 18 ++++---- Basalt/libraries/utils.lua | 38 ++++++++++++---- Basalt/main.lua | 84 +++++++++++++++++++----------------- Basalt/objects/Animation.lua | 17 +++++--- Basalt/objects/Label.lua | 13 +----- Basalt/objects/Radio.lua | 9 +++- Basalt/objects/Textfield.lua | 8 ++++ 8 files changed, 154 insertions(+), 100 deletions(-) diff --git a/Basalt/Frame.lua b/Basalt/Frame.lua index 4f40369..c61dcaa 100644 --- a/Basalt/Frame.lua +++ b/Basalt/Frame.lua @@ -36,6 +36,9 @@ return function(name, parent, pTerm, basalt) local mirrorSide = "" local importantScroll = false + local focusedOBjectCache + local focusedObject + base:setZIndex(10) local basaltDraw = BasaltDraw(termObject) @@ -151,6 +154,11 @@ return function(name, parent, pTerm, basalt) end local function newDynamicValue(_, obj, str) + for k,v in pairs(dynamicValues)do + if(v[2]==str)and(v[4]==obj)then + return v + end + end dynValueId = dynValueId + 1 dynamicValues[dynValueId] = {0, str, {}, obj, dynValueId} return dynamicValues[dynValueId] @@ -244,14 +252,7 @@ return function(name, parent, pTerm, basalt) end; setFocusedObject = function(self, obj) - if (basalt.getFocusedObject() ~= nil) then - basalt.getFocusedObject():loseFocusHandler() - basalt.setFocusedObject(nil) - end - if(obj~=nil)then - basalt.setFocusedObject(obj) - obj:getFocusHandler() - end + focusedOBjectCache = obj return self end; @@ -306,24 +307,21 @@ return function(name, parent, pTerm, basalt) return self end; - getOffset = function(self) + getOffsetInternal = function(self) return xOffset, yOffset end; - getOffsetInternal = function(self) -- internal + getOffset = function(self) -- internal return xOffset < 0 and math.abs(xOffset) or -xOffset, yOffset < 0 and math.abs(yOffset) or -yOffset end; removeFocusedObject = function(self) - if (basalt.getFocusedObject() ~= nil) then - basalt.getFocusedObject():loseFocusHandler() - end - basalt.setFocusedObject(nil) + focusedOBjectCache = nil return self end; getFocusedObject = function(self) - return basalt.getFocusedObject() + return focusedObject end; setCursor = function(self, _blink, _xCursor, _yCursor, color) @@ -371,6 +369,14 @@ return function(name, parent, pTerm, basalt) return self end, + getMaxScroll = function(self) + return maxScroll + end, + + getMinScroll = function(self) + return minScroll + end, + show = function(self) base.show(self) if(self.parent==nil)then @@ -534,6 +540,10 @@ return function(name, parent, pTerm, basalt) loseFocusHandler = function(self) base.loseFocusHandler(self) + if(focusedOBjectCache~=nil)then + focusedOBjectCache:loseFocusHandler() + focusedOBjectCache = nil + end end; getFocusHandler = function(self) @@ -545,7 +555,6 @@ return function(name, parent, pTerm, basalt) end; keyHandler = function(self, event, key) - local focusedObject = basalt.getFocusedObject() if (focusedObject ~= nil) then if(focusedObject~=self)then if (focusedObject.keyHandler ~= nil) then @@ -617,7 +626,7 @@ return function(name, parent, pTerm, basalt) mouseHandler = function(self, event, button, x, y) if (self.drag) then - local xO, yO = self.parent:getOffset() + 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 @@ -634,15 +643,14 @@ return function(name, parent, pTerm, basalt) return true end - local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) + local fx, fy = self:getAbsolutePosition(self:getAnchorPosition()) local yOff = false - if(objY-1 == y)and(self:getBorder("top"))then + if(fy-1 == y)and(self:getBorder("top"))then y = y+1 yOff = true end if (base.mouseHandler(self, event, button, x, y)) then - local fx, fy = self:getAbsolutePosition(self:getAnchorPosition()) fx = fx + xOffset;fy = fy + yOffset; if(isScrollable)and(importantScroll)then if(event=="mouse_scroll")then @@ -662,8 +670,8 @@ return function(name, parent, pTerm, basalt) end end end + self:removeFocusedObject() if (self.isMoveable) then - local fx, fy = self:getAbsolutePosition(self:getAnchorPosition()) if (x >= fx) and (x <= fx + self:getWidth() - 1) and (y == fy) and (event == "mouse_click") then self.drag = true dragXOffset = fx - x @@ -677,10 +685,6 @@ return function(name, parent, pTerm, basalt) end end end - if (basalt.getFocusedObject() ~= nil) then - basalt.getFocusedObject():loseFocusHandler() - basalt.setFocusedObject(nil) - end return true end return false @@ -768,6 +772,17 @@ return function(name, parent, pTerm, basalt) 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 + end + local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) local anchx, anchy = self:getAnchorPosition() local w,h = self:getSize() @@ -851,7 +866,7 @@ return function(name, parent, pTerm, basalt) end, addFrame = function(self, name) - local obj = basalt.newFrame(name, self, nil, basalt) + local obj = basalt.newFrame(name or uuid(), self, nil, basalt) return addObject(obj) end; } diff --git a/Basalt/Object.lua b/Basalt/Object.lua index 3e6725d..f532d9e 100644 --- a/Basalt/Object.lua +++ b/Basalt/Object.lua @@ -232,11 +232,11 @@ return function(name) end; getX = function(self) - return type(self.x) == "number" and self.x or self.x[1] + return type(self.x) == "number" and self.x or math.floor(self.x[1]+0.5) end; getY = function(self) - return type(self.y) == "number" and self.y or self.y[1] + return type(self.y) == "number" and self.y or math.floor(self.y[1]+0.5) end; getPosition = function(self) @@ -275,11 +275,11 @@ return function(name) end; getHeight = function(self) - return type(self.height) == "number" and self.height or self.height[1] + return type(self.height) == "number" and self.height or math.floor(self.height[1]+0.5) end; getWidth = function(self) - return type(self.width) == "number" and self.width or self.width[1] + return type(self.width) == "number" and self.width or math.floor(self.width[1]+0.5) end; getSize = function(self) @@ -464,7 +464,7 @@ return function(name) y = math.floor(ph/2) + y - 1 end - local xO, yO = self.parent:getOffset() + local xO, yO = self.parent:getOffsetInternal() if not(ignOffset or ignOff) then return x+xO, y+yO end @@ -663,7 +663,7 @@ return function(name) 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:getOffset() + 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()) @@ -680,8 +680,10 @@ return function(name) dragXOffset, dragYOffset = objX - x, objY - y end if(event~="mouse_drag")then - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) + 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 diff --git a/Basalt/libraries/utils.lua b/Basalt/libraries/utils.lua index 06c4657..5791eaa 100644 --- a/Basalt/libraries/utils.lua +++ b/Basalt/libraries/utils.lua @@ -1,3 +1,14 @@ +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 + return { getTextHorizontalAlign = function(text, width, textAlign, replaceChar) text = string.sub(text, 1, width) @@ -37,15 +48,26 @@ rpairs = function(t) end, t, #t + 1 end, -splitString = function(str, sep) - if sep == nil then - sep = "%s" +splitString = splitString, + +createText = function(str, width) + local uniqueLines = splitString(str, "\n") + local lines = {} + for k,v in pairs(uniqueLines)do + local line = "" + local words = splitString(v, " ") + for a,b in pairs(words)do + if(#line+#b <= width)then + line = line=="" and b or line.." "..b + if(a==#words)then table.insert(lines, line) end + else + table.insert(lines, line) + line = b:sub(1,width) + if(a==#words)then table.insert(lines, line) end + end + end end - local t={} - for v in string.gmatch(str, "([^"..sep.."]+)") do - table.insert(t, v) - end - return t + return lines end, getValueFromXML = function(name, tab) diff --git a/Basalt/main.lua b/Basalt/main.lua index e431308..b6cb895 100644 --- a/Basalt/main.lua +++ b/Basalt/main.lua @@ -1,7 +1,9 @@ local basaltEvent = require("basaltEvent")() local Frame = require("Frame") local theme = require("theme") -local uuid = require("utils").uuid +local utils = require("utils") +local uuid = utils.uuid +local createText = utils.createText local baseTerm = term.current() local version = 4 @@ -85,6 +87,41 @@ local bInstance = { end } +local basaltError = function(errMsg) + baseTerm.clear() + 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]0)then local finished = {} @@ -93,7 +130,7 @@ local function handleShedules(event, p1, p2, p3, p4) if (coroutine.status(shedules[n]) == "suspended")then local ok, result = coroutine.resume(shedules[n], event, p1, p2, p3, p4) if not(ok)then - table.insert(finished, n) + basaltError(result) end else table.insert(finished, n) @@ -164,41 +201,6 @@ local function basaltUpdateEvent(event, p1, p2, p3, p4) drawFrames() end -local basaltError = function(errMsg) - baseTerm.clear() - 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] 50) then basalt.debugList:removeItem(1) end diff --git a/Basalt/objects/Animation.lua b/Basalt/objects/Animation.lua index e9ff569..87b56a4 100644 --- a/Basalt/objects/Animation.lua +++ b/Basalt/objects/Animation.lua @@ -45,6 +45,7 @@ return function(name) local animations = {} local animationTime = 0 + local animationActive = false local index = 1 local infinitePlay = false @@ -279,7 +280,7 @@ return function(name) offset = function(self, x, y, duration, timer, obj) _OBJ = obj or _OBJ - predefinedLerp(x,y,duration,timer or 0,_OBJ.getOffsetInternal,_OBJ.setOffset) + predefinedLerp(x,y,duration,timer or 0,_OBJ.getOffset,_OBJ.setOffset) return self end, @@ -384,6 +385,7 @@ return function(name) play = function(self, infinite) self:cancel() + animationActive = true infinitePlay = infinite and true or false index = 1 animationTime = 0 @@ -404,6 +406,7 @@ return function(name) os.cancelTimer(timerObj) infinitePlay = false end + animationActive = false return self end; @@ -412,11 +415,13 @@ return function(name) end, eventHandler = function(self, event, tObj) - if (event == "timer") and (tObj == timerObj) then - if (animations[index] ~= nil) then - onPlay(self) - else - self:animationDoneHandler() + if(animationActive)then + if (event == "timer") and (tObj == timerObj) then + if (animations[index] ~= nil) then + onPlay(self) + else + self:animationDoneHandler() + end end end end; diff --git a/Basalt/objects/Label.lua b/Basalt/objects/Label.lua index b35527a..8ac9765 100644 --- a/Basalt/objects/Label.lua +++ b/Basalt/objects/Label.lua @@ -1,6 +1,7 @@ local Object = require("Object") local utils = require("utils") local xmlValue = utils.getValueFromXML +local createText = utils.createText local tHex = require("tHex") local bigFont = require("bigfont") @@ -95,17 +96,7 @@ return function(name) if(self.fgColor~=false)then self.parent:drawForegroundBox(obx, oby, w, h, self.fgColor) end if(fontsize==0)then if not(autoSize)then - local splittedText = utils.splitString(self:getValue(), " ") - local text = {} - local line = "" - for _,v in pairs(splittedText)do - if(line:len()+v:len()<=w)then - line = line=="" and v or line.." "..v - else - table.insert(text, line) - line = v:sub(1,w) - end - end + local text = createText(self:getValue(), self:getWidth()) for k,v in pairs(text)do self.parent:setText(obx, oby+k-1, v) end diff --git a/Basalt/objects/Radio.lua b/Basalt/objects/Radio.lua index d09412c..0b5f8e6 100644 --- a/Basalt/objects/Radio.lua +++ b/Basalt/objects/Radio.lua @@ -104,12 +104,17 @@ return function(name) return self end; + setActiveSymbol = function(self, sym) + symbol = sym:sub(1,1) + return self + end, + setSelectedItem = function(self, bgCol, fgCol, boxBG, boxFG, active) itemSelectedBG = bgCol or itemSelectedBG itemSelectedFG = fgCol or itemSelectedFG boxSelectedBG = boxBG or boxSelectedBG boxSelectedFG = boxFG or boxSelectedFG - selectionColorActive = active + selectionColorActive = active~=nil and active or true return self end; @@ -123,7 +128,7 @@ return function(name) if (self.parent ~= nil) then self.parent:setFocusedObject(self) end - --eventSystem:sendEvent(event, self, event, button, x, y) + self:getEventSystem():sendEvent(event, self, event, button, x, y) self:setVisualChanged() return true end diff --git a/Basalt/objects/Textfield.lua b/Basalt/objects/Textfield.lua index a65e140..19dbc76 100644 --- a/Basalt/objects/Textfield.lua +++ b/Basalt/objects/Textfield.lua @@ -147,6 +147,14 @@ return function(name) return self end; + clear = function(self) + lines = {""} + bgLines = {""} + fgLines = {""} + hIndex, wIndex, textX, textY = 1, 1, 1, 1 + return self + end, + addLine = function(self, text, index) if(text~=nil)then if(#lines==1)and(lines[1]=="")then