mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-10 10:13:35 +00:00
Fix loading of toolbox text/tooltips of the current language
This commit is contained in:
parent
8d9c3c7c11
commit
473542542e
@ -89,10 +89,21 @@ public:
|
||||
Preferences m_preferences;
|
||||
};
|
||||
|
||||
class App::LoadLanguage {
|
||||
public:
|
||||
LoadLanguage(Preferences& pref,
|
||||
Extensions& exts) {
|
||||
Strings::createInstance(pref, exts);
|
||||
}
|
||||
};
|
||||
|
||||
class App::Modules {
|
||||
public:
|
||||
LoggerModule m_loggerModule;
|
||||
FileSystemModule m_file_system_module;
|
||||
Extensions m_extensions;
|
||||
// Load main language (after loading the extensions)
|
||||
LoadLanguage m_loadLanguage;
|
||||
tools::ToolBox m_toolbox;
|
||||
tools::ActiveToolManager m_activeToolManager;
|
||||
Commands m_commands;
|
||||
@ -100,12 +111,13 @@ public:
|
||||
RecentFiles m_recent_files;
|
||||
InputChain m_inputChain;
|
||||
clipboard::ClipboardManager m_clipboardManager;
|
||||
Extensions m_extensions;
|
||||
// This is a raw pointer because we want to delete this explicitly.
|
||||
app::crash::DataRecovery* m_recovery;
|
||||
|
||||
Modules(bool createLogInDesktop, Preferences& pref)
|
||||
Modules(const bool createLogInDesktop,
|
||||
Preferences& pref)
|
||||
: m_loggerModule(createLogInDesktop)
|
||||
, m_loadLanguage(pref, m_extensions)
|
||||
, m_activeToolManager(&m_toolbox)
|
||||
, m_recent_files(pref.general.recentItems())
|
||||
, m_recovery(nullptr) {
|
||||
@ -175,6 +187,7 @@ void App::initialize(const AppOptions& options)
|
||||
break;
|
||||
}
|
||||
|
||||
// Load modules
|
||||
m_modules = new Modules(createLogInDesktop, preferences());
|
||||
m_legacy = new LegacyModules(isGui() ? REQUIRE_INTERFACE: 0);
|
||||
m_brushes.reset(new AppBrushes);
|
||||
@ -194,9 +207,6 @@ void App::initialize(const AppOptions& options)
|
||||
if (isGui()) {
|
||||
LOG("APP: GUI mode\n");
|
||||
|
||||
// Load main language (which might be in an extension)
|
||||
Strings::instance()->loadCurrentLanguage();
|
||||
|
||||
// Setup the GUI cursor and redraw screen
|
||||
ui::set_use_native_cursors(preferences().cursor.useNativeCursor());
|
||||
ui::set_mouse_cursor_scale(preferences().cursor.cursorScale());
|
||||
|
@ -104,6 +104,7 @@ namespace app {
|
||||
|
||||
private:
|
||||
class CoreModules;
|
||||
class LoadLanguage;
|
||||
class Modules;
|
||||
|
||||
static App* m_instance;
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "app/extensions.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/resource_finder.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "app/xml_document.h"
|
||||
#include "app/xml_exception.h"
|
||||
#include "base/fs.h"
|
||||
@ -22,20 +21,29 @@
|
||||
|
||||
namespace app {
|
||||
|
||||
static Strings* singleton = nullptr;
|
||||
static const char* kDefLanguage = "en";
|
||||
|
||||
// static
|
||||
void Strings::createInstance(Preferences& pref,
|
||||
Extensions& exts)
|
||||
{
|
||||
ASSERT(!singleton);
|
||||
singleton = new Strings(pref, exts);
|
||||
}
|
||||
|
||||
// static
|
||||
Strings* Strings::instance()
|
||||
{
|
||||
static Strings* singleton = nullptr;
|
||||
if (!singleton)
|
||||
singleton = new Strings();
|
||||
return singleton;
|
||||
}
|
||||
|
||||
Strings::Strings()
|
||||
Strings::Strings(Preferences& pref,
|
||||
Extensions& exts)
|
||||
: m_pref(pref)
|
||||
, m_exts(exts)
|
||||
{
|
||||
loadLanguage(kDefLanguage);
|
||||
loadLanguage(currentLanguage());
|
||||
}
|
||||
|
||||
std::set<std::string> Strings::availableLanguages() const
|
||||
@ -56,7 +64,7 @@ std::set<std::string> Strings::availableLanguages() const
|
||||
}
|
||||
|
||||
// Add languages in extensions
|
||||
for (const auto& ext : App::instance()->extensions()) {
|
||||
for (const auto& ext : m_exts) {
|
||||
if (ext->isEnabled() &&
|
||||
ext->hasLanguages()) {
|
||||
for (const auto& langId : ext->languages())
|
||||
@ -70,7 +78,7 @@ std::set<std::string> Strings::availableLanguages() const
|
||||
|
||||
std::string Strings::currentLanguage() const
|
||||
{
|
||||
return Preferences::instance().general.language();
|
||||
return m_pref.general.language();
|
||||
}
|
||||
|
||||
void Strings::setCurrentLanguage(const std::string& langId)
|
||||
@ -79,19 +87,10 @@ void Strings::setCurrentLanguage(const std::string& langId)
|
||||
if (currentLanguage() == langId)
|
||||
return;
|
||||
|
||||
Preferences::instance().general.language(langId);
|
||||
m_pref.general.language(langId);
|
||||
loadLanguage(langId);
|
||||
|
||||
// Reload menus
|
||||
App::instance()->mainWindow()->reloadMenus();
|
||||
}
|
||||
|
||||
// Called when extensions are available
|
||||
void Strings::loadCurrentLanguage()
|
||||
{
|
||||
std::string langId = currentLanguage();
|
||||
if (langId != kDefLanguage)
|
||||
loadLanguage(langId);
|
||||
LanguageChange();
|
||||
}
|
||||
|
||||
void Strings::loadLanguage(const std::string& langId)
|
||||
@ -120,8 +119,7 @@ void Strings::loadStringsFromDataDir(const std::string& langId)
|
||||
|
||||
void Strings::loadStringsFromExtension(const std::string& langId)
|
||||
{
|
||||
Extensions& exts = App::instance()->extensions();
|
||||
std::string fn = exts.languagePath(langId);
|
||||
std::string fn = m_exts.languagePath(langId);
|
||||
if (!fn.empty() && base::is_file(fn))
|
||||
loadStringsFromFile(fn);
|
||||
}
|
||||
|
@ -12,30 +12,41 @@
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "obs/signal.h"
|
||||
|
||||
#include "strings.ini.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
class Preferences;
|
||||
class Extensions;
|
||||
|
||||
// Singleton class to load and access "strings/en.ini" file.
|
||||
class Strings : public app::gen::Strings<app::Strings> {
|
||||
public:
|
||||
static void createInstance(Preferences& pref,
|
||||
Extensions& exts);
|
||||
static Strings* instance();
|
||||
|
||||
const std::string& translate(const char* id) const;
|
||||
|
||||
void loadCurrentLanguage();
|
||||
std::set<std::string> availableLanguages() const;
|
||||
std::string currentLanguage() const;
|
||||
void setCurrentLanguage(const std::string& langId);
|
||||
|
||||
obs::signal<void()> LanguageChange;
|
||||
|
||||
private:
|
||||
Strings();
|
||||
Strings(Preferences& pref,
|
||||
Extensions& exts);
|
||||
|
||||
void loadLanguage(const std::string& langId);
|
||||
void loadStringsFromDataDir(const std::string& langId);
|
||||
void loadStringsFromExtension(const std::string& langId);
|
||||
void loadStringsFromFile(const std::string& fn);
|
||||
|
||||
Preferences& m_pref;
|
||||
Extensions& m_exts;
|
||||
mutable std::unordered_map<std::string, std::string> m_strings;
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -26,16 +26,10 @@ namespace app {
|
||||
class Tool {
|
||||
public:
|
||||
|
||||
Tool(ToolGroup* group,
|
||||
const std::string& id,
|
||||
const std::string& text,
|
||||
const std::string& tips,
|
||||
int default_brush_size)
|
||||
Tool(ToolGroup* group, const std::string& id)
|
||||
: m_group(group)
|
||||
, m_id(id)
|
||||
, m_text(text)
|
||||
, m_tips(tips)
|
||||
, m_default_brush_size(default_brush_size)
|
||||
, m_default_brush_size(1)
|
||||
{ }
|
||||
|
||||
virtual ~Tool()
|
||||
@ -47,6 +41,12 @@ namespace app {
|
||||
const std::string& getTips() const { return m_tips; }
|
||||
int getDefaultBrushSize() const { return m_default_brush_size; }
|
||||
|
||||
void setText(const std::string& text) { m_text = text; }
|
||||
void setTips(const std::string& tips) { m_tips = tips; }
|
||||
void setDefaultBrushSize(const int default_brush_size) {
|
||||
m_default_brush_size = default_brush_size;
|
||||
}
|
||||
|
||||
Fill getFill(int button) { return m_button[button].m_fill; }
|
||||
Ink* getInk(int button) { return m_button[button].m_ink; }
|
||||
Controller* getController(int button) { return m_button[button].m_controller; }
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2017 David Capello
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -31,6 +31,7 @@
|
||||
#include "fixmath/fixmath.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "app/tools/controllers.h"
|
||||
#include "app/tools/inks.h"
|
||||
@ -91,6 +92,18 @@ const char* WellKnownPointShapes::Brush = "brush";
|
||||
const char* WellKnownPointShapes::FloodFill = "floodfill";
|
||||
const char* WellKnownPointShapes::Spray = "spray";
|
||||
|
||||
namespace {
|
||||
|
||||
struct deleter {
|
||||
template<typename T>
|
||||
void operator()(T* p) { delete p; }
|
||||
|
||||
template<typename A, typename B>
|
||||
void operator()(std::pair<A,B>& p) { delete p.second; }
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
ToolBox::ToolBox()
|
||||
{
|
||||
m_xmlTranslator.setStringIdPrefix("tools");
|
||||
@ -137,16 +150,12 @@ ToolBox::ToolBox()
|
||||
m_intertwiners[WellKnownIntertwiners::AsPixelPerfect] = new IntertwineAsPixelPerfect();
|
||||
|
||||
loadTools();
|
||||
|
||||
// When the language is change, we reload the toolbox stirngs/tooltips.
|
||||
Strings::instance()->LanguageChange.connect(
|
||||
[this]{ loadTools(); });
|
||||
}
|
||||
|
||||
struct deleter {
|
||||
template<typename T>
|
||||
void operator()(T* p) { delete p; }
|
||||
|
||||
template<typename A, typename B>
|
||||
void operator()(std::pair<A,B>& p) { delete p.second; }
|
||||
};
|
||||
|
||||
ToolBox::~ToolBox()
|
||||
{
|
||||
std::for_each(m_tools.begin(), m_tools.end(), deleter());
|
||||
@ -203,7 +212,19 @@ void ToolBox::loadTools()
|
||||
|
||||
LOG(VERBOSE) << "TOOL: Group " << groupId << "\n";
|
||||
|
||||
ToolGroup* toolGroup = new ToolGroup(groupId);
|
||||
// Find an existent ToolGroup (this is useful in case we are
|
||||
// reloading tool text/tooltips).
|
||||
ToolGroup* toolGroup = nullptr;
|
||||
for (auto g : m_groups) {
|
||||
if (g->id() == groupId) {
|
||||
toolGroup = g;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (toolGroup == nullptr) {
|
||||
toolGroup = new ToolGroup(groupId);
|
||||
m_groups.push_back(toolGroup);
|
||||
}
|
||||
|
||||
// For each tool
|
||||
TiXmlNode* xmlToolNode = xmlGroup->FirstChild("tool");
|
||||
@ -214,20 +235,31 @@ void ToolBox::loadTools()
|
||||
std::string toolTips = m_xmlTranslator(xmlTool, "tooltip");
|
||||
const char* defaultBrushSize = xmlTool->Attribute("default_brush_size");
|
||||
|
||||
Tool* tool = new Tool(toolGroup, toolId, toolText, toolTips,
|
||||
defaultBrushSize ? strtol(defaultBrushSize, NULL, 10): 1);
|
||||
Tool* tool = nullptr;
|
||||
for (auto t : m_tools) {
|
||||
if (t->getId() == toolId) {
|
||||
tool = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tool == nullptr) {
|
||||
tool = new Tool(toolGroup, toolId);
|
||||
m_tools.push_back(tool);
|
||||
}
|
||||
|
||||
tool->setText(toolText);
|
||||
tool->setTips(toolTips);
|
||||
tool->setDefaultBrushSize(
|
||||
defaultBrushSize ? std::strtol(defaultBrushSize, nullptr, 10): 1);
|
||||
|
||||
LOG(VERBOSE) << "TOOL: Tool " << toolId << " in group " << groupId << " found\n";
|
||||
|
||||
loadToolProperties(xmlTool, tool, 0, "left");
|
||||
loadToolProperties(xmlTool, tool, 1, "right");
|
||||
|
||||
m_tools.push_back(tool);
|
||||
|
||||
xmlTool = xmlTool->NextSiblingElement();
|
||||
}
|
||||
|
||||
m_groups.push_back(toolGroup);
|
||||
xmlGroup = xmlGroup->NextSiblingElement();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2017 David Capello
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -13,6 +13,7 @@
|
||||
#include "app/app.h"
|
||||
#include "app/app_menus.h"
|
||||
#include "app/commands/commands.h"
|
||||
#include "app/i18n/strings.h"
|
||||
#include "app/ini_file.h"
|
||||
#include "app/modules/editors.h"
|
||||
#include "app/notification_delegate.h"
|
||||
@ -150,6 +151,15 @@ MainWindow::MainWindow()
|
||||
remapWindow();
|
||||
|
||||
AppMenus::instance()->rebuildRecentList();
|
||||
|
||||
// When the language is change, we reload the menu bar strings and
|
||||
// relayout the whole main window.
|
||||
Strings::instance()->LanguageChange.connect(
|
||||
[this]{
|
||||
m_menuBar->reload();
|
||||
layout();
|
||||
invalidate();
|
||||
});
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
@ -207,14 +217,6 @@ CheckUpdateDelegate* MainWindow::getCheckUpdateDelegate()
|
||||
}
|
||||
#endif
|
||||
|
||||
void MainWindow::reloadMenus()
|
||||
{
|
||||
m_menuBar->reload();
|
||||
|
||||
layout();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void MainWindow::showNotification(INotificationDelegate* del)
|
||||
{
|
||||
m_notifications->addLink(del);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2017 David Capello
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -65,7 +65,6 @@ namespace app {
|
||||
#endif
|
||||
|
||||
void start();
|
||||
void reloadMenus();
|
||||
void showNotification(INotificationDelegate* del);
|
||||
void showHomeOnOpen();
|
||||
void showHome();
|
||||
|
Loading…
x
Reference in New Issue
Block a user