我正在编写一个脚本来制作可以在我的 TI Nspire CX CAS 2 计算器上打开和关闭的小窗口。添加新窗口效果很好,但尝试删除它们会导致我的软件在应该删除窗口的功能完成时崩溃。我也在我的计算器上试过它,它仍然卡住,但我能够关闭脚本然后重新打开它。当我重新打开它时,第 465 行出现“中断”错误,我的计算器的图片出现错误
screen = platform.window
screenx,screeny = screen.width(),screen.height()
-- system stuff
local password = nil
local passVerify = nil
local drawObjects = {}
local processes = {}
local rectangle = class()
local backgroundObj = class()
local taskbar = class()
local window = class()
local process = class()
local taskbarHeight = 20
local hasBeenSetup = false
local customSetupProcedures = {}
local isLogedIn = false
local draggingMode = {
move = 0,
left = 1,
top = 2,
right = 3,
bottom = 4
}
local readyToDraw = true
local currentDraggingMode = draggingMode.both
local selectedWindowForDragging = nil
local textures = {}
local processStatus = {
waiting = 0,
running = 1,
halted = 2,
dead = 3
}
local specialColors = {
taskbarColor = 0x00969E,
windowBackgroundColor = 0xF7F7F7,
windowTopBarColor = 0xA2A2A2,
windowCloseButtonColor = 0xFF5100,
windowMaximizeButtonColor = 0x00FF00,
windowMinimizeButtonColor = 0xFFFF00
}
function process:init(run,onKill)
self.status = processStatus.waiting
self.co = coroutine.create(run)
self.onKill = onKill
coroutine.resume(self.co,self)
end
function process:update()
if self.status == processStatus.running then
coroutine.resume(self.co)
end
end
function process:halt()
self.status = processStatus.halted
end
function process:resume()
self.status = processStatus.waiting
end
function process:kill()
readyToDraw = false
self.status = processStatus.dead
self.co = nil
self.onKill()
readyToDraw = true
end
function rectangle:init(x,y,width,height)
self.x = x
self.y = y
self.width = width
self.height = height
end
function rectangle:contains(x,y)
return self.x<x and x<self.x+self.width and self.y<y and y<self.y+self.height
end
function taskbar:init()
end
function taskbar:draw(gc)
gc:setColorRGB(specialColors.taskbarColor)
gc:fillRect(0,screeny-taskbarHeight,screenx,screeny)
--gc:drawImage(textures[1],0,screeny-20)
end
function taskbar:isWindow()
return false
end
function window:init(x,y,width,height)
self.x = x
self.y = y
self.draggedOnX = 0
self.draggedOnY = 0
self.width = width
self.height = height
self.icon = nil
self.components = {}
self.focusLevel = 0
newWindowFocused(#drawObjects+1)
self.resizable = true
self:subclassInit(x,y,width,height)
end
function window:subclassInit(x,y,width,height)
end
function window:getFocusLevel()
return self.focusLevel
end
function window:draw(gc)
gc:setColorRGB(specialColors.windowBackgroundColor)
gc:fillRect(self.x,self.y,self.width,self.height)
gc:setColorRGB(specialColors.windowTopBarColor)
gc:fillRect(self.x,self.y,self.width,10)
gc:setColorRGB(specialColors.windowMinimizeButtonColor)
gc:fillRect(self.x+self.width-29,self.y+1,8,8)
gc:setColorRGB(specialColors.windowMaximizeButtonColor)
gc:fillRect(self.x+self.width-19,self.y+1,8,8)
gc:setColorRGB(specialColors.windowCloseButtonColor)
gc:fillRect(self.x+self.width-9,self.y+1,8,8)
self:drawComponents(gc)
end
function window:drawComponents(gc)
for i in ipairs(self.components) do
self.components[i]:draw(gc,self)
end
end
function window:addComponent(component)
i = #self.components+1
self.components[i] = component
return i
end
function window:decreaseFocus()
self.focusLevel = self.focusLevel+1
end
function window:isWindow()
return true
end
function window:contains(x,y)
return self.x<x and self.y < y and self.width+self.x>x and self.height+self.y>y
end
function window:checkForMouse(x,y)
if y-self.y <= 3 and self.resizable then
cursor.set('resize row')
elseif y-self.y>=self.height-3 and self.resizable then
cursor.set('resize row')
elseif x-self.x<=3 and self.resizable then
cursor.set('resize column')
elseif x-self.x>=self.width-3 and self.resizable then
cursor.set('resize column')
end
end
function window:click(x,y,n)
self:focus(n)
if y-self.y <= 3 and self.resizable then
selectedWindowForDragging = self
currentDraggingMode = draggingMode.top
elseif y-self.y>=self.height-3 and self.resizable then
selectedWindowForDragging = self
currentDraggingMode = draggingMode.bottom
elseif x-self.x<=3 and self.resizable then
selectedWindowForDragging = self
currentDraggingMode = draggingMode.left
elseif x-self.x>=self.width-3 and self.resizable then
selectedWindowForDragging = self
currentDraggingMode = draggingMode.right
elseif y-self.y <= 10 then
if x>=self.x+self.width-10 then
self:close()
elseif x>=self.x+self.width-20 then
self:maximize()
elseif x>=self.x+self.width-30 then
self:minimize()
else
selectedWindowForDragging = self
currentDraggingMode = draggingMode.move
self.draggedOnX = x - self.x
self.draggedOnY = y - self.y
end
end
self:clickComponents(x,y)
end
function window:clickComponents(x,y)
end
function newWindowFocused(n)
for window in ipairs(drawObjects) do
window = drawObjects[window]
if window:isWindow() then
if window:getFocusLevel() < n then
window:decreaseFocus()
end
end
end
end
function window:focus(n)
self.focusLevel = -1
newWindowFocused(n)
end
function window:minimize()
end
function window:maximize()
end
function window:close()
processes[1]:kill()
end
function on.resize()
screenx = screen:width()
screeny = screen:height()
end
function on.mouseDown(x,y)
minFocus = 0
for i = 0,#drawObjects,1 do
for windown in ipairs(drawObjects) do
window=drawObjects[windown]
if window:isWindow() then
if window:getFocusLevel() == minFocus then
if window:contains(x,y) then
window:click(x,y,minFocus)
return
end
minFocus = minFocus+1
end
end
end
end
end
function on.mouseMove(x,y)
cursor.set('default')
if selectedWindowForDragging ~= nil then
if currentDraggingMode == draggingMode.move then
selectedWindowForDragging.x = x - selectedWindowForDragging.draggedOnX
selectedWindowForDragging.y = y - selectedWindowForDragging.draggedOnY
if selectedWindowForDragging.x+selectedWindowForDragging.draggedOnX<5 then selectedWindowForDragging.x = 5-selectedWindowForDragging.draggedOnX end
if selectedWindowForDragging.x+selectedWindowForDragging.draggedOnX>screenx-5 then selectedWindowForDragging.x = screenx-selectedWindowForDragging.draggedOnX-5 end
if selectedWindowForDragging.y<0 then selectedWindowForDragging.y=0 end
if selectedWindowForDragging.y>screeny-taskbarHeight-5 then selectedWindowForDragging.y = screeny-taskbarHeight-5 end
elseif currentDraggingMode == draggingMode.top then
i = selectedWindowForDragging.draggedOnY + y
selectedWindowForDragging.height = math.max(selectedWindowForDragging.height - selectedWindowForDragging.draggedOnY - y + selectedWindowForDragging.y,20)
selectedWindowForDragging.y = i
elseif currentDraggingMode == draggingMode.bottom then
selectedWindowForDragging.height = math.max(y - selectedWindowForDragging.y,20)
elseif currentDraggingMode == draggingMode.left then
i = selectedWindowForDragging.draggedOnX + x
selectedWindowForDragging.width = math.max(selectedWindowForDragging.width - selectedWindowForDragging.draggedOnX - x + selectedWindowForDragging.x,20)
selectedWindowForDragging.x = i
elseif currentDraggingMode == draggingMode.right then
selectedWindowForDragging.width = math.max(x - selectedWindowForDragging.x,20)
end
end
minFocus = 0
for i = 0,#drawObjects,1 do
for windown in ipairs(drawObjects) do
window=drawObjects[windown]
if window:isWindow() then
if window:getFocusLevel() == minFocus then
if window:contains(x,y) then
window:checkForMouse(x,y)
return
end
minFocus = minFocus+1
end
end
end
end
end
function on.mouseUp(x,y)
selectedWindowForDragging = nil
end
local calculator = class(window)
function calculator:subclassInit()
self.width = 60
self.height = 90
self.resizable = false
self.number = ''
print(self.number)
self.button1 = rectangle(5,22,13,10)
self.button2 = rectangle(24,22,14,10)
self.button3 = rectangle(44,22,13,10)
self.button4 = rectangle(5,34,13,10)
self.button5 = rectangle(24,34,14,10)
self.button6 = rectangle(44,34,13,10)
self.button7 = rectangle(5,45,13,10)
self.button8 = rectangle(24,45,14,10)
self.button9 = rectangle(44,45,13,10)
self.button0 = rectangle(24,57,14,10)
self.buttonC = rectangle(5,57,13,10)
self.buttonDot = rectangle(44,57,13,10)
self.buttonPlus = rectangle(6,70,7,7)
self.buttonMinus = rectangle(15,70,7,7)
self.buttonMultiply = rectangle(40,70,7,7)
self.buttonDivide = rectangle(49,70,7,7)
self.buttonEquals = rectangle(24,69,14,8)
end
function calculator:drawComponents(gc)
--gc:drawImage(textures[2],self.x,self.y+10)
gc:setColorRGB(0x000000)
gc:setFont('sansserif','r',6)
if #self.number < 10 then
gc:drawString(string.sub(self.number,0,#self.number),self.x+5,self.y+13)
else
gc:drawString(string.sub(self.number,#self.number-9,#self.number),self.x+5,self.y+13)
print(self.number)
end
end
function calculator:clickComponents(x,y)
x = x-self.x
y = y-self.y-10
if self.button1:contains(x,y) then self.number = self.number..'1' elseif
self.button2:contains(x,y) then self.number = self.number..'2' elseif
self.button3:contains(x,y) then self.number = self.number..'3' elseif
self.button4:contains(x,y) then self.number = self.number..'4' elseif
self.button5:contains(x,y) then self.number = self.number..'5' elseif
self.button6:contains(x,y) then self.number = self.number..'6' elseif
self.button7:contains(x,y) then self.number = self.number..'7' elseif
self.button8:contains(x,y) then self.number = self.number..'8' elseif
self.button9:contains(x,y) then self.number = self.number..'9' elseif
self.button0:contains(x,y) then self.number = self.number..'0' elseif
self.buttonPlus:contains(x,y) then self.number = self.number..'+' elseif
self.buttonMinus:contains(x,y) then self.number = self.number..'-' elseif
self.buttonMultiply:contains(x,y) then self.number = self.number..'*' elseif
self.buttonDivide:contains(x,y) then self.number = self.number..'/' elseif
self.buttonDot:contains(x,y) then self.number = self.number..'.' elseif
self.buttonEquals:contains(x,y) then
if not pcall(function()self.number = ''..math.eval(self.number)end) then self.number = 'error' end
elseif
self.buttonC:contains(x,y) then self.number = '' end
end
function backgroundObj:draw(gc)
gc:setColorRGB(0xC4C4C4)
gc:fillRect(0,0,screenx,screeny-taskbarHeight)
--gc:drawImage(textures[0],screenx/2-50,(screeny-taskbarHeight)/2-50)
end
function backgroundObj:isWindow()
return false
end
function loadTextures()
--textures[0]=image.new(_R.IMG.logo)
--textures[1]=image.new(_R.IMG.startMenuButton)
--textures[2]=image.new(_R.IMG.calculator)
end
function on.construction()
timer.start(1/30)
checkForSetup()
checkForLogin()
end
function on.timer()
screen:invalidate()
end
function encrypt(str,key)
result = ''
for i = 1,#str,1 do
result = result..string.char(math.abs(string.byte(str:sub(i,i))+key+i)%422)
end
return result
end
function decrypt(str,key)
result = ''
for i = 1,#str,1 do
result = result..string.char(math.abs((string.byte(str:sub(i,i))-key-i)%422))
end
return result
end
function checkForLogin()
end
function checkForSetup()
if not hasBeenSetup then
print('loading textures...')
loadTextures()
print('setting up graphics...')
setupGraphics()
print('executing default setup procedure...')
print('setting up password...')
setupPassword()
print('executing custom setup procedures...')
for funct in ipairs(customSetupProcedures) do
funct()
end
end
hasBeenSetup = true
end
function setupGraphics()
processes[1] = process(
function(proc)
drawObjects[1] = backgroundObj()
end,
function()
drawObjects[1] = nil
end)
drawObjects[2] = taskbar()
end
function setupPassword()
w1 = calculator(50,100,100,100)
drawObjects[3] = w1
w2 = window(0,50,100,100)
drawObjects[4] = w2
end
--system stuff
--graphics stuff
function on.paint(gc)
if readyToDraw then
if drawObjects[1]~=nil then
drawObjects[1]:draw(gc)
end
focus = 0
for i in ipairs(drawObjects) do
window = drawObjects[i]
if window:isWindow() then
focus = math.max(focus,window:getFocusLevel())
end
end
while focus>=0 do
for i in ipairs(drawObjects) do
window = drawObjects[i]
if window:isWindow() and window:getFocusLevel()==focus then
window:draw(gc)
focus = focus-1
break
end
end
end
drawObjects[2]:draw(gc)
end
end
--graphics stuff
--default programs
--default programs
编辑:我刚刚发现,如果您在学生软件中运行脚本并且它陷入循环,按 F12 会中断循环(就像实际计算器上的主页按钮一样)。