Improve Zictionary scene so we don't need to hyper tapping much than before (#926)

* Attempt to rework Zictionary scene

* Rearrange the layout and handling most of thing

* Remove ALPHA key, done keyboard handling, changed some key's behavior

* Add Help text

* Update Help text & fix some bugs

* Update help text

* Edit help text

* Support gamepad

* small changes in help text

* small changes

* Fix copy bug

* small change

* Add hint text to open Hint

* Fix a bug that item accidentally selected when scrolling

* Clean up a dumb function
(Forget to cleanup in previous commit)

* add backup solution, just in case

* fix another bug

* fix touch bug

* Refix the scroll bug when touch

* small code changes

* small change in English file
This commit is contained in:
C6H12O6 + NaCl + H2O
2023-07-31 02:20:24 +07:00
committed by GitHub
parent 4d82b182a6
commit 9d3fb33d10
3 changed files with 346 additions and 91 deletions

View File

@@ -16,7 +16,7 @@ return {
{"Practice Recommendations",
"readme noob new guides recommendations suggestions helps",
"help",
"Here are our recommendations for improving your Tetris skills. If you have ever felt difficulties in your training, you can just relax and spend some time playing the modes you do enjoy. Have fun!\n\nThese are sets of missions that you need to accomplish. When there is order within each set, we recommend you to do all three sets of tasks simultaneously instead of one by one.\n\nA. Stacking\n\tA1. Think twice before you place your block. If your first decision doesnt seem to fit well, think again.\n\tA2. Keep your terrain flat since it allows more possibilities for different blocks.\n\tA3. When hold allowed, thinking more about sequences to arrange the pieces in your hand, the held one, plus the previews. In order to have flat terrain for longer time.\nB. Efficiency & Speed\n\tB1. Dont count on ghost pieces. Think, with your brain, where this piece would land and what keys you should press. Do it only when you are ready.\n\tB2. Use both of the rotation keys. Dont just use one and press it many times when you can press the other one just once.\n\tB3. Dont worry too much about your speed when you start learning Finesse. Keep your move accurate, and then it is not hard to improve your speed once you have mastered it.\nC. Stacking\n\tC1. Finish 40L without topping out.\n\tC2. Finish 40L with no Hold without topping out.\n\tC3. Finish 40L with all Techrashes.\n\tC4. Finish 40L with all Techrashes and no Hold.\n\nSet C is more flexible, and you can adjust the difficulties based on your own conditions (like what does ” means to you).\n\nWhen you finish all the tasks in set C, keep practicing A1. This is the fundamental skill in any Tetris game, and you can master practically any mode when you can just scan through the Next sequence easily.",
"Here are our recommendations for improving your Tetris skills. If you have ever felt difficulties in your training, you can just relax and spend some time playing the modes you do enjoy. Have fun!\n\nThese are sets of missions that you need to accomplish. When there is order within each set, we recommend you to do all three sets of tasks simultaneously instead of one by one.\n\nA. Stacking\n\tA1. Think twice before you place your block. If your first decision doesnt seem to fit well, think again.\n\tA2. Keep your terrain flat since it allows more possibilities for different blocks.\n\tA3. When hold allowed, thinking more about sequences to arrange the pieces in your hand, the held one, plus the previews. In order to have flat terrain for longer time.\nB. Efficiency & Speed\n\tB1. Dont count on ghost pieces. Think, with your brain, where this piece would land and what keys you should press. Do it only when you are ready.\n\tB2. Use both of the rotation keys. Dont just use one and press it many times when you can press the other one just once.\n\tB3. Dont worry too much about your speed when you start learning Finesse. Keep your move accurate, and then it is not hard to improve your speed once you have mastered it.\nC. Stacking\n\tC1. Finish 40L without topping out.\n\tC2. Finish 40L with no Hold without topping out.\n\tC3. Finish 40L with all Techrashes.\n\tC4. Finish 40L with all Techrashes and no Hold.\n\nSet C is more flexible, and you can adjust the difficulties based on your own conditions (like what does “stably” means to you).\n\nWhen you finish all the tasks in set C, keep practicing A1. This is the fundamental skill in any Tetris game, and you can master practically any mode when you can just scan through the Next sequence easily.",
},
{"Learning T-spins",
"tspins learning study guides tips recommendations suggestions helps",

View File

@@ -378,6 +378,64 @@ return {
sha2 [Egor Skriptunoff]
]],
support="Support the author",
dict={
sizeChanged="Changed font size: $1",
sizeReset="Reset font size: 25",
helpText=
[[
ZICTIONARY NAVIGATION INSTRUCTION
NOTE: Some functions may not have specific gestures for gamepad input.
In such cases, you can use alternative input methods or follow the provided instructions.
Scrolling text:
Keyboard: Use [$1] to scroll up, [$2] to scroll down.
Gamepad: Use $5 to scroll up, $6 to scroll down.
Mouse/Touch screen: Use the familiar scrolling gestures.
Exiting Zictionary:
Keyboard: Press [Esc] key.
Gamepad: Press [BACK] button.
Mouse/Touch screen: Press the Back button in the top right corner of the screen.
Opening/closing Help:
Keyboard: Press [F1] key.
Gamepad: Press $10 key.
Mouse/Touch screen: Tap [$13] key.
Opening previous/next item in the list:
Keyboard: Press [$3] to open the previous item, [$4] to open the next one.
Gamepad: Press $7 to open the previous item, $8 to open the next one.
Mouse/Touch screen: Click/touch the item below the currently selected one in the list.
Jumping backward/forward through 12 items:
Keyboard: Hold [Ctrl]/[Shift]/[Alt] key first, then press [$3] to jump backward, [$4] to jump forward.
Gamepad: Hold $11 key first, then press $7 to jump backward, and $8 to jump forward.
Mouse/Touch screen: Click/Touch [$16] to jump backward, [$17] to jump forward
Changing font size (DEFAULT: 25):
Keyboard: Hold Ctrl key first, then press [-] to make the text smaller, [+] to make it bigger, [0] to reset the font size to default.
Gamepad: Hold $11 key first, then press $6 to make the text smaller, and $5 to make it bigger.
Mouse/Touch screen:
Press [aA] to show [a] and [A] buttons.
Click/touch [a] to make the text smaller.
Click/touch [A] to make the text bigger.
To reset the font size, wait for 3 seconds for [aA] [100%] to reappear, then click/touch [100%] to reset.
Note: There's no gesture to reset the font size with the Gamepad, but you can set it back to 25.
Copying the content:
Keyboard: Press [Ctrl] + [C].
Mouse/Touch screen: Press [$14] key.
Opening item's URL (if available):
Keyboard: Press [$18] (Context menu/Application key).
Mouse/Touch screen: Press [$15] key.
]]
-- 1-4: Up, Down, Left, Right
-- 5-8: Up, Down, Left, Right but D-Pad
-- 9-12: X, Y, A, B
-- 13-18: Help, Copy, Open, Forward, Backward, MENU
},
WidgetText={
main={
offline="Single Player",

View File

@@ -1,6 +1,5 @@
local gc=love.graphics
local inputBox=WIDGET.newInputBox{name='input',x=20,y=110,w=762,h=60,font=40,limit=32}
local int,abs=math.floor,math.abs
local min,sin=math.min,math.sin
local ins=table.insert
@@ -13,10 +12,17 @@ local result-- Result Lable
local lastTickInput
local searchWait-- Searching animation timer
local selected-- Selected option
local scrollPos-- Scroll down length
local lastSearch-- Last searched string
local lastSelected -- Last selected item
local justSearched -- Just searched or not?
local currentFontSize=25 -- Current font size, default: 25
local showingHelp=false -- Help is triggered or not
local zoomWait=0 -- The last time zoom is triggered
local oldScrollPos=0
local lastMouseX,lastMouseY,lastTouchX,lastTouchY
local typeColor={
help=COLOR.Y,
@@ -29,9 +35,11 @@ local typeColor={
english=COLOR.B,
name=COLOR.lV,
}
-- Scan the dictionary and return the list
local function _filter(word_org)
local word=word_org
word=word:gsub("[Tt]etris",CHAR.zChan.thinking)
word=word:gsub("[Tt][Ee][Tt][Rr][Ii][Ss]",CHAR.zChan.thinking)
if FNNS then word=word:gsub("[Pp]\97\116\114\101\111\110",CHAR.zChan.qualified) end
return word,word_org
end
@@ -49,23 +57,44 @@ local function _scanDict(D)
end
end
local function _getList() return result[1] and result or dict end
-- Drawing objects
local infoBox =WIDGET.newTextBox {name='infoBox',x=320,y=180,w=862,h=526,font=25,fix=true}
local inputBox=WIDGET.newInputBox{name='input', x=20, y=110,w=762,h=60, font=40,limit=32}
local listBox =WIDGET.newListBox {name='listBox',x=20, y=180,w=280,h=526,font=30,lineH=35,drawF=function(item,id,ifSel)
-- Draw list box
-- Background
if ifSel then
gc.setColor(1,1,1,.4)
gc.rectangle('fill',0,0,280,35)
end
-- Name & color
local item=_getList()[id]
GC.shadedPrint(item.title,10,-3,'left',1,COLOR.D,typeColor[item.type])
-- Draw list box /
end}
-- Drawing object /
-- Necessary local functions
-- Clear the result
local function _clearResult()
TABLE.cut(result)
selected=1
scrollPos=0
listBox.selected=1
justSearched=true
searchWait,lastSearch=0,false
scene.widgetList.copy.hide=false
end
-- Search through the dictionary
local function _search()
local input=inputBox:getText():lower()
_clearResult()
-- This change was made by Sea. Should the search function prioritize the best match result and move it to the top of the search result
-- Usually yes except Vietnamese version of Zictionary
local prioritizeBestMatch=not SETTING.locale:find"vi"
local first
for i=1,#dict do
local pos=find(dict[i].title:lower(),input,nil,true) or find(dict[i].keywords:lower(),input,nil,true)
if pos==1 and not first and prioritizeBestMatch then
if pos==1 and not first then
ins(result,1,dict[i])
first=true
elseif pos then
@@ -74,10 +103,115 @@ local function _search()
end
if #result>0 then
SFX.play('reach')
justSearched=true
end
lastSearch=input
end
-- Jump over n items
local function _jumpover(key,n)
n=n or 1
if key=='left' or key=='pageup' then
for _=1,n do scene.widgetList.listBox:arrowKey('up') end
else for _=1,n do scene.widgetList.listBox:arrowKey('down') end end
end
-- Copy the content
local function _copy()
local t=_getList()[listBox.selected]
t=t.title_Org..":\n"..t.content_Org..(t.url and "\n[ "..t.url.." ]\n" or "\n")..text.dictNote
love.system.setClipboardText(t)
scene.widgetList.copy.hide=true
MES.new('info',text.copyDone)
end
-- Update the infobox
local function _updateInfoBox(c)
local _t,t
if c==nil then
if showingHelp then
if text.dict.helpText then
t,_t=text.dict.helpText:repD(
CHAR.key.up, CHAR.key.down, CHAR.key.left, CHAR.key.right,
CHAR.controller.xboxX, CHAR.controller.xboxY, CHAR.controller.xboxA, CHAR.controller.xboxB,
CHAR.icon.help, CHAR.icon.copy, CHAR.icon.globe,
CHAR.icon.toUp, CHAR.icon.toDown, CHAR.key.winMenu
),true
else _t,t=true,{"NO HELP TEXT AVAILABLE!\n","Please switch language to English and try again to read the help text"} end
else _t,t=pcall(function() return _getList()[listBox.selected].content end) end
if _t then c=t else c={""} end
_t,t=nil,nil
end
local _w,c=FONT.get(currentFontSize):getWrap(c,840)
infoBox:setTexts(c)
end
-- Show Help or not
local function _toggleHelp()
local listBox = scene.widgetList.listBox
showingHelp = not showingHelp
if not showingHelp then
listBox.selected=lastSelected
scene.widgetList.copy.hide=false
end
_updateInfoBox()
end
-- Zoom and reset zoom
local function _openZoom() zoomWait=2 end
local function _resetZoom()
currentFontSize,infoBox.font=25,25
infoBox.lineH,infoBox.capacity=35,math.ceil((infoBox.h-10)/35)
_updateInfoBox()
MES.new("check",text.dict.sizeReset,1.26)
end
local function _setZoom(z)
if z~=0 then
currentFontSize=MATH.clamp(currentFontSize+z,15,40)
infoBox.font=currentFontSize
infoBox.lineH=currentFontSize*7/5 -- Recalculate the line's height
infoBox.capacity=math.ceil((infoBox.h-10)/infoBox.lineH)
_updateInfoBox()
_openZoom()
MES.new("check",text.dict.sizeChanged:repD(currentFontSize),1.26)
end
end
-- Checking if waiting countdown reach 0 to run the function.
--
-- currentCountdown: the variable that tracking waiting time
-- timeEndF: run this function if the time reach 0
-- nTimeEndF: run this function if the time has not reached 0
--
-- NOTE: This function will return the modified value of currentcountdown
local function _waitingfor(currentcountdown, timeEndF, nTimeEndF)
currentcountdown = currentcountdown or 0
timeEndF = timeEndF or function() end
nTimeEndF= nTimeEndF or function() end
if currentcountdown>0 then
currentcountdown=currentcountdown-love.timer.getDelta()
if currentcountdown<=0 then timeEndF() else nTimeEndF() end
end
return currentcountdown
end
local function fixScrollingByTouch(x,y,lastX,lastY)
if WIDGET.isFocus(listBox) then
if abs(oldScrollPos-listBox.scrollPos)>26 then
oldScrollPos=listBox.scrollPos
listBox.selected=lastSelected
listBox.scrollPos=oldScrollPos
else
lastSelected=listBox.selected
scene.widgetList.copy.hide=false
_updateInfoBox()
end
end
end
-- Reset everything when opening Zictionary
function scene.enter()
dict=require("parts.language.dict_"..(SETTING.locale:find'zh' and 'zh' or SETTING.locale:find'ja' and 'ja' or SETTING.locale:find'vi' and 'vi' or 'en'))
_scanDict(dict)
@@ -85,12 +219,14 @@ function scene.enter()
inputBox:clear()
result={}
searchWait=0
selected=1
scrollPos=0
if showingHelp then _toggleHelp() end
searchWait=0
lastSelected=0
listBox.selected=1
lastSearch=false
WIDGET.focus(inputBox)
if not MOBILE then WIDGET.focus(inputBox) end
BG.set('rainbow')
end
@@ -98,57 +234,95 @@ function scene.wheelMoved(_,y)
WHEELMOV(y)
end
function scene.keyDown(key)
if key=='up' then
if selected and selected>1 then
selected=selected-1
if selected<scrollPos+1 then
scrollPos=scrollPos-1
-- Switching selected items
if key=='up' or key=='down' then
if not showingHelp then
if love.mouse.isDown(2,3) then
listBox:arrowKey(key)
return
elseif WIDGET.isFocus(listBox) then
listBox:scroll(key=='up' and -1 or 1)
return
end
scene.widgetList.copy.hide=false
end
elseif key=='down' then
if selected and selected<#_getList() then
selected=selected+1
if selected>scrollPos+15 then
scrollPos=selected-15
infoBox:scroll(key=='up' and -3 or 3)
elseif (key=='left' or key=='pageup' or key=='right' or key=='pagedown')
then
if love.keyboard.isDown('lctrl','rctrl','lalt','ralt','lshift','rshift')
then _jumpover(key,12)
else _jumpover(key,1)
end
scene.widgetList.copy.hide=false
end
elseif key=='left' or key=='pageup' then
for _=1,12 do scene.keyDown('up') end
elseif key=='right' or key=='pagedown' then
for _=1,12 do scene.keyDown('down') end
elseif key=='application' then
local url=_getList()[selected].url
-- Copy & Zoom
elseif key=='cC' then _copy()
elseif love.keyboard.isDown('lctrl','rctrl') then
if key == 'c' and not showingHelp then _copy() return
elseif love.keyboard.isDown('-','=','kp-','kp+') then _setZoom((key=='-' or key=='kp-') and -5 or 5)
elseif love.keyboard.isDown('0','kp0') then _resetZoom() end
-- Clear search input, open URL
elseif key=='application' and not showingHelp then
local url=_getList()[listBox.selected].url
if url then love.system.openURL(url) end
elseif key=='delete' then
elseif key=='delete' and not showingHelp then
if inputBox:hasText() then
_clearResult()
inputBox:clear()
SFX.play('hold')
end
-- Get out of Zictionary
elseif key=='escape' then
if inputBox:hasText() then
scene.keyDown('delete')
else
SCN.back()
if inputBox:hasText() then scene.keyDown('delete')
elseif showingHelp then _toggleHelp()
else SCN.back()
end
elseif key=='c' and love.keyboard.isDown('lctrl','rctrl') or key=='cC' then
local t=_getList()[selected]
t=t.title_Org..":\n"..t.content_Org..(t.url and "\n[ "..t.url.." ]\n" or "\n")..text.dictNote
love.system.setClipboardText(t)
scene.widgetList.copy.hide=true
MES.new('info',text.copyDone)
return
-- Calling Help
elseif key=='f1' then _toggleHelp()
-- Focus on the search box
else
if not WIDGET.isFocus(inputBox) then
WIDGET.focus(inputBox)
end
if not WIDGET.isFocus(inputBox) then WIDGET.focus(inputBox) end
return true
end
end
function scene.gamepadDown(key)
local Joystick=love.joystick.getJoysticks()[love.joystick.getJoystickCount()]
-- Scrolling text & zooming
if (key=='dpup' or key=='dpdown') then
if Joystick:isGamepadDown('a')
then _setZoom(key=='dpup' and 5 or -5)
else infoBox:scroll(key=='dpup' and -3 or 3)
end
-- Switching selected items
elseif key=='dpleft' or key=='dpright' then
_jumpover(key:gsub('dp',''),Joystick:isGamepadDown('a') and 12 or 1)
-- Activate help
elseif key=='y' then _toggleHelp()
-- Exit
elseif key=='back' then SCN.back()
end
end
function scene.mouseDown(mx,my)
lastMouseX,lastMouseY=mx,my
end
function scene.touchDown(mx,my)
lastTouchX,lastTouchY=mx,my
end
-- Check if left mouse key is released
function scene.mouseUp(mx,my)
fixScrollingByTouch(mx,my,lastMouseX,lastMouseY)
end
function scene.touchUp(mx,my)
fixScrollingByTouch(mx,my,lastTouchX,lastTouchY)
end
function scene.update(dt)
-- It's time to search?
local input=inputBox:getText()
if input~=lastTickInput then
if #input==0 then
@@ -158,53 +332,62 @@ function scene.update(dt)
end
lastTickInput=input
end
if searchWait>0 then
searchWait=searchWait-dt
if searchWait<=0 then
if #input>0 and input~=lastSearch then
_search()
end
searchWait=_waitingfor(
searchWait,
function() if #input>0 and input~=lastSearch then _search() end end
)
-- It's time to swap zoom buttons?
zoomWait=_waitingfor(
zoomWait,
function()
scene.widgetList.openzoom .hide=false
scene.widgetList.resetzoom.hide=false
scene.widgetList.zoomin .hide=true
scene.widgetList.zoomout .hide=true
end,
function()
scene.widgetList.openzoom .hide=true
scene.widgetList.resetzoom.hide=true
scene.widgetList.zoomin .hide=false
scene.widgetList.zoomout .hide=false
end
end
)
end
local function listStencil()
GC.rectangle('fill',20,180,280,526)
end
function scene.draw()
-- Order: list, info, keys
-- Draw background
gc.setColor(COLOR.dX)
gc.rectangle('fill',300,180,958,526,5)
gc.rectangle('fill',20,180,280,526,5)
gc.rectangle('fill',1194,180,80,526,5) -- keys
-- Draw outline
gc.setLineWidth(2)
gc.setColor(COLOR.Z)
gc.rectangle('line',300,180,958,526,5)
gc.rectangle('line',20,180,280,526,5)
gc.rectangle('line',1194,180,80,526,5) -- keys
-- Draw key seperating outline
gc.rectangle('line',1194,260,80,1,0) -- A | B
gc.rectangle('line',1194,410,80,1,0) -- B | C
gc.rectangle('line',1194,560,80,1,0) -- C | D
local list=_getList()
gc.setColor(COLOR.Z)
local t=list[selected].content
setFont(
#t>900 and 15 or
#t>600 and 20 or
#t>400 and 25 or
30
)
gc.printf(t,306,180,950)
setFont(30)
gc.setColor(1,1,1,.4+.05*sin(TIME()*12.6))
gc.rectangle('fill',20,143+35*(selected-scrollPos),280,35)
GC.stencil(listStencil)
GC.setStencilTest('equal',1)
setFont(30)
for i=1,min(#list,15) do
local y=142+35*i
i=i+scrollPos
local item=list[i]
GC.shadedPrint(item.title,30,y,'left',1,COLOR.D,typeColor[item.type])
-- Showing Help?
if showingHelp then
listBox.selected=0
scene.widgetList.copy.hide,scene.widgetList.link.hide=true,true
-- If not then, check the selected item if it is changed or not?
-- If yes, update lastSelected then update the textbox!
elseif justSearched then
listBox:setList(_getList())
justSearched=false
elseif lastSelected~=listBox.selected and not love.mouse.isDown(1) then
_updateInfoBox()
lastSelected=listBox.selected
scene.widgetList.copy.hide=false
end
GC.setStencilTest()
if searchWait>0 then
local r=TIME()*2
@@ -215,16 +398,30 @@ function scene.draw()
end
scene.widgetList={
WIDGET.newText{name='book', x=20,y=15,font=70,align='L',fText=CHAR.icon.zBook},
WIDGET.newText{name='title', x=100,y=15,font=70,align='L'},
WIDGET.newText {name='book', x=20, y=15, font=70,align='L',fText=CHAR.icon.zBook},
WIDGET.newText {name='title', x=100, y=15, font=70,align='L'},
listBox,
inputBox,
WIDGET.newKey{name='link', x=1120,y=655,w=80,font=55,fText=CHAR.icon.globe, code=pressKey'application',hideF=function() return not _getList()[selected].url end},
WIDGET.newKey{name='copy', x=1210,y=655,w=80,font=50,fText=CHAR.icon.copy, code=pressKey'cC'},
WIDGET.newKey{name='up', x=1120,y=475,w=80,font=50,fText=CHAR.key.up, code=pressKey'up',hide=not MOBILE},
WIDGET.newKey{name='down', x=1120,y=565,w=80,font=50,fText=CHAR.key.down, code=pressKey'down',hide=not MOBILE},
WIDGET.newKey{name='pageup', x=1210,y=475,w=80,font=50,fText=CHAR.icon.toUp, code=pressKey'pageup',hide=not MOBILE},
WIDGET.newKey{name='pagedown',x=1210,y=565,w=80,font=50,fText=CHAR.icon.toDown,code=pressKey'pagedown',hide=not MOBILE},
WIDGET.newButton{name='back', x=1165,y=60,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=backScene},
}
infoBox,
WIDGET.newKey {name='link', x=1234,y=600,w=60,font=45,fText=CHAR.icon.globe, code=pressKey'application',hideF=function() return not ((not (showingHelp or listBox.selected==0)) and _getList()[listBox.selected].url) end},
WIDGET.newKey {name='copy', x=1234,y=670,w=60,font=40,fText=CHAR.icon.copy, code=pressKey'cC'},
WIDGET.newKey {name='openzoom', x=1234,y=300,w=60,font=25,fText="aA", code=function() _openZoom() end,hide=false},
WIDGET.newKey {name='resetzoom',x=1234,y=370,w=60,font=25,fText="100%", code=function() _resetZoom() end,hide=false},
WIDGET.newKey {name='zoomin', x=1234,y=300,w=60,font=40,fText="A", code=function() _setZoom(5) end,hide=true},
WIDGET.newKey {name='zoomout', x=1234,y=370,w=60,font=40,fText="a", code=function() _setZoom(-5) end,hide=true},
WIDGET.newKey {name='pageup', x=1234,y=450,w=60,font=40,fText=CHAR.icon.toUp, hideF=function() return love.mouse.isDown(2,3) or showingHelp end,code=function() _jumpover('left') end},
WIDGET.newKey {name='pagedown', x=1234,y=520,w=60,font=40,fText=CHAR.icon.toDown,hideF=function() return love.mouse.isDown(2,3) or showingHelp end,code=function() _jumpover('right') end},
WIDGET.newKey {name='pageup1', x=1234,y=450,w=60,font=40,fText=CHAR.key.up, hideF=function() return not love.mouse.isDown(2,3) or showingHelp end,color="A"},
WIDGET.newKey {name='pagedown1',x=1234,y=520,w=60,font=40,fText=CHAR.key.down, hideF=function() return not love.mouse.isDown(2,3) or showingHelp end,color="A"},
WIDGET.newKey {name='help0', x=1234,y=220,w=60,font=40,fText=CHAR.icon.help, code=pressKey'f1',hideF=function() return showingHelp end},
WIDGET.newKey {name='help1', x=1234,y=220,w=60,font=40,fText=CHAR.icon.help, code=pressKey'f1',hideF=function() return not showingHelp end,color='lF'},
WIDGET.newButton{name='back', x=1165,y=60, w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=backScene},
WIDGET.newText {name='buttontip',x=1274,y=110,w=762,h=60,font=40,align='R',fText=CHAR.controller.xboxY.."/[F1]: "..CHAR.icon.help}
}
-- NOTE: The gap between Link-Copy, Page, Zoom, Help is 60*1.5-10=80 :) The gap between 2 buttons in one group is 60+10=70
return scene