删除测试代码,升级textBox控件,改进listBox控件,整理代码

This commit is contained in:
MrZ626
2021-06-23 04:49:50 +08:00
parent 27ce516dd9
commit 6c2cbe5f20
3 changed files with 121 additions and 141 deletions

View File

@@ -39,6 +39,11 @@ local largerThen=DOGC{20,20,
{'line',2,2,19,10,2,18}, {'line',2,2,19,10,2,18},
} }
local STW,STH--stencil-wid/hei
local function rectangleStencil()
gc.rectangle('fill',1,1,STW-2,STH-2)
end
local WIDGET={} local WIDGET={}
local widgetMetatable={ local widgetMetatable={
__tostring=function(self) __tostring=function(self)
@@ -542,7 +547,7 @@ function slider:release(x)
self:drag(x) self:drag(x)
self.lastTime=0 self.lastTime=0
end end
function slider:arrowKey(isLeft) function slider:move(isLeft)
local p=self.disp() local p=self.disp()
local u=(self.smooth and .01 or 1) local u=(self.smooth and .01 or 1)
local P=isLeft and max(p-u,0)or min(p+u,self.unit) local P=isLeft and max(p-u,0)or min(p+u,self.unit)
@@ -704,7 +709,7 @@ function selector:press(x)
end end
end end
end end
function selector:arrowKey(isLeft) function selector:move(isLeft)
local s=self.select local s=self.select
if isLeft and s==1 or not isLeft and s==#self.list then return end if isLeft and s==1 or not isLeft and s==#self.list then return end
if isLeft then if isLeft then
@@ -881,10 +886,8 @@ end
local textBox={ local textBox={
type='textBox', type='textBox',
dragAble=true, dragAble=true,
scrollPos=0,--Which line display at bottom scrollPos=0,--Scroll-down-distance
scrollPix=0,--Hidden wheel move value
sure=0,--Sure-timer for clear history sure=0,--Sure-timer for clear history
new=false,--If there is a new message
} }
function textBox:reset() function textBox:reset()
--haha nothing here, techmino is so fun! --haha nothing here, techmino is so fun!
@@ -896,7 +899,6 @@ end
function textBox:clear() function textBox:clear()
self.texts={} self.texts={}
self.scrollPos=0 self.scrollPos=0
self.new=false
SFX.play('fall') SFX.play('fall')
end end
function textBox:isAbove(x,y) function textBox:isAbove(x,y)
@@ -918,8 +920,6 @@ function textBox:push(t)
ins(self.texts,t) ins(self.texts,t)
if self.scrollPos==#self.texts-1 then if self.scrollPos==#self.texts-1 then
self.scrollPos=#self.texts self.scrollPos=#self.texts
else
self.new=true
end end
end end
function textBox:press(x,y) function textBox:press(x,y)
@@ -928,7 +928,6 @@ function textBox:press(x,y)
if not self.fix and x>self.x+self.w-40 and y<self.y+40 then if not self.fix and x>self.x+self.w-40 and y<self.y+40 then
if self.sure>0 then if self.sure>0 then
self:clear() self:clear()
self.new=false
self.sure=0 self.sure=0
else else
self.sure=60 self.sure=60
@@ -936,67 +935,56 @@ function textBox:press(x,y)
end end
end end
function textBox:drag(_,_,_,dy) function textBox:drag(_,_,_,dy)
_=self.scrollPix+dy self.scrollPos=max(0,min(self.scrollPos-dy,(#self.texts-self.capacity)*self.lineH))
local sign=_>0 and 1 or -1
while abs(_)>self.lineH do
_=_-self.lineH*sign
self:scroll(-sign)
end
self.scrollPix=_
end end
function textBox:scroll(n) function textBox:scroll(n)
if n<0 then self.scrollPos=max(0,min(self.scrollPos+n*self.lineH,(#self.texts-self.capacity)*self.lineH))
self.scrollPos=max(self.scrollPos+n,min(#self.texts,self.capacity))
else
self.scrollPos=min(self.scrollPos+n,#self.texts)
end
end end
function textBox:draw() function textBox:draw()
local x,y,w,h=self.x,self.y,self.w,self.h local x,y,w,h=self.x,self.y,self.w,self.h
local texts=self.texts local texts=self.texts
local scroll=self.scrollPos local scrollPos=self.scrollPos
local cap=self.capacity local cap=self.capacity
local lineH=self.lineH
--Update new message status, necessary when hide==true
if self.scrollPos==#self.texts then
self.new=false
end
--Background --Background
gc_setColor(0,0,0,.4) gc_setColor(0,0,0,.4)
gc_rectangle('fill',x,y,w,h) gc_rectangle('fill',x,y,w,h)
--Frame --Frame
gc_setLineWidth(4) gc_setLineWidth(3)
gc_setColor(WIDGET.sel==self and COLOR.lN or COLOR.Z) gc_setColor(WIDGET.sel==self and COLOR.lN or COLOR.Z)
gc_rectangle('line',x,y,w,h) gc_rectangle('line',x,y,w,h)
--Slider
if #texts>cap then
gc_setLineWidth(2)
gc_rectangle('line',x-25,y,20,h)
local len=max(h*cap/#texts,26)
gc_rectangle('fill',x-22,y+(h-len-6)*(scroll-cap)/(#texts-cap)+3,14,len)
end
--Clear button
gc_setColor(1,1,1)
if not self.fix then
gc_rectangle('line',x+w-40,y,40,40)
gc_draw(self.sure==0 and clearIcon or sureIcon,x+w-40,y)
end
--Texts --Texts
setFont(self.font) setFont(self.font)
for i=max(scroll-cap+1,1),scroll do gc_push('transform')
gc_printf(texts[i],x+8,y+h-10-self.lineH*(scroll-i+1),w) gc_translate(x,y)
end
--New message --Slider
if self.new and self.scrollPos~=#texts then gc_setColor(1,1,1)
gc_setColor(1,TIME()%.4<.2 and 1 or 0,0) if #texts>cap then
gc_print("v",x+w-25,y+h-40) local len=h*h/(#texts*lineH)
end gc_rectangle('fill',-15,(h-len)*scrollPos/((#texts-cap)*lineH),12,len)
end
--Clear button
if not self.fix then
gc_rectangle('line',w-40,0,40,40)
gc_draw(self.sure==0 and clearIcon or sureIcon,w-40,0)
end
gc_setStencilTest('equal',1)
STW,STH=w,h
gc_stencil(rectangleStencil)
gc_translate(0,-(scrollPos%lineH))
local pos=int(scrollPos/lineH)
for i=pos+1,min(pos+cap+1,#texts)do
gc_printf(texts[i],10,4,w-16)
gc_translate(0,lineH)
end
gc_setStencilTest()
gc_pop()
end end
function textBox:getInfo() function textBox:getInfo()
return("x=%d,y=%d,w=%d,h=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h) return("x=%d,y=%d,w=%d,h=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h)
@@ -1039,7 +1027,7 @@ end
local listBox={ local listBox={
type='listBox', type='listBox',
dragAble=true, dragAble=true,
scrollPos=0,--Which line display at bottom scrollPos=0,--Scroll-down-distance
selected=0,--Hidden wheel move value selected=0,--Hidden wheel move value
} }
function listBox:reset() function listBox:reset()
@@ -1071,7 +1059,7 @@ function listBox:isAbove(x,y)
y<self.y+self.h y<self.y+self.h
end end
function listBox:getCenter() function listBox:getCenter()
return self.x+self.w*.5,self.y+self.w return self.x+self.w*.5,self.y+self.h*.5
end end
function listBox:push(t) function listBox:push(t)
ins(self.list,t) ins(self.list,t)
@@ -1080,7 +1068,7 @@ function listBox:press(x,y)
if not(x and y)then return end if not(x and y)then return end
self:drag(nil,nil,nil,0) self:drag(nil,nil,nil,0)
x,y=x-self.x,y-self.y x,y=x-self.x,y-self.y
y=int(y/40+self.scrollPos)+1 y=int((y+self.scrollPos)/self.lineH)+1
if self.list[y]then if self.list[y]then
if self.selected~=y then if self.selected~=y then
self.selected=y self.selected=y
@@ -1090,15 +1078,9 @@ function listBox:press(x,y)
end end
function listBox:drag(_,_,_,dy) function listBox:drag(_,_,_,dy)
self.scrollPos=max(0,min(self.scrollPos-dy,(#self.list-self.capacity)*self.lineH)) self.scrollPos=max(0,min(self.scrollPos-dy,(#self.list-self.capacity)*self.lineH))
print(self.scrollPos)
end end
function listBox:scroll(n) function listBox:scroll(n)
self.scrollPos=max(0,min(self.scrollPos-n*self.lineH,(#self.list-self.capacity)*self.lineH)) self.scrollPos=max(0,min(self.scrollPos+n*self.lineH,(#self.list-self.capacity)*self.lineH))
print(self.scrollPos)
end
local SSW,SSH--stencil-size-w/h
local function listBoxStencil()
gc.rectangle('fill',1,1,SSW-2,SSH-2)
end end
function listBox:draw() function listBox:draw()
local x,y,w,h=self.x,self.y,self.w,self.h local x,y,w,h=self.x,self.y,self.w,self.h
@@ -1109,20 +1091,23 @@ function listBox:draw()
gc_push('transform') gc_push('transform')
gc_translate(x,y) gc_translate(x,y)
--Frame
gc_setColor(WIDGET.sel==self and COLOR.lN or COLOR.Z) gc_setColor(WIDGET.sel==self and COLOR.lN or COLOR.Z)
gc_setLineWidth(3) gc_setLineWidth(3)
gc_rectangle('line',0,0,w,h) gc_rectangle('line',0,0,w,h)
--Slider
if #list>cap then if #list>cap then
gc_setColor(1,1,1) gc_setColor(1,1,1)
local len=h*h/(#list*lineH) local len=h*h/(#list*lineH)
gc_rectangle('fill',-15,(h-len)*scrollPos/((#list-cap)*lineH),12,len) gc_rectangle('fill',-15,(h-len)*scrollPos/((#list-cap)*lineH),12,len)
end end
--List
gc_setStencilTest('equal',1) gc_setStencilTest('equal',1)
SSW,SSH=w,h STW,STH=w,h
gc_stencil(listBoxStencil) gc_stencil(rectangleStencil)
setFont(35)
local pos=int(scrollPos/lineH) local pos=int(scrollPos/lineH)
gc_translate(0,-(scrollPos%lineH)) gc_translate(0,-(scrollPos%lineH))
for i=pos+1,min(pos+cap+1,#list)do for i=pos+1,min(pos+cap+1,#list)do
@@ -1282,18 +1267,22 @@ function WIDGET.drag(x,y,dx,dy)
end end
function WIDGET.release(x,y) function WIDGET.release(x,y)
local W=WIDGET.sel local W=WIDGET.sel
if W and W.type=='slider'then if W and W.release then
W:release(x,y+WIDGET.scrollPos) W:release(x,y+WIDGET.scrollPos)
end end
end end
function WIDGET.keyPressed(k,isRep) function WIDGET.keyPressed(k,isRep)
local W=WIDGET.sel local W=WIDGET.sel
if not isRep and(k=="space"or k=="return")then if k=="space"or k=="return"then
WIDGET.press() if not isRep then
elseif kb.isDown("lshift","lalt","lctrl")and(k=="left"or k=="right")then WIDGET.press()
--When hold [↑], control slider with left/right end
if W and W.type=='slider'or W.type=='selector'then elseif kb.isDown("lshift","lalt","lctrl")then
W:arrowKey(k=="left") if k=="left"or k=="right"then
--When hold shift/ctrl/alt, control slider with left/right
if W and W.arrowKey then W:move(k=="left")end
elseif k=="up"or k=="down"then
if W and W.scroll then W:scroll((k=="up"and -1 or 1)*W.lineH)end
end end
elseif k=="up"or k=="down"or k=="left"or k=="right"then elseif k=="up"or k=="down"or k=="left"or k=="right"then
if not W then if not W then
@@ -1303,37 +1292,36 @@ function WIDGET.keyPressed(k,isRep)
return return
end end
end end
return elseif W.getCenter then
end local WX,WY=W:getCenter()
if not W.getCenter then return end local dir=(k=="right"or k=="down")and 1 or -1
local WX,WY=W:getCenter() local tar
local dir=(k=="right"or k=="down")and 1 or -1 local minDist=1e99
local tar local swap_xy=k=="up"or k=="down"
local minDist=1e99 if swap_xy then WX,WY=WY,WX end -- note that we do not swap them back later
local swap_xy=k=="up"or k=="down" for _,W1 in ipairs(WIDGET.active)do
if swap_xy then WX,WY=WY,WX end -- note that we do not swap them back later if W~=W1 and W1.resCtr and not W1.hide then
for _,W1 in ipairs(WIDGET.active)do local L=W1.resCtr
if W~=W1 and W1.resCtr and not W1.hide then for j=1,#L,2 do
local L=W1.resCtr local x,y=L[j],L[j+1]
for j=1,#L,2 do if swap_xy then x,y=y,x end -- note that we do not swap them back later
local x,y=L[j],L[j+1] local dist=(x-WX)*dir
if swap_xy then x,y=y,x end -- note that we do not swap them back later if dist>10 then
local dist=(x-WX)*dir dist=dist+abs(y-WY)*6.26
if dist>10 then if dist<minDist then
dist=dist+abs(y-WY)*6.26 minDist=dist
if dist<minDist then tar=W1
minDist=dist end
tar=W1
end end
end end
end end
end end
end if tar then
if tar then WIDGET.focus(tar)
WIDGET.focus(tar) end
end end
else else
if W and W.type=='inputBox'then if W and W.keypress then
W:keypress(k) W:keypress(k)
end end
end end

View File

@@ -508,21 +508,6 @@ function NET.updateWS_play()
SFX.play('connected') SFX.play('connected')
elseif res.action==0 then--Fetch rooms elseif res.action==0 then--Fetch rooms
if SCN.cur=="net_rooms"then if SCN.cur=="net_rooms"then
for i=1,16 do
res.roomList[i]={
rid="qwe",
roomInfo={
name="Test room "..i,
type="classic",
version=VERSION.short,
description="x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x ",
},
private=i%3==0,
start=i%4==0,
count=i%5,
capacity=5,
}
end
WIDGET.active.roomList:setList(res.roomList) WIDGET.active.roomList:setList(res.roomList)
end end
NET.unlock('fetchRoom') NET.unlock('fetchRoom')
@@ -571,7 +556,7 @@ function NET.updateWS_play()
mode=d.mode, mode=d.mode,
config=d.config, config=d.config,
} }
if SCN.socketRead then SCN.socketRead('join',d)end if SCN.cur=='net_game'then SCN.socketRead('join',d)end
NET.allReady=false NET.allReady=false
end end
elseif res.action==3 then--Player leave elseif res.action==3 then--Player leave
@@ -584,10 +569,10 @@ function NET.updateWS_play()
netPLY.remove(d.sid) netPLY.remove(d.sid)
removePlayer(PLAYERS,d.sid) removePlayer(PLAYERS,d.sid)
removePlayer(PLY_ALIVE,d.sid) removePlayer(PLY_ALIVE,d.sid)
if SCN.socketRead then SCN.socketRead('leave',d)end if SCN.cur=='net_game'then SCN.socketRead('leave',d)end
end end
elseif res.action==4 then--Player talk elseif res.action==4 then--Player talk
if SCN.socketRead then SCN.socketRead('talk',d)end if SCN.cur=='net_game'then SCN.socketRead('talk',d)end
elseif res.action==5 then--Player change settings elseif res.action==5 then--Player change settings
netPLY.setConf(d.uid,d.config) netPLY.setConf(d.uid,d.config)
elseif res.action==6 then--Player change join mode elseif res.action==6 then--Player change join mode
@@ -600,7 +585,7 @@ function NET.updateWS_play()
NET.connectingStream=true NET.connectingStream=true
NET.wsconn_stream(d.srid) NET.wsconn_stream(d.srid)
elseif res.action==9 then--Game finished elseif res.action==9 then--Game finished
if SCN.socketRead then SCN.socketRead('finish',d)end if SCN.cur=='net_game'then SCN.socketRead('finish',d)end
--d.result: list of {place,survivalTime,uid,score} --d.result: list of {place,survivalTime,uid,score}
for _,p in next,d.result do for _,p in next,d.result do

View File

@@ -1,26 +1,33 @@
local gc=love.graphics local gc=love.graphics
local gc_translate=gc.translate
local gc_setColor,gc_setLineWidth=gc.setColor,gc.setLineWidth
local gc_draw=gc.draw
local gc_rectangle,gc_arc=gc.rectangle,gc.arc
local gc_print,gc_printf=gc.print,gc.printf
local NET=NET local NET=NET
local fetchTimer local fetchTimer
local roomList=WIDGET.newListBox{name="roomList",x=50,y=50,w=800,h=440,lineH=40,drawF=function(ifSel,id,item) local roomList=WIDGET.newListBox{name="roomList",x=50,y=50,w=800,h=440,lineH=40,drawF=function(ifSel,id,item)
setFont(35)
if ifSel then if ifSel then
gc.setColor(1,1,1,.3) gc_setColor(1,1,1,.3)
gc.rectangle('fill',0,0,800,40) gc_rectangle('fill',0,0,800,40)
end end
gc.setColor(1,1,1) gc_setColor(1,1,1)
if item.private then gc.draw(IMG.lock,10,5)end if item.private then gc_draw(IMG.lock,10,5)end
gc.print(item.count.."/"..item.capacity,670,-4) gc_print(item.count.."/"..item.capacity,670,-4)
gc.setColor(.9,.9,1) gc_setColor(.9,.9,1)
gc.print(id,45,-4) gc_print(id,45,-4)
if item.start then if item.start then
gc.setColor(0,.4,.1) gc_setColor(0,.4,.1)
else else
gc.setColor(1,1,.7) gc_setColor(1,1,.7)
end end
gc.print(item.roomInfo.name,200,-4) gc_print(item.roomInfo.name,200,-4)
end} end}
local function hidePW() local function hidePW()
local R=roomList:getSel() local R=roomList:getSel()
@@ -86,30 +93,30 @@ end
function scene.draw() function scene.draw()
--Fetching timer --Fetching timer
gc.setColor(1,1,1,.12) gc_setColor(1,1,1,.12)
gc.arc('fill','pie',250,630,40,-1.5708,-1.5708-.6283*fetchTimer) gc_arc('fill','pie',250,630,40,-1.5708,-1.5708-.6283*fetchTimer)
--Room list --Room list
local R=roomList:getSel() local R=roomList:getSel()
if R then if R then
gc.translate(870,220) gc_translate(870,220)
gc.setColor(1,1,1) gc_setColor(1,1,1)
gc.setLineWidth(3) gc_setLineWidth(3)
gc.rectangle('line',0,0,385,335) gc_rectangle('line',0,0,385,335)
setFont(25) setFont(25)
gc.print(R.roomInfo.type,10,25) gc_print(R.roomInfo.type,10,25)
gc.setColor(1,1,.7) gc_setColor(1,1,.7)
gc.printf(R.roomInfo.name,10,0,365) gc_printf(R.roomInfo.name,10,0,365)
setFont(20) setFont(20)
gc.setColor(.8,.8,.8) gc_setColor(.8,.8,.8)
gc.printf(R.roomInfo.description or"[No description]",10,55,365) gc_printf(R.roomInfo.description or"[No description]",10,55,365)
if R.start then if R.start then
gc.setColor(0,1,.2) gc_setColor(0,1,.2)
gc.print(text.started,10,300) gc_print(text.started,10,300)
end end
gc.setColor(1,.2,0) gc_setColor(1,.2,0)
gc.printf(R.roomInfo.version,10,300,365,'right') gc_printf(R.roomInfo.version,10,300,365,'right')
gc.translate(-870,-220) gc_translate(-870,-220)
end end
--Profile --Profile