rotor-framework 0.7.5 β 0.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -96,7 +96,7 @@ You can find [π±](./docs/ai/readme.opt.yaml) symbols in all documentation page
|
|
|
96
96
|
|
|
97
97
|
## π Learn More
|
|
98
98
|
|
|
99
|
-

|
|
100
100
|
|
|
101
101
|
### Framework Core
|
|
102
102
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rotor-framework",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.6",
|
|
4
4
|
"description": "Roku toolkit library providing a ViewBuilder, full UI lifecycle with focus handling and many core features, plus MVI-based state management.",
|
|
5
5
|
"author": "BalΓ‘zs MolnΓ‘r",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
' βββββββ ββ β ββ βββββββ βββββββββββββββββ βββββββββ ββββ βββββββββββ
|
|
5
5
|
' ββ βββββββ β βββββββ ββ ββ ββ ββββ ββββ βββββββββββββββββββ ββββ ββ
|
|
6
6
|
' Rotor Frameworkβ’
|
|
7
|
-
' Version 0.7.
|
|
7
|
+
' Version 0.7.6
|
|
8
8
|
' Β© 2025 BalΓ‘zs MolnΓ‘r β Apache License 2.0
|
|
9
9
|
' =========================================================================
|
|
10
10
|
|
|
@@ -86,7 +86,7 @@ namespace Rotor
|
|
|
86
86
|
class Framework
|
|
87
87
|
|
|
88
88
|
name = "Rotor Framework"
|
|
89
|
-
version = "0.7.
|
|
89
|
+
version = "0.7.6"
|
|
90
90
|
|
|
91
91
|
config = {
|
|
92
92
|
tasks: invalid, ' @array (optional)
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
' βββββββ ββ β ββ βββββββ βββββββββββββββββ βββββββββ ββββ βββββββββββ
|
|
5
5
|
' ββ βββββββ β βββββββ ββ ββ ββ ββββ ββββ βββββββββββββββββββ ββββ ββ
|
|
6
6
|
' Rotor Frameworkβ’
|
|
7
|
-
' Version 0.7.
|
|
7
|
+
' Version 0.7.6
|
|
8
8
|
' Β© 2025 BalΓ‘zs MolnΓ‘r β Apache License 2.0
|
|
9
9
|
' =========================================================================
|
|
10
10
|
|
|
@@ -70,7 +70,7 @@ namespace Rotor
|
|
|
70
70
|
class FrameworkTask
|
|
71
71
|
|
|
72
72
|
name = "Rotor Framework"
|
|
73
|
-
version = "0.7.
|
|
73
|
+
version = "0.7.6"
|
|
74
74
|
|
|
75
75
|
config = {
|
|
76
76
|
tasks: invalid, ' optional
|
|
@@ -797,17 +797,12 @@ namespace Rotor
|
|
|
797
797
|
if group = invalid then return ""
|
|
798
798
|
|
|
799
799
|
' Get fallback identifier for this group
|
|
800
|
-
|
|
800
|
+
' (enableSpatialEnter groups return the spatially closest member here)
|
|
801
|
+
newHID = group.getFallbackIdentifier(m.globalFocusHID)
|
|
801
802
|
|
|
802
803
|
' Check if we found a FocusItem
|
|
803
804
|
if m.focusItemStack.has(newHID)
|
|
804
|
-
'
|
|
805
|
-
if group.enableSpatialEnter = true and direction <> ""
|
|
806
|
-
focused = m.focusItemStack.get(m.globalFocusHID)
|
|
807
|
-
newSpatialHID = m.spatialNavigation(focused, direction, group.getGroupMembersHIDs())
|
|
808
|
-
if newSpatialHID <> "" then newHID = newSpatialHID
|
|
809
|
-
end if
|
|
810
|
-
|
|
805
|
+
' noop β direct focusItem resolved
|
|
811
806
|
else if newHID <> ""
|
|
812
807
|
' Try to find as group first, then deep search
|
|
813
808
|
newHID = m.capturingFocus_recursively(newHID, direction, group.HID)
|
|
@@ -819,7 +814,8 @@ namespace Rotor
|
|
|
819
814
|
end if
|
|
820
815
|
|
|
821
816
|
' Prevent capturing by fallback in the same group where original focus was
|
|
822
|
-
|
|
817
|
+
' Skip this guard for enableSpatialEnter groups (spatial enter explicitly targets a sibling group's member)
|
|
818
|
+
if not group.enableSpatialEnter and newHID <> "" and m.globalFocusHID <> ""
|
|
823
819
|
currentAncestors = m.findAncestorGroups(m.globalFocusHID)
|
|
824
820
|
newAncestors = m.findAncestorGroups(newHID)
|
|
825
821
|
if currentAncestors.Count() > 0 and newAncestors.Count() > 0
|
|
@@ -923,7 +919,6 @@ namespace Rotor
|
|
|
923
919
|
end if
|
|
924
920
|
' Prevent any navigation if it is disabled
|
|
925
921
|
#if debug
|
|
926
|
-
if m.enableFocusNavigation = false and press = true then print "[PLUGIN][FOCUS][INFO] Focus navigation is disabled. Call enableFocusNavigation(true) to make it enabled"
|
|
927
922
|
#end if
|
|
928
923
|
if m.enableFocusNavigation = false then return m.parseOnKeyEventResult(key, false, false)
|
|
929
924
|
' Execute action according to key press
|
|
@@ -1307,7 +1302,6 @@ namespace Rotor
|
|
|
1307
1302
|
trackDescendantFocus as boolean
|
|
1308
1303
|
focusItemsRef as object
|
|
1309
1304
|
groupsRef as object
|
|
1310
|
-
|
|
1311
1305
|
isFocusItem = false
|
|
1312
1306
|
isGroup = true
|
|
1313
1307
|
|
|
@@ -1368,34 +1362,66 @@ namespace Rotor
|
|
|
1368
1362
|
end if
|
|
1369
1363
|
end function
|
|
1370
1364
|
|
|
1371
|
-
function getFallbackIdentifier() as string
|
|
1365
|
+
function getFallbackIdentifier(globalFocusHID = "" as string) as string
|
|
1372
1366
|
HID = ""
|
|
1373
|
-
|
|
1367
|
+
' enableSpatialEnter takes priority over lastFocusedHID
|
|
1368
|
+
' (lastFocusedHID may be stale from slot recycling)
|
|
1369
|
+
if not m.enableSpatialEnter and m.lastFocusedHID <> ""
|
|
1374
1370
|
return m.lastFocusedHID
|
|
1375
|
-
|
|
1376
|
-
if Rotor.Utils.isFunction(m.defaultFocusId)
|
|
1377
|
-
defaultFocusId = Rotor.Utils.callbackScoped(m.defaultFocusId, m.widget) ?? ""
|
|
1378
|
-
else
|
|
1379
|
-
defaultFocusId = m.defaultFocusId
|
|
1380
|
-
end if
|
|
1381
|
-
|
|
1382
|
-
if defaultFocusId <> ""
|
|
1383
|
-
focusItemsHIDlist = m.getGroupMembersHIDs()
|
|
1384
|
-
if focusItemsHIDlist.Count() > 0
|
|
1371
|
+
end if
|
|
1385
1372
|
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1373
|
+
' enableSpatialEnter: return the spatially closest member to the current focus
|
|
1374
|
+
if m.enableSpatialEnter = true and globalFocusHID <> ""
|
|
1375
|
+
prevFocused = m.focusItemsRef.get(globalFocusHID)
|
|
1376
|
+
if prevFocused <> invalid
|
|
1377
|
+
prevFocused.refreshBounding()
|
|
1378
|
+
refPoint = prevFocused.metrics.middlePoint
|
|
1379
|
+
members = m.getGroupMembersHIDs()
|
|
1380
|
+
minDist = 2147483647
|
|
1381
|
+
closestHID = ""
|
|
1382
|
+
for each memberHID in members
|
|
1383
|
+
if memberHID <> globalFocusHID
|
|
1384
|
+
member = m.focusItemsRef.get(memberHID)
|
|
1385
|
+
if member <> invalid
|
|
1386
|
+
member.refreshBounding()
|
|
1387
|
+
dx = member.metrics.middlePoint.x - refPoint.x
|
|
1388
|
+
dy = member.metrics.middlePoint.y - refPoint.y
|
|
1389
|
+
dist = dx * dx + dy * dy
|
|
1390
|
+
if dist < minDist
|
|
1391
|
+
minDist = dist
|
|
1392
|
+
closestHID = memberHID
|
|
1393
|
+
end if
|
|
1394
|
+
end if
|
|
1390
1395
|
end if
|
|
1396
|
+
end for
|
|
1397
|
+
if closestHID <> ""
|
|
1398
|
+
return closestHID
|
|
1399
|
+
end if
|
|
1400
|
+
end if
|
|
1401
|
+
end if
|
|
1391
1402
|
|
|
1392
|
-
|
|
1403
|
+
' Default: use defaultFocusId expression
|
|
1404
|
+
if Rotor.Utils.isFunction(m.defaultFocusId)
|
|
1405
|
+
defaultFocusId = Rotor.Utils.callbackScoped(m.defaultFocusId, m.widget) ?? ""
|
|
1406
|
+
else
|
|
1407
|
+
defaultFocusId = m.defaultFocusId
|
|
1408
|
+
end if
|
|
1393
1409
|
|
|
1394
|
-
|
|
1410
|
+
if defaultFocusId <> ""
|
|
1411
|
+
focusItemsHIDlist = m.getGroupMembersHIDs()
|
|
1412
|
+
if focusItemsHIDlist.Count() > 0
|
|
1395
1413
|
|
|
1414
|
+
' Try find valid HID in focusItems by node id
|
|
1415
|
+
focusItemHID = m.findHIDinFocusItemsByNodeId(defaultFocusId, focusItemsHIDlist)
|
|
1416
|
+
if focusItemHID <> ""
|
|
1417
|
+
HID = focusItemHID
|
|
1396
1418
|
end if
|
|
1397
|
-
end if
|
|
1398
1419
|
|
|
1420
|
+
else
|
|
1421
|
+
|
|
1422
|
+
return defaultFocusId
|
|
1423
|
+
|
|
1424
|
+
end if
|
|
1399
1425
|
end if
|
|
1400
1426
|
|
|
1401
1427
|
return HID
|