Added localization support
This commit is contained in:
parent
79c7aa91f8
commit
5fcccf05ca
@ -27,6 +27,9 @@ import ru.windcorp.progressia.client.graphics.gui.event.HoverEvent;
|
|||||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
|
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutVertical;
|
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutVertical;
|
||||||
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
|
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
|
||||||
|
import ru.windcorp.progressia.client.localization.Localizer;
|
||||||
|
|
||||||
|
import java.net.http.WebSocket;
|
||||||
|
|
||||||
public class LayerTestGUI extends GUILayer {
|
public class LayerTestGUI extends GUILayer {
|
||||||
|
|
||||||
@ -77,13 +80,15 @@ public class LayerTestGUI extends GUILayer {
|
|||||||
|
|
||||||
Component charlie = new DebugComponent("Charlie", null, 0x222222);
|
Component charlie = new DebugComponent("Charlie", null, 0x222222);
|
||||||
charlie.setLayout(new LayoutVertical());
|
charlie.setLayout(new LayoutVertical());
|
||||||
|
|
||||||
|
//Debug
|
||||||
|
Localizer.getInstance().setLanguage("ru-RU");
|
||||||
// These two are swapped in code due to a bug in layouts, fixing ATM
|
// These two are swapped in code due to a bug in layouts, fixing ATM
|
||||||
charlie.addChild(
|
charlie.addChild(
|
||||||
new Label(
|
new Label(
|
||||||
"Epsilon",
|
"Epsilon",
|
||||||
new Font().withColor(0x4444BB).deriveItalic(),
|
new Font().withColor(0x4444BB).deriveItalic(),
|
||||||
"Hooray?.. \u269b"
|
Localizer.getInstance().getValue("Epsilon")+"\u269b"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
charlie.addChild(
|
charlie.addChild(
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
package ru.windcorp.progressia.client.localization;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface LocaleListener {
|
||||||
|
void onLocaleChanged(String newLanguage);
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package ru.windcorp.progressia.client.localization;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class Localizer {
|
||||||
|
private static final Localizer instance = new Localizer("assets/languages/lang_list.txt");
|
||||||
|
|
||||||
|
private final Parser langParser;
|
||||||
|
|
||||||
|
private String language;
|
||||||
|
private final String langFolder;
|
||||||
|
|
||||||
|
private Map<String, String> data;
|
||||||
|
private final Map<String, String> langList;
|
||||||
|
|
||||||
|
private final Collection<WeakReference<LocaleListener>> listeners =
|
||||||
|
Collections.synchronizedCollection(new LinkedList<>());
|
||||||
|
|
||||||
|
//lang list must be in the same folder as .lang files
|
||||||
|
public Localizer(String langList) {
|
||||||
|
this.langFolder = langList.concat("/../");
|
||||||
|
langParser = new Parser(langList);
|
||||||
|
this.langList = langParser.parse();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void setLanguage(String language) {
|
||||||
|
if (langList.containsKey(language)) {
|
||||||
|
this.language = language;
|
||||||
|
langParser.setFilePath(langFolder + language + ".lang");
|
||||||
|
data = langParser.parse();
|
||||||
|
pokeListeners(language);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Language not found: " + language);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized String getLanguage() {
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized String getValue(String key) {
|
||||||
|
try {
|
||||||
|
return data.getOrDefault(key, key);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pokeListeners(String newLanguage) {
|
||||||
|
synchronized (listeners) {
|
||||||
|
Iterator<WeakReference<LocaleListener>> iterator = listeners.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
LocaleListener listenerOrNull = iterator.next().get();
|
||||||
|
if (listenerOrNull == null) {
|
||||||
|
iterator.remove();
|
||||||
|
} else {
|
||||||
|
listenerOrNull.onLocaleChanged(newLanguage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Localizer getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addListener(LocaleListener listener) {
|
||||||
|
listeners.add(new WeakReference<>(listener));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeListener(LocaleListener listener) {
|
||||||
|
listeners.removeIf(ref -> listener.equals(ref.get()));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
package ru.windcorp.progressia.client.localization;
|
||||||
|
|
||||||
|
import ru.windcorp.jputil.chars.EscapeException;
|
||||||
|
import ru.windcorp.jputil.chars.Escaper;
|
||||||
|
import ru.windcorp.progressia.common.resource.ResourceManager;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Parser {
|
||||||
|
|
||||||
|
public Parser(String filePath) {
|
||||||
|
this.filePath = filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilePath(String filePath) {
|
||||||
|
this.filePath = filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> parse() {
|
||||||
|
Map<String, String> parsedData = new HashMap<>();
|
||||||
|
try (Reader rawData = ResourceManager
|
||||||
|
.getResource(filePath)
|
||||||
|
.getReader()
|
||||||
|
) {
|
||||||
|
int code;
|
||||||
|
char c;
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
while (true) {
|
||||||
|
code = rawData.read();
|
||||||
|
if (code == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c = (char)code;
|
||||||
|
if (c == '#') {
|
||||||
|
while (c != '\n') {
|
||||||
|
code = rawData.read();
|
||||||
|
if (code == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c = (char)code;
|
||||||
|
}
|
||||||
|
} else if (c == ' ') {
|
||||||
|
code = rawData.read();
|
||||||
|
if (code == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c = (char) code;
|
||||||
|
if (c == '=') {
|
||||||
|
String key = escaper.escape(stringBuilder.toString());
|
||||||
|
stringBuilder.setLength(0);
|
||||||
|
rawData.read(); //skip a char
|
||||||
|
while (true) {
|
||||||
|
code = rawData.read();
|
||||||
|
if (code == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = (char) code;
|
||||||
|
if (code == '\n') {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
stringBuilder.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parsedData.put(escaper.unescape(key),
|
||||||
|
escaper.unescape(stringBuilder.toString()));
|
||||||
|
stringBuilder.setLength(0);
|
||||||
|
}
|
||||||
|
} else if (c == '\n') {
|
||||||
|
stringBuilder.setLength(0);
|
||||||
|
} else {
|
||||||
|
stringBuilder.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException | EscapeException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return parsedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilePath() {
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String filePath;
|
||||||
|
static private final Escaper escaper = new Escaper.EscaperBuilder()
|
||||||
|
.withChars("n", "\n").build();
|
||||||
|
}
|
3
src/main/resources/assets/languages/en-US.lang
Normal file
3
src/main/resources/assets/languages/en-US.lang
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# ru-RU
|
||||||
|
#test
|
||||||
|
Epsilon = Hooray?..
|
2
src/main/resources/assets/languages/lang_list.txt
Normal file
2
src/main/resources/assets/languages/lang_list.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
en-US = US English
|
||||||
|
ru-RU = Русский
|
3
src/main/resources/assets/languages/ru-RU.lang
Normal file
3
src/main/resources/assets/languages/ru-RU.lang
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# ru-RU
|
||||||
|
#test
|
||||||
|
Epsilon = Ура?
|
Reference in New Issue
Block a user