You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
5.2 KiB
143 lines
5.2 KiB
|
5 years ago
|
--========================================================--
|
||
|
|
-- Scorpio UI Reactive --
|
||
|
|
-- --
|
||
|
|
-- Author : kurapica125@outlook.com --
|
||
|
|
-- Create Date : 2020/12/22 --
|
||
|
|
--========================================================--
|
||
|
|
|
||
|
|
--========================================================--
|
||
|
|
Scorpio "Scorpio.UI.Reactive" "1.0.0"
|
||
|
|
--========================================================--
|
||
|
|
|
||
|
|
import "System.Reactive"
|
||
|
|
|
||
|
|
local isUIObject = UI.IsUIObject
|
||
|
|
local isObjectType = Class.IsObjectType
|
||
|
|
local isProperty = System.Property.Validate
|
||
|
|
local isIndexerProperty = System.Property.IsIndexer
|
||
|
|
local getCurrentTarget = Scorpio.UI.Style.GetCurrentTarget
|
||
|
|
local getFeature = Class.GetFeature
|
||
|
|
|
||
|
|
__Static__() __Arguments__{ NEString * 1 }
|
||
|
|
function Wow.FromUIProperty(...)
|
||
|
|
local name = select("#", ...) == 1 and name or { ... }
|
||
|
|
return Observable(function(observer)
|
||
|
|
local indicator = getCurrentTarget()
|
||
|
|
|
||
|
|
if indicator and isUIObject(indicator) then
|
||
|
|
local frame = indicator
|
||
|
|
local subject
|
||
|
|
|
||
|
|
if type(name) == "string" then
|
||
|
|
while frame do
|
||
|
|
subject = Observable.From(frame, name)
|
||
|
|
if subject then break end
|
||
|
|
|
||
|
|
frame = frame:GetParent()
|
||
|
|
end
|
||
|
|
else
|
||
|
|
local nsubject
|
||
|
|
for _, n in ipairs(name) do
|
||
|
|
frame = indicator
|
||
|
|
nsubject = nil
|
||
|
|
|
||
|
|
while frame do
|
||
|
|
nsubject= Observable.From(frame, n)
|
||
|
|
if nsubject then break end
|
||
|
|
|
||
|
|
frame = frame:GetParent()
|
||
|
|
end
|
||
|
|
|
||
|
|
if nsubject then
|
||
|
|
subject = subject and subject:CombineLatest(nsubject) or nsubject
|
||
|
|
else
|
||
|
|
return
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
if subject then return subject:Subscribe(observer) end
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
end
|
||
|
|
|
||
|
|
__Static__() __Arguments__{ NEString * 1 }
|
||
|
|
function Wow.FromPanelProperty(...)
|
||
|
|
local name = select("#", ...) == 1 and name or { ... }
|
||
|
|
return Observable(function(observer)
|
||
|
|
local indicator = getCurrentTarget()
|
||
|
|
|
||
|
|
if indicator and isUIObject(indicator) then
|
||
|
|
local frame = indicator
|
||
|
|
local parent = indicator:GetParent()
|
||
|
|
local index
|
||
|
|
|
||
|
|
while parent do
|
||
|
|
if isObjectType(parent, ElementPanel) then
|
||
|
|
-- Only check the nearest element panel
|
||
|
|
index = frame:GetID()
|
||
|
|
break
|
||
|
|
end
|
||
|
|
|
||
|
|
frame = parent
|
||
|
|
parent = parent:GetParent()
|
||
|
|
end
|
||
|
|
|
||
|
|
if index then
|
||
|
|
if type(name) == "string" then
|
||
|
|
local prop = getFeature(getmetatable(parent), name, true)
|
||
|
|
local psub = prop and isIndexerProperty(prop) and Observable.From(parent, name)
|
||
|
|
if not psub then return end
|
||
|
|
|
||
|
|
local matchIdx = psub.__MatchIndex
|
||
|
|
if not matchIdx then
|
||
|
|
matchIdx = {}
|
||
|
|
psub.__MatchIndex = matchIdx
|
||
|
|
|
||
|
|
psub:Subscribe(function(idx, ...)
|
||
|
|
local s = matchIdx[idx]
|
||
|
|
return s and s:OnNext(...)
|
||
|
|
end)
|
||
|
|
end
|
||
|
|
|
||
|
|
local idxSub = matchIdx[index]
|
||
|
|
if not idxSub then
|
||
|
|
idxSub = Subject()
|
||
|
|
matchIdx[index] = idxSub
|
||
|
|
end
|
||
|
|
|
||
|
|
return idxSub:Subscribe(observer)
|
||
|
|
else
|
||
|
|
local subject
|
||
|
|
|
||
|
|
for _, n in ipairs(name) do
|
||
|
|
local prop = getFeature(getmetatable(parent), n, true)
|
||
|
|
local psub = prop and isIndexerProperty(prop) and Observable.From(parent, n)
|
||
|
|
if not psub then return end
|
||
|
|
|
||
|
|
local matchIdx = psub.__MatchIndex
|
||
|
|
if not matchIdx then
|
||
|
|
matchIdx = {}
|
||
|
|
psub.__MatchIndex = matchIdx
|
||
|
|
|
||
|
|
psub:Subscribe(function(idx, ...)
|
||
|
|
local s = matchIdx[idx]
|
||
|
|
return s and s:OnNext(...)
|
||
|
|
end)
|
||
|
|
end
|
||
|
|
|
||
|
|
local idxSub = matchIdx[index]
|
||
|
|
if not idxSub then
|
||
|
|
idxSub = Subject()
|
||
|
|
matchIdx[index] = idxSub
|
||
|
|
end
|
||
|
|
|
||
|
|
subject = subject and subject:CombineLatest(idxSub) or idxSub
|
||
|
|
end
|
||
|
|
|
||
|
|
if subject then subject:Subscribe(observer) end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
end
|