Translator初步
This commit is contained in:
@@ -4,6 +4,7 @@ Checks: >
|
||||
-altera-struct-pack-align,
|
||||
-altera-unroll-loops,
|
||||
-boost-*,
|
||||
-bugprone-assignment-in-if-condition,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-bugprone-forward-declaration-namespace,
|
||||
-bugprone-reserved-identifier,
|
||||
|
||||
@@ -37,6 +37,8 @@ add_executable(${PROJECT_NAME}
|
||||
IText.h
|
||||
exception.cpp
|
||||
exception.h
|
||||
File.h
|
||||
File.cpp
|
||||
TextureManager.cpp
|
||||
TextureManager.h
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
#include "def.h"
|
||||
|
||||
#include "exception.h"
|
||||
#include "File.h"
|
||||
|
||||
File FileAccessor::getAccess(const String& path) {
|
||||
namespace fs = std::filesystem;
|
||||
using Path = fs::path;
|
||||
Path original = path;
|
||||
Path p = original.parent_path();
|
||||
if (!fs::exists(p)) {
|
||||
create_directories(p);
|
||||
Logger.info(L"Created directory " + p.wstring());
|
||||
}
|
||||
return File(p);
|
||||
}
|
||||
@@ -153,3 +153,12 @@ public:
|
||||
return loadUntil(line);
|
||||
}
|
||||
};
|
||||
|
||||
class FileAccessor {
|
||||
public:
|
||||
[[nodiscard]] bool exists(const String& path) const { return std::filesystem::exists(path); }
|
||||
|
||||
File getAccess(const String& path);
|
||||
};
|
||||
|
||||
inline FileAccessor fileAccessor = FileAccessor();
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <random>
|
||||
|
||||
#include "gc.h"
|
||||
#include "Hud.h"
|
||||
#include "Task.h"
|
||||
|
||||
@@ -61,7 +61,7 @@ void Font::drawDirect(const RenderableString::StringConfig& config, const int x,
|
||||
}
|
||||
|
||||
void Font::clear() const {
|
||||
for (const auto& fnt : fonts | std::views::values) renderer.deleteObject(fnt);
|
||||
for (const auto& [_, fnt] : fonts) renderer.deleteObject(fnt);
|
||||
fonts.clear();
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ void Font::drawCenter(const RenderableString& text, int x, int y, const int w, c
|
||||
}
|
||||
|
||||
int Font::getWidth(const RenderableString::StringConfig& config) const {
|
||||
HFONT font = tryCreate(config);
|
||||
HFONT const font = tryCreate(config);
|
||||
RECT rect{};
|
||||
SelectObject(renderer.assistDC, font);
|
||||
DrawTextW(renderer.assistDC, config.text.c_str(), static_cast<int>(config.text.length()), &rect, DT_CALCRECT | DT_NOCLIP | DT_SINGLELINE);
|
||||
@@ -129,10 +129,23 @@ void TranslatableText::refreshText() const noexcept {
|
||||
|
||||
void languageMakeChinese(Language& lang) {
|
||||
Logger.debug(L"languageMakeChinese called");
|
||||
Map<std::wstring, LiteralText>& map = lang.translateTable;
|
||||
map.emplace(String(L"hbp.title"), TranslatedText(L"高血压"));
|
||||
map.emplace(String(L"hbp.confirm.confirm"), TranslatedText(L"确认"));
|
||||
map.emplace(String(L"hbp.confirm.cancel"), TranslatedText(L"取消"));
|
||||
Map<std::wstring, TranslatedText>& map = lang.translateTable;
|
||||
map.emplace(L"hbp.title", TranslatedText(L"高血压"));
|
||||
map.emplace(L"hbp.confirm.confirm", TranslatedText(L"确认"));
|
||||
map.emplace(L"hbp.confirm.cancel", TranslatedText(L"取消"));
|
||||
map.emplace(L"hbp.caption.close", TranslatedText(L"\\#ffee0000关闭窗口"));
|
||||
map.emplace(L"hbp.caption.maximize", TranslatedText(L"\\#ff4488ee最大化窗口"));
|
||||
map.emplace(L"hbp.caption.restore", TranslatedText(L"\\#ff4488ee复原窗口"));
|
||||
map.emplace(L"hbp.caption.minimize", TranslatedText(L"\\#ffeeaaaa最小化窗口"));
|
||||
map.emplace(L"hbp.float.freshCanvas", TranslatedText(L"\\.ff4488aa\\#ff000000右键以刷新窗口绘制"));
|
||||
map.emplace(L"hbp.button.exit", TranslatedText(L"\\#ff44ee66退出"));
|
||||
map.emplace(L"hbp.float.exit", TranslatedText(L"\\#ff44ee66退出游戏"));
|
||||
map.emplace(L"hbp.confirming.exit", TranslatedText(L"是否\\#ff44ee66退出游戏\\r?"));
|
||||
map.emplace(L"hbp.button.settings", TranslatedText(L"\\#ff4488aa设置"));
|
||||
map.emplace(L"hbp.float.settings", TranslatedText(L"\\#ff4488aa设置"));
|
||||
map.emplace(L"hbp.button.start", TranslatedText(L"\\#ffee0000开始"));
|
||||
map.emplace(L"hbp.float.start", TranslatedText(L"\\#ffee0000开始游戏"));
|
||||
map.emplace(L"hbp.confirming.start", TranslatedText(L"是否\\#ffee0000退出游戏\\r?"));
|
||||
}
|
||||
|
||||
inline Translator translator = Translator();
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ranges>
|
||||
|
||||
#include "def.h"
|
||||
#include "Chars.h"
|
||||
@@ -355,8 +354,7 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
inline RenderableString operator""_renderable(const wchar* const text, const QWORD) noexcept { return RenderableString(text); }
|
||||
|
||||
inline RenderableString operator""_renderable(const wchar* const text, const QWORD length) noexcept { return RenderableString(String(text, length)); }
|
||||
|
||||
class Font {
|
||||
public:
|
||||
@@ -468,7 +466,7 @@ public:
|
||||
[[nodiscard]] Font& getDefault() const noexcept { return *defaultFont; }
|
||||
|
||||
void resize(const int width, const int height) {
|
||||
for (auto& font : fonts | std::views::values)
|
||||
for (auto& [_, font] : fonts)
|
||||
if (font.resize) font.resize(width, height);
|
||||
else {
|
||||
font.height = static_cast<long>(interactSettings.actual.fontHeight * font.heightModifier);
|
||||
@@ -497,6 +495,8 @@ public:
|
||||
const RenderableString& getRenderableString() const noexcept override { return renderableString; }
|
||||
} TranslatedText;
|
||||
|
||||
inline LiteralText operator""_literal(const wchar* const text, const QWORD length) noexcept { return LiteralText(String(text, length)); }
|
||||
|
||||
class TranslatableText final : public IText {
|
||||
const String idSrc;
|
||||
mutable const LiteralText* target = nullptr;
|
||||
@@ -505,11 +505,17 @@ class TranslatableText final : public IText {
|
||||
public:
|
||||
TranslatableText(const String& id) : idSrc(id) {}
|
||||
TranslatableText(String&& id) : idSrc(std::move(id)) {}
|
||||
TranslatableText(const TranslatableText& other) : idSrc(other.idSrc) {}
|
||||
TranslatableText(TranslatableText&& other) noexcept : idSrc(std::move(other.idSrc)) {}
|
||||
const String& getID() const noexcept { return idSrc; }
|
||||
const String& getText() const noexcept override;
|
||||
const RenderableString& getRenderableString() const noexcept override;
|
||||
void refreshText() const noexcept;
|
||||
};
|
||||
|
||||
inline TranslatableText operator""_translates(const wchar* const text, const QWORD length) noexcept { return TranslatableText(String(text, length)); }
|
||||
inline TranslatedText operator""__translated(const wchar* const text, const QWORD length) noexcept { return TranslatedText(String(text, length)); }
|
||||
|
||||
using LangID = unsigned int;
|
||||
|
||||
struct Language {
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include "def.h"
|
||||
#include "exception.h"
|
||||
#include "Task.h"
|
||||
|
||||
+14
-13
@@ -45,9 +45,9 @@ void WindowManager::clear() noexcept {
|
||||
}
|
||||
|
||||
CaptionWindow::CaptionWindow() {
|
||||
Widget* close = widgets.emplace_back(Button(0, 0, interactSettings.actual.captionHeight, interactSettings.actual.captionHeight, Location::RIGHT_TOP, LiteralText(L"\\f\1\u2716")));
|
||||
Widget* close = widgets.emplace_back(Button(0, 0, interactSettings.actual.captionHeight, interactSettings.actual.captionHeight, Location::RIGHT_TOP, L"\\f\1\u2716"_literal));
|
||||
close->mouseClick = [](Widget&, MouseButtonCode) { DestroyWindow(MainWindowHandle); };
|
||||
close->onTick = [this](const Widget& self, MouseButtonCode) { if (self.containsMouse()) game.getFloatWindow().push(L"\\#ffee0000关闭窗口"_renderable); };
|
||||
close->onTick = [](const Widget& self, MouseButtonCode) { if (self.containsMouse()) game.getFloatWindow().push(TranslatableText(L"hbp.caption.close").getRenderableString()); };
|
||||
close->absolute();
|
||||
close->backgroundColor.hover = 0xffee0000;
|
||||
close->backgroundColor.active = 0;
|
||||
@@ -58,15 +58,15 @@ CaptionWindow::CaptionWindow() {
|
||||
close->foregroundColor.inactive = 0xff000000;
|
||||
close->foregroundColor.clicked = 0xff000000;
|
||||
|
||||
Widget* maxRestore = widgets.emplace_back(Button(-interactSettings.actual.captionHeight, 0, interactSettings.actual.captionHeight, interactSettings.actual.captionHeight, Location::RIGHT_TOP, LiteralText(IsZoomed(MainWindowHandle) ? L"\\f\1🗗" : L"\\f\1🗖" )));
|
||||
Widget* maxRestore = widgets.emplace_back(Button(-interactSettings.actual.captionHeight, 0, interactSettings.actual.captionHeight, interactSettings.actual.captionHeight, Location::RIGHT_TOP, IsZoomed(MainWindowHandle) ? L"\\f\1🗗"_literal : L"\\f\1🗖"_literal ));
|
||||
maxRestore->mouseClick = [](Widget&, MouseButtonCode) {};
|
||||
maxRestore->mouseClick = [](Widget& self, MouseButtonCode) {
|
||||
if ((self.unused[1] = IsZoomed(MainWindowHandle))) ShowWindow(MainWindowHandle, SW_RESTORE);
|
||||
if ((self.unused[1] = static_cast<char>(IsZoomed(MainWindowHandle)))) ShowWindow(MainWindowHandle, SW_RESTORE);
|
||||
else ShowWindow(MainWindowHandle, SW_MAXIMIZE);
|
||||
};
|
||||
maxRestore->onTick = [this](const Widget& self, MouseButtonCode) { if (self.containsMouse()) game.getFloatWindow().push(self.unused[1] ? L"\\#ff4488ee复原窗口"_renderable : L"\\#ff4488ee最大化窗口"_renderable); };
|
||||
maxRestore->onTick = [](const Widget& self, MouseButtonCode) { if (self.containsMouse()) game.getFloatWindow().push(self.unused[1] ? TranslatableText(L"hbp.caption.maximize").getRenderableString() : TranslatableText(L"hbp.caption.restore").getRenderableString() ); };
|
||||
maxRestore->absolute();
|
||||
maxRestore->unused[1] = IsZoomed(MainWindowHandle);
|
||||
maxRestore->unused[1] = static_cast<char>(IsZoomed(MainWindowHandle));
|
||||
maxRestore->backgroundColor.hover = 0xffcccccc;
|
||||
maxRestore->backgroundColor.active = 0;
|
||||
maxRestore->backgroundColor.inactive = 0xff555555;
|
||||
@@ -76,7 +76,8 @@ CaptionWindow::CaptionWindow() {
|
||||
maxRestore->foregroundColor.inactive = 0xff000000;
|
||||
maxRestore->foregroundColor.clicked = 0xff000000;
|
||||
|
||||
Widget* hide = widgets.emplace_back(Button(-2 * interactSettings.actual.captionHeight, 0, interactSettings.actual.captionHeight, interactSettings.actual.captionHeight, Location::RIGHT_TOP, LiteralText(L"\\f\1🗕")));
|
||||
Widget* hide = widgets.emplace_back(Button(-2 * interactSettings.actual.captionHeight, 0, interactSettings.actual.captionHeight, interactSettings.actual.captionHeight, Location::RIGHT_TOP, L"\\f\1🗕"_literal));
|
||||
hide->onTick = [](const Widget& self, MouseButtonCode) { if (self.containsMouse()) game.getFloatWindow().push(TranslatableText(L"hbp.caption.minimize").getRenderableString()); };
|
||||
hide->mouseClick = [](Widget&, MouseButtonCode) { ShowWindow(MainWindowHandle, SW_MINIMIZE); };
|
||||
hide->absolute();
|
||||
hide->backgroundColor.hover = 0xffcccccc;
|
||||
@@ -88,11 +89,11 @@ CaptionWindow::CaptionWindow() {
|
||||
hide->foregroundColor.inactive = 0xff000000;
|
||||
hide->foregroundColor.clicked = 0xff000000;
|
||||
|
||||
Widget* options = widgets.emplace_back(Button(0, 0, interactSettings.actual.captionHeight, interactSettings.actual.captionHeight, Location::LEFT_TOP, LiteralText(L"\\f\1⛭")));
|
||||
Widget* options = widgets.emplace_back(Button(0, 0, interactSettings.actual.captionHeight, interactSettings.actual.captionHeight, Location::LEFT_TOP, L"\\f\1⛭"_literal));
|
||||
options->onTick = [](const Widget& self, MouseButtonCode) {
|
||||
if (self.containsMouse()) {
|
||||
game.getFloatWindow().push(L"\\#ff4488aa设置"_renderable);
|
||||
game.getFloatWindow().push(L"\\.ff4488aa\\#ff000000右键以刷新窗口绘制"_renderable);
|
||||
game.getFloatWindow().push(TranslatableText(L"hbp.float.settings").getRenderableString());
|
||||
game.getFloatWindow().push(TranslatableText(L"hbp.float.freshCanvas").getRenderableString());
|
||||
}
|
||||
};
|
||||
options->mouseClick = [](Widget&, const MouseButtonCode code) { if (static_cast<int>(MouseButtonCodeEnum::MBC_R_DOWN) & code) { game.tasks.pushThis(renderer.resizeReloadBitmap); } };
|
||||
@@ -157,7 +158,7 @@ void FloatWindow::render() const noexcept {
|
||||
width += fwm2;
|
||||
height += fwm2;
|
||||
if (x + width > renderer.getWidth()) x = renderer.getWidth() - width;
|
||||
y = y < height ? 0 : y - height;
|
||||
y = y < height + interactSettings.actual.captionHeight ? interactSettings.actual.captionHeight : y - height;
|
||||
renderer.fill(x, y, width, height, interactSettings.constants.floatWindowBackground);
|
||||
|
||||
const int xf = x + interactSettings.actual.floatWindowMargin;
|
||||
@@ -327,8 +328,8 @@ ConfirmWindow& ConfirmWindow::requireCancel(const Function<void(Button&)>& func)
|
||||
cancel->x = 0.125;
|
||||
cancel->w = 0.5;
|
||||
}
|
||||
cancel->onTick = [](Widget& cancel, MouseButtonCode) { if (cancel.containsMouse()) cancel.backgroundColor.hover = static_cast<Button&>(cancel).animation.adaptsColor(0x99880000, 0x99ff0000); };
|
||||
cancel->mouseLeave = [](Widget& cancel, int) { static_cast<Button&>(cancel).animation.reset(); };
|
||||
cancel->onTick = [](Widget& cancel, MouseButtonCode) { if (cancel.containsMouse()) cancel.backgroundColor.hover = dynamic_cast<Button&>(cancel).animation.adaptsColor(0x99880000, 0x99ff0000); };
|
||||
cancel->mouseLeave = [](Widget& cancel, int) { dynamic_cast<Button&>(cancel).animation.reset(); };
|
||||
if (func) func(*cancel);
|
||||
cancel->onResize();
|
||||
return *this;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <typeinfo>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <string>
|
||||
@@ -21,6 +22,8 @@
|
||||
#include <sstream>
|
||||
#include <cmath>
|
||||
#include <set>
|
||||
#include <filesystem>
|
||||
#include <random>
|
||||
|
||||
using wchar = wchar_t;
|
||||
using QWORD = unsigned long long int;
|
||||
|
||||
+10
-20
@@ -10,32 +10,22 @@ class StartWindow final : public Window {
|
||||
TranslatableText title = TranslatableText(L"hbp.title");
|
||||
|
||||
StartWindow() {
|
||||
Button* start = dynamic_cast<Button*>(widgets.emplace_back(std::move(Button(0, 0.1, 0.4, 0.08, Location::CENTER, LiteralText(L"\\f\4\\#ff44ee66Exit")))).ptr());
|
||||
start->onTick = [](const Widget& self, MouseButtonCode) { if (self.containsMouse()) game.getFloatWindow().push(L"\\#ff44ee66退出游戏"_renderable); };
|
||||
Button* start = dynamic_cast<Button*>(widgets.emplace_back(std::move(Button(0, 0.1, 0.4, 0.08, Location::CENTER, L"hbp.button.exit"_translates))).ptr());
|
||||
start->onTick = [](const Widget& self, MouseButtonCode) { if (self.containsMouse()) game.getFloatWindow().push(L"hbp.float.exit"_translates.getRenderableString()); };
|
||||
start->mouseClick = [](Widget&, MouseButtonCode) {
|
||||
game.setWindow(&ConfirmWindow::of(LiteralText(L"是否\\#ff44ee66退出游戏\\r?"))->requireCancel().requireConfirm([](Button& confirm) {
|
||||
game.setWindow(&ConfirmWindow::of(L"hbp.confirming.exit"_translates)->requireCancel().requireConfirm([](Button& confirm) {
|
||||
confirm.mouseClick = [](Widget&, MouseButtonCode) { DestroyWindow(MainWindowHandle); };
|
||||
confirm.onTick = [](Widget& self, MouseButtonCode) {
|
||||
if (self.containsMouse()) {
|
||||
game.getFloatWindow().push(L"\\#ff44ee66确定退出游戏"_renderable);
|
||||
self.backgroundColor.hover = static_cast<Button&>(self).animation.adaptsColor(0x99008800, 0x9900ff00);
|
||||
}
|
||||
};
|
||||
confirm.onTick = [](Widget& self, MouseButtonCode) { if (self.containsMouse()) self.backgroundColor.hover = static_cast<Button&>(self).animation.adaptsColor(0x99008800, 0x9900ff00); };
|
||||
}));
|
||||
};
|
||||
Button* optn = dynamic_cast<Button*>(widgets.emplace_back(std::move(Button(0, 0.2, 0.4, 0.08, Location::CENTER, LiteralText(L"\\f\4\\#ff4488eeOptions")))).ptr());
|
||||
optn->onTick = [](const Widget& self, MouseButtonCode) { if (self.containsMouse()) game.getFloatWindow().push(L"\\#ff4488ee设置"_renderable); };
|
||||
Button* exit = dynamic_cast<Button*>(widgets.emplace_back(std::move(Button(0, 0.3, 0.4, 0.08, Location::CENTER, LiteralText(L"\\f\4\\#ffee0000Start")))).ptr());
|
||||
exit->onTick = [](const Widget& self, MouseButtonCode) { if (self.containsMouse()) game.getFloatWindow().push(L"\\#ffee0000开始游戏"_renderable); };
|
||||
Button* optn = dynamic_cast<Button*>(widgets.emplace_back(std::move(Button(0, 0.2, 0.4, 0.08, Location::CENTER, L"hbp.button.settings"_translates))).ptr());
|
||||
optn->onTick = [](const Widget& self, MouseButtonCode) { if (self.containsMouse()) game.getFloatWindow().push(L"hbp.float.settings"_translates.getRenderableString()); };
|
||||
Button* exit = dynamic_cast<Button*>(widgets.emplace_back(std::move(Button(0, 0.3, 0.4, 0.08, Location::CENTER, L"hbp.button.start"_translates))).ptr());
|
||||
exit->onTick = [](const Widget& self, MouseButtonCode) { if (self.containsMouse()) game.getFloatWindow().push(L"hbp.float.start"_translates.getRenderableString()); };
|
||||
exit->mouseClick = [](Widget&, MouseButtonCode) {
|
||||
game.setWindow(&ConfirmWindow::of(LiteralText(L"是否\\#ffee0000退出游戏\\r?"))->requireCancel().requireConfirm([](Button& confirm) {
|
||||
game.setWindow(&ConfirmWindow::of(L"hbp.confirming.start"_translates)->requireCancel().requireConfirm([](Button& confirm) {
|
||||
confirm.mouseClick = [](Widget&, MouseButtonCode) { DestroyWindow(MainWindowHandle); };
|
||||
confirm.onTick = [](Widget& self, MouseButtonCode) {
|
||||
if (self.containsMouse()) {
|
||||
game.getFloatWindow().push(L"\\#ff44ee66确定退出游戏"_renderable);
|
||||
self.backgroundColor.hover = static_cast<Button&>(self).animation.adaptsColor(0x99008800, 0x9900ff00);
|
||||
}
|
||||
};
|
||||
confirm.onTick = [](Widget& self, MouseButtonCode) { if (self.containsMouse()) self.backgroundColor.hover = static_cast<Button&>(self).animation.adaptsColor(0x99008800, 0x9900ff00); };
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user