feat: Add lang module
This commit is contained in:
parent
a857b9be51
commit
7361c012db
8 changed files with 323 additions and 19 deletions
|
|
@ -25,6 +25,8 @@ function module.init(shared)
|
|||
local parseStyles = style.ParseStyles
|
||||
local advancedTween = shared.Tween ---@type quad_module_tween
|
||||
local round = shared.Round ---@type quad_module_round
|
||||
local signal = shared.Signal ---@type quad_module_signal
|
||||
local bindable = signal.Bindable
|
||||
|
||||
local function InstanceNewWithName(classname,parent,name)
|
||||
local item = InstanceNew(classname,parent)
|
||||
|
|
@ -114,6 +116,7 @@ function module.init(shared)
|
|||
if ok then return err end
|
||||
return nil
|
||||
end
|
||||
new.PcallGetProperty = PcallGetProperty
|
||||
|
||||
local function ProcessQuadProperty(processedProperty,iprop,holder,item,className,index,value)
|
||||
if processedProperty[index] then
|
||||
|
|
@ -341,15 +344,21 @@ function module.init(shared)
|
|||
end
|
||||
|
||||
function this:GetPropertyChangedSignal(propertyName)
|
||||
local signal = self.__propertyChangedSignals[propertyName]
|
||||
if not signal then
|
||||
signal = {}
|
||||
self.__propertyChangedSignals[propertyName] = signal
|
||||
local thisSignal = self.__propertyChangedSignals[propertyName]
|
||||
if thisSignal then
|
||||
return thisSignal
|
||||
end
|
||||
thisSignal = bindable.New()
|
||||
self.__propertyChangedSignals[propertyName] = thisSignal
|
||||
return thisSignal
|
||||
end
|
||||
|
||||
function this:EmitPropertyChangedSignal(propertyName,value)
|
||||
|
||||
local thisSignal = self.__propertyChangedSignals[propertyName]
|
||||
if not thisSignal then
|
||||
return
|
||||
end
|
||||
thisSignal:Fire(value)
|
||||
end
|
||||
|
||||
--- re-render object (if some props chaged, call this to render again)
|
||||
|
|
@ -453,9 +462,18 @@ function module.init(shared)
|
|||
if this.UpdateTriggers[k] then
|
||||
self:Update()
|
||||
end
|
||||
|
||||
-- call PropertyChangedSignal
|
||||
if self.__propertyChangedSignals[k] and self[k] ~= v then
|
||||
self:EmitPropertyChangedSignal(k,v)
|
||||
end
|
||||
end
|
||||
|
||||
this.Getter = {}
|
||||
this.Getter = {
|
||||
Parent = function(self)
|
||||
return rawget(self,"__parent")
|
||||
end
|
||||
}
|
||||
this.Setter = {
|
||||
Parent = function(self,parent,object)
|
||||
rawset(self,"__parent",parent)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
---@class quad
|
||||
local module = {}
|
||||
|
||||
if not Instance then
|
||||
print("Instance is not exist, Using custom Instance and print result as string . . .")
|
||||
end
|
||||
|
||||
local IS_TEST = true
|
||||
local VER = "1.14" .. (IS_TEST and "B" or "")
|
||||
local VER = "2.14" .. (IS_TEST and "B" or "")
|
||||
if IS_TEST then
|
||||
warn("You are using BETA version of quad now. Many features may change in the future and unstable. AS USING BETA VERSION OF QUAD, YOU SHOULD KNOW IT WILL BUGGY SOMETIME. still on development - you can ignore this message if have no issue. if you have issue on using quad, please report issue on github. VERSION: "..VER)
|
||||
end
|
||||
|
|
|
|||
173
src/lang.lua
173
src/lang.lua
|
|
@ -1,11 +1,174 @@
|
|||
local module = {}
|
||||
|
||||
function module.init(shared)
|
||||
---@class quad_module_lang
|
||||
local new = {}
|
||||
local insert = table.insert
|
||||
local gsub = string.gsub
|
||||
|
||||
return new
|
||||
function module.init(shared)
|
||||
---@class quad_module_lang
|
||||
local new = {}
|
||||
local warn = shared.warn
|
||||
local store = shared.Store
|
||||
local class = shared.Class
|
||||
local PcallGetProperty = class.PcallGetProperty
|
||||
|
||||
new.Locales = {
|
||||
["English"] = "en_us";
|
||||
["Spanish"] = "es_es";
|
||||
["French"] = "fr_fr";
|
||||
["Indonesian"] = "id_id";
|
||||
["Italian"] = "it_it";
|
||||
["Japanese"] = "ja_jp";
|
||||
["Korean"] = "ko_kr";
|
||||
["Russian"] = "ru_ru";
|
||||
["Thai"] = "th_th";
|
||||
["Turkish"] = "tr_tr";
|
||||
["Vietnamese"] = "vi_vn";
|
||||
["Portuguese"] = "pt_br";
|
||||
["German"] = "de_de";
|
||||
["ChineseSimplified"] = "zh_cn";
|
||||
["ChineseTraditional"] = "zh_tw";
|
||||
["Bulgarian"] = "bg_bg";
|
||||
["Bengali"] = "bn_bd";
|
||||
["Czech"] = "cs_cz";
|
||||
["Danish"] = "da_dk";
|
||||
["Greek"] = "el_gr";
|
||||
["Estonian"] = "et_ee";
|
||||
["Finnish"] = "fi_fi";
|
||||
["Hindi"] = "hi_in";
|
||||
["Croatian"] = "hr_hr";
|
||||
["Hungarian"] = "hu_hu";
|
||||
["Georgian"] = "ka_ge";
|
||||
["Kazakh"] = "kk_kz";
|
||||
["Khmer"] = "km_kh";
|
||||
["Lithuanian"] = "lt_lt";
|
||||
["Latvian"] = "lv_lv";
|
||||
["Malay"] = "ms_my";
|
||||
["Burmese"] = "my_mm";
|
||||
["Bokmal"] = "nb_no";
|
||||
["Dutch"] = "nl_nl";
|
||||
["Filipino"] = "fil_ph";
|
||||
["Polish"] = "pl_pl";
|
||||
["Romanian"] = "ro_ro";
|
||||
["Ukrainian"] = "uk_ua";
|
||||
["Sinhala"] = "si_lk";
|
||||
["Slovak"] = "sk_sk";
|
||||
["Slovenian"] = "sl_sl";
|
||||
["Albanian"] = "sq_al";
|
||||
["Bosnian"] = "bs_ba";
|
||||
["Serbian"] = "sr_rs";
|
||||
["Swedish"] = "sv_se";
|
||||
["Arabic"] = "ar_001";
|
||||
}
|
||||
new.Lang = game:GetService("LocalizationService").RobloxLocaleId
|
||||
new.Default = new.Locales.English
|
||||
|
||||
local lang = {}
|
||||
lang.__index = lang
|
||||
function lang.New(id,handlers)
|
||||
local this = {handlers=handlers,id=id,store=store.New(),index=1}
|
||||
lang[id] = this
|
||||
setmetatable(this,lang)
|
||||
end
|
||||
|
||||
-- read options, and make string and save into store for updating
|
||||
function lang.Update(valueStore,handler,index,options)
|
||||
if not index then
|
||||
error(("Index must be a number, but got %s"):format(type(index)))
|
||||
end
|
||||
index = tostring(index)
|
||||
|
||||
-- parsing options
|
||||
local parsedOptions = {}
|
||||
for optionName,option in pairs(options) do
|
||||
local quadType = PcallGetProperty(option,"__type")
|
||||
local optionType = type(option)
|
||||
local formatted
|
||||
if quadType == "quad_register" then
|
||||
local default = option.dvalue
|
||||
local with = option.wfunc
|
||||
local tstore = option.store
|
||||
local rawKey = option.key
|
||||
local value = tstore[rawKey]
|
||||
if value == nil then
|
||||
value = default
|
||||
elseif with then
|
||||
value = with(tstore,value,rawKey)
|
||||
end
|
||||
formatted = value
|
||||
elseif optionType == "number" then
|
||||
if option%1 == 0 then
|
||||
-- int
|
||||
formatted = ("%d"):format(option)
|
||||
else
|
||||
-- float
|
||||
formatted = tostring(option)
|
||||
end
|
||||
else
|
||||
formatted = tostring(option)
|
||||
end
|
||||
parsedOptions[optionName] = formatted
|
||||
end
|
||||
|
||||
-- set store value
|
||||
local handlerType = type(handler)
|
||||
if handlerType == "function" then
|
||||
valueStore[index] = handler(parsedOptions)
|
||||
elseif handlerType == "string" then
|
||||
valueStore[index] = gsub(handler,"{(.-)}",parsedOptions)
|
||||
end
|
||||
end
|
||||
local Update = lang.Update
|
||||
|
||||
function lang:Format(options)
|
||||
-- find handler
|
||||
local handler = self.handlers[new.Lang]
|
||||
if not handler then
|
||||
handler = self.handlers[new.Default]
|
||||
end
|
||||
if not handler then
|
||||
warn(("Langauge handle %s is not found on Localization %s"):format(new.Default,self.id))
|
||||
end
|
||||
local index = self.index
|
||||
self.index = index + 1
|
||||
|
||||
-- setup updater
|
||||
for _,option in pairs(options) do
|
||||
local quadType = PcallGetProperty(option,"__type")
|
||||
-- if it is register, setup updater
|
||||
if quadType == "quad_register" then
|
||||
local function regFn()
|
||||
-- !HOLD IT SELF TO PREVENT THIS REGISTER BEGIN REMOVED FROM MEMORY
|
||||
Update(self.store,handler,index,options)
|
||||
end
|
||||
option:Register(regFn)
|
||||
insert(self.store.__keep,regFn)
|
||||
end
|
||||
end
|
||||
|
||||
-- update once
|
||||
Update(self.store,handler,index,options)
|
||||
|
||||
-- return resiter
|
||||
return self.store(tostring(index))
|
||||
end
|
||||
|
||||
function new.New(id,handlers)
|
||||
return lang.New(id,handlers)
|
||||
end
|
||||
|
||||
setmetatable(new,{
|
||||
__call = function(_,id)
|
||||
return function (options)
|
||||
local data = lang[id]
|
||||
if not data then
|
||||
error(("Localization %s is not definded"):format(id))
|
||||
end
|
||||
return data:Format(options)
|
||||
end
|
||||
end;
|
||||
})
|
||||
|
||||
return new
|
||||
end
|
||||
|
||||
return module
|
||||
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ function module.init(shared)
|
|||
local self = {waitting={},onceConnection={},connection={}}
|
||||
setmetatable(self,signal)
|
||||
end
|
||||
new.Signal = signal
|
||||
new.Bindable = signal
|
||||
|
||||
return new
|
||||
end
|
||||
|
|
|
|||
108
src/types.lua
108
src/types.lua
|
|
@ -187,7 +187,113 @@ export type module_round = {
|
|||
-------------------
|
||||
-- module_signal
|
||||
-------------------
|
||||
export type module_lang = {}
|
||||
export type langOptions = {
|
||||
[string]: register|string|number|any;
|
||||
}
|
||||
export type langHandler = {
|
||||
[string]: string|(langOptions:langOptions)->string;
|
||||
}
|
||||
export type Locale = string
|
||||
export type module_lang = {
|
||||
New: (id:string,handlers:{
|
||||
en_us: langHandler;
|
||||
es_es: langHandler;
|
||||
fr_fr: langHandler;
|
||||
id_id: langHandler;
|
||||
it_it: langHandler;
|
||||
ja_jp: langHandler;
|
||||
ko_kr: langHandler;
|
||||
ru_ru: langHandler;
|
||||
th_th: langHandler;
|
||||
tr_tr: langHandler;
|
||||
vi_vn: langHandler;
|
||||
pt_br: langHandler;
|
||||
de_de: langHandler;
|
||||
zh_cn: langHandler;
|
||||
zh_tw: langHandler;
|
||||
bg_bg: langHandler;
|
||||
bn_bd: langHandler;
|
||||
cs_cz: langHandler;
|
||||
da_dk: langHandler;
|
||||
el_gr: langHandler;
|
||||
et_ee: langHandler;
|
||||
fi_fi: langHandler;
|
||||
hi_in: langHandler;
|
||||
hr_hr: langHandler;
|
||||
hu_hu: langHandler;
|
||||
ka_ge: langHandler;
|
||||
kk_kz: langHandler;
|
||||
km_kh: langHandler;
|
||||
lt_lt: langHandler;
|
||||
lv_lv: langHandler;
|
||||
ms_my: langHandler;
|
||||
my_mm: langHandler;
|
||||
nb_no: langHandler;
|
||||
nl_nl: langHandler;
|
||||
fil_ph: langHandler;
|
||||
pl_pl: langHandler;
|
||||
ro_ro: langHandler;
|
||||
uk_ua: langHandler;
|
||||
si_lk: langHandler;
|
||||
sk_sk: langHandler;
|
||||
sl_sl: langHandler;
|
||||
sq_al: langHandler;
|
||||
bs_ba: langHandler;
|
||||
sr_rs: langHandler;
|
||||
sv_se: langHandler;
|
||||
ar_001: langHandler;
|
||||
})->();
|
||||
Locales: {
|
||||
English: Locale & "en_us";
|
||||
Spanish: Locale & "es_es";
|
||||
French: Locale & "fr_fr";
|
||||
Indonesian: Locale & "id_id";
|
||||
Italian: Locale & "it_it";
|
||||
Japanese: Locale & "ja_jp";
|
||||
Korean: Locale & "ko_kr";
|
||||
Russian: Locale & "ru_ru";
|
||||
Thai: Locale & "th_th";
|
||||
Turkish: Locale & "tr_tr";
|
||||
Vietnamese: Locale & "vi_vn";
|
||||
Portuguese: Locale & "pt_br";
|
||||
German: Locale & "de_de";
|
||||
ChineseSimplified: Locale & "zh_cn";
|
||||
ChineseTraditional: Locale & "zh_tw";
|
||||
Bulgarian: Locale & "bg_bg";
|
||||
Bengali: Locale & "bn_bd";
|
||||
Czech: Locale & "cs_cz";
|
||||
Danish: Locale & "da_dk";
|
||||
Greek: Locale & "el_gr";
|
||||
Estonian: Locale & "et_ee";
|
||||
Finnish: Locale & "fi_fi";
|
||||
Hindi: Locale & "hi_in";
|
||||
Croatian: Locale & "hr_hr";
|
||||
Hungarian: Locale & "hu_hu";
|
||||
Georgian: Locale & "ka_ge";
|
||||
Kazakh: Locale & "kk_kz";
|
||||
Khmer: Locale & "km_kh";
|
||||
Lithuanian: Locale & "lt_lt";
|
||||
Latvian: Locale & "lv_lv";
|
||||
Malay: Locale & "ms_my";
|
||||
Burmese: Locale & "my_mm";
|
||||
Bokmal: Locale & "nb_no";
|
||||
Dutch: Locale & "nl_nl";
|
||||
Filipino: Locale & "fil_ph";
|
||||
Polish: Locale & "pl_pl";
|
||||
Romanian: Locale & "ro_ro";
|
||||
Ukrainian: Locale & "uk_ua";
|
||||
Sinhala: Locale & "si_lk";
|
||||
Slovak: Locale & "sk_sk";
|
||||
Slovenian: Locale & "sl_sl";
|
||||
Albanian: Locale & "sq_al";
|
||||
Bosnian: Locale & "bs_ba";
|
||||
Serbian: Locale & "sr_rs";
|
||||
Swedish: Locale & "sv_se";
|
||||
Arabic: Locale & "ar_001";
|
||||
};
|
||||
Lang: Locale;
|
||||
Default: Locale;
|
||||
} & (id:string)->(langOptions)->register;
|
||||
|
||||
-------------------
|
||||
-- module
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ end
|
|||
|
||||
function module.init()
|
||||
---@module Quad.src.types
|
||||
local types = require(script.Parent.Quad.types)
|
||||
local quad = (require(script.Parent.Quad) :: types.module).Init("ui")
|
||||
local types = require(script.Quad.types)
|
||||
local quad = (require(script.Quad) :: types.module).Init("ui")
|
||||
local Round,Class,Mount,Store,Event,Tween,Style,Signal
|
||||
= quad.Round,quad.Class,quad.Mount,quad.Store,quad.Event,quad.Tween,quad.Style,quad.Signal
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ return {
|
|||
track = function ()
|
||||
|
||||
reload()
|
||||
|
||||
wait()
|
||||
if not _G.uichangetracker then
|
||||
local tracker = require(script.tracker)
|
||||
local changeTracker = tracker.new(script.Parent)
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ local module = {}
|
|||
---@module Quad.src.types
|
||||
local types = require(script.Parent.Quad.types)
|
||||
local quad = (require(script.Parent.Quad) :: types.module).Init("ui")
|
||||
local Round,Class,Mount,Store,Event,Tween,Style
|
||||
= quad.Round,quad.Class,quad.Mount,quad.Store,quad.Event,quad.Tween,quad.Style
|
||||
local Round,Class,Mount,Store,Event,Tween,Style,Lang
|
||||
= quad.Round,quad.Class,quad.Mount,quad.Store,quad.Event,quad.Tween,quad.Style,quad.Lang
|
||||
|
||||
local Global = Store.GetStore "global"
|
||||
|
||||
|
|
@ -26,15 +26,22 @@ Style "tweenTestFrame" {
|
|||
BackgroundColor3 = Color3.fromRGB(0, 0, 0);
|
||||
}
|
||||
|
||||
Lang.New("tweenCount",{
|
||||
[Lang.Locales.Korean] = "{count}번 실행했어요";
|
||||
[Lang.Locales.English] = "Ran {count} times";
|
||||
})
|
||||
|
||||
-- Create GUI
|
||||
local tweenTest = Class.Extend()
|
||||
|
||||
function tweenTest:Init(Prop)
|
||||
Prop:Default("Count",0)
|
||||
Prop:Default("Position",UDim2.fromOffset(50,0))
|
||||
local on = false
|
||||
task.spawn(function()
|
||||
while task.wait(2) do
|
||||
on = not on
|
||||
Prop.Count = Prop.Count + 1
|
||||
Prop.Position = on and UDim2.new(1,-50-60,0,0) or UDim2.fromOffset(50,0)
|
||||
end
|
||||
end)
|
||||
|
|
@ -42,6 +49,12 @@ end
|
|||
|
||||
function tweenTest:Render(Prop)
|
||||
return Frame {
|
||||
TextLabel {
|
||||
Size = UDim2.new(1,0,0,30);
|
||||
Text = Lang "tweenCount" {
|
||||
count = Prop "Count":With(function(_,value) return value*2 end);
|
||||
};
|
||||
};
|
||||
Size = UDim2.fromScale(1,1);
|
||||
TextLabel "tweenTestFrame" {
|
||||
Text = "Linear";
|
||||
|
|
|
|||
Loading…
Reference in a new issue