feat: Add lang module

This commit is contained in:
Qwreey 2023-02-17 09:25:39 +09:00
parent a857b9be51
commit 7361c012db
8 changed files with 323 additions and 19 deletions

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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";