mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-13 05:57:00 -04:00
Added 'insert symbol' menu for SymbolFonts;
Added scriptable 'enabled' to symbols in symbol font, used instead of scripted filenames. This means changing the tap symbol style now works; Added localisation for games, stylesheets and symbolfonts; Warnings from Reader are now shown onIdle; git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@198 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -305,6 +305,38 @@ game:
|
|||||||
# Set info
|
# Set info
|
||||||
|
|
||||||
# descriptions/help text
|
# descriptions/help text
|
||||||
#stylesheet:
|
stylesheet:
|
||||||
# magic-new:
|
magic-new:
|
||||||
#
|
|
||||||
|
symbol font:
|
||||||
|
magic-mana-small:
|
||||||
|
menu item T: &Tap symbol T
|
||||||
|
menu item W: &White mana W
|
||||||
|
menu item U: Bl&ue mana U
|
||||||
|
menu item B: &Black mana B
|
||||||
|
menu item R: &Red mana R
|
||||||
|
menu item G: &Green mana G
|
||||||
|
menu item S: &Snow mana S
|
||||||
|
menu item X: Variable mana &X X
|
||||||
|
menu item Y: Variable mana &Y Y
|
||||||
|
menu item Z: Variable mana &Z Z
|
||||||
|
menu item colorless: &Colorless mana...
|
||||||
|
menu item half: &Half mana
|
||||||
|
menu item |W: &White |W
|
||||||
|
menu item |U: Bl&ue |U
|
||||||
|
menu item |B: &Black |B
|
||||||
|
menu item |R: &Red |R
|
||||||
|
menu item |G: &Green |G
|
||||||
|
menu item |S: &Snow |S
|
||||||
|
menu item 1/2: &Colorless 1/2
|
||||||
|
menu item hybrid: H&ybrid mana (two color)
|
||||||
|
menu item W/U: White/Blue mana W/U
|
||||||
|
menu item U/B: Blue/Black mana U/B
|
||||||
|
menu item B/R: Black/Ref mana B/R
|
||||||
|
menu item R/G: Red/Green mana R/G
|
||||||
|
menu item G/W: Green/White mana G/W
|
||||||
|
menu item W/B: White/Black mana W/B
|
||||||
|
menu item U/R: Blue/Red mana U/R
|
||||||
|
menu item B/G: Black/Green mana B/G
|
||||||
|
menu item R/W: Red/White mana R/W
|
||||||
|
menu item G/U: Green/blue mana G/U
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
mse version: 0.2.7
|
mse version: 0.3.0
|
||||||
# Symbol font in the 'popup' style, used for casting costs on modern cards
|
# Symbol font in the 'popup' style, used for casting costs on modern cards
|
||||||
|
|
||||||
image font size: 135
|
image font size: 135
|
||||||
@@ -7,7 +7,15 @@ symbol:
|
|||||||
image: mana_circle.png
|
image: mana_circle.png
|
||||||
symbol:
|
symbol:
|
||||||
code: T
|
code: T
|
||||||
image: script: mana_t()
|
image: mana_t_older.png
|
||||||
|
enabled: { mana_t() == "older" }
|
||||||
|
symbol:
|
||||||
|
code: T
|
||||||
|
image: mana_t_old.png
|
||||||
|
enabled: { mana_t() == "old" }
|
||||||
|
symbol:
|
||||||
|
code: T
|
||||||
|
image: mana_t.png
|
||||||
symbol:
|
symbol:
|
||||||
code: W/U
|
code: W/U
|
||||||
image: mana_wu.png
|
image: mana_wu.png
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
mse version: 0.2.7
|
mse version: 0.3.0
|
||||||
# Symbol font in the normal, flat, style, used for text boxes and on old style cards
|
# Symbol font in the normal, flat, style, used for text boxes and on old style cards
|
||||||
# Note:
|
# Note:
|
||||||
# Define small_mana_t:="mana_t(_old)?.png" in the init script of the style
|
# Define mana_t := {"new|old|older"} in the init script of the style
|
||||||
#
|
#
|
||||||
# So for example:
|
# So for example:
|
||||||
#
|
#
|
||||||
#init script:
|
#init script:
|
||||||
# small_mana_t := "mana_t.png"
|
# mana_t := {"new"}
|
||||||
|
|
||||||
image font size: 135
|
image font size: 135
|
||||||
horizontal space: 2
|
horizontal space: 2
|
||||||
@@ -14,7 +14,15 @@ symbol:
|
|||||||
image: mana_circle.png
|
image: mana_circle.png
|
||||||
symbol:
|
symbol:
|
||||||
code: T
|
code: T
|
||||||
image: { mana_t() }
|
image: mana_t_older.png
|
||||||
|
enabled: { mana_t() == "older" }
|
||||||
|
symbol:
|
||||||
|
code: T
|
||||||
|
image: mana_t_old.png
|
||||||
|
enabled: { mana_t() == "old" }
|
||||||
|
symbol:
|
||||||
|
code: T
|
||||||
|
image: mana_t.png
|
||||||
symbol:
|
symbol:
|
||||||
code: W/U
|
code: W/U
|
||||||
image: mana_wu.png
|
image: mana_wu.png
|
||||||
@@ -102,4 +110,50 @@ text font:
|
|||||||
text margin left: 3
|
text margin left: 3
|
||||||
text margin right: 2
|
text margin right: 2
|
||||||
text margin top: -1
|
text margin top: -1
|
||||||
text margin bottom: -1
|
text margin bottom: -1
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# Insert-symbol menu
|
||||||
|
insert symbol menu:
|
||||||
|
item: T
|
||||||
|
item:
|
||||||
|
type: line
|
||||||
|
item: X
|
||||||
|
item: Y
|
||||||
|
item: Z
|
||||||
|
item:
|
||||||
|
type: custom
|
||||||
|
name: colorless
|
||||||
|
item:
|
||||||
|
type: line
|
||||||
|
item: W
|
||||||
|
item: U
|
||||||
|
item: B
|
||||||
|
item: R
|
||||||
|
item: G
|
||||||
|
item: S
|
||||||
|
item:
|
||||||
|
type: line
|
||||||
|
item:
|
||||||
|
name: half
|
||||||
|
item: 1/2
|
||||||
|
item: |W
|
||||||
|
item: |U
|
||||||
|
item: |B
|
||||||
|
item: |R
|
||||||
|
item: |G
|
||||||
|
item: |S
|
||||||
|
item:
|
||||||
|
name: hybrid
|
||||||
|
item: W/U
|
||||||
|
item: U/B
|
||||||
|
item: B/R
|
||||||
|
item: R/G
|
||||||
|
item: G/W
|
||||||
|
item:
|
||||||
|
type: line
|
||||||
|
item: W/B
|
||||||
|
item: U/R
|
||||||
|
item: B/G
|
||||||
|
item: R/W
|
||||||
|
item: G/U
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ init script:
|
|||||||
land_template := { "acard.jpg" }
|
land_template := { "acard.jpg" }
|
||||||
|
|
||||||
# Use the normal tap symbol
|
# Use the normal tap symbol
|
||||||
mana_t := { "mana_t.png" }
|
mana_t := { "new" }
|
||||||
|
|
||||||
# Does the card have a color that requires a white font for copyright/artist?
|
# Does the card have a color that requires a white font for copyright/artist?
|
||||||
white_font_colors := filter_rule(match:"^(hybrid )?black|^land")
|
white_font_colors := filter_rule(match:"^(hybrid )?black|^land")
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ init script:
|
|||||||
|
|
||||||
# Use the normal tap symbol
|
# Use the normal tap symbol
|
||||||
mana_t := {
|
mana_t := {
|
||||||
if styling.tap_symbol == "old" then "mana_t_old.png"
|
if styling.tap_symbol == "old" then "old"
|
||||||
else if styling.tap_symbol == "diagonal T" then "mana_t_older.png"
|
else if styling.tap_symbol == "diagonal T" then "older"
|
||||||
else "mana_t.png"
|
else "new"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Does the card have a color that requires a white font for copyright/artist?
|
# Does the card have a color that requires a white font for copyright/artist?
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ init script:
|
|||||||
# Horizontal 5 color blends are not supported
|
# Horizontal 5 color blends are not supported
|
||||||
card_hybrid_5b := card_hybrid_5
|
card_hybrid_5b := card_hybrid_5
|
||||||
|
|
||||||
# Use the normal tap symbol
|
# Use the old tap symbol
|
||||||
mana_t := { "mana_t_old.png" }
|
mana_t := { "old" }
|
||||||
|
|
||||||
# Does the card have a color that requires a black font for copyright/artist?
|
# Does the card have a color that requires a black font for copyright/artist?
|
||||||
black_font_colors := filter_rule(match:"^(hybrid 2 color)?white")
|
black_font_colors := filter_rule(match:"^(hybrid 2 color)?white")
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ init script:
|
|||||||
# Horizontal 5 color blends are not supported
|
# Horizontal 5 color blends are not supported
|
||||||
card_hybrid_5b := card_hybrid_5
|
card_hybrid_5b := card_hybrid_5
|
||||||
|
|
||||||
# Use the normal tap symbol
|
# Use the old tap symbol
|
||||||
mana_t := { "mana_t_old.png" }
|
mana_t := { "old" }
|
||||||
|
|
||||||
# Does the card have a color that requires a black font for copyright/artist?
|
# Does the card have a color that requires a black font for copyright/artist?
|
||||||
black_font_colors := filter_rule(match:"^(hybrid 2 color)?white")
|
black_font_colors := filter_rule(match:"^(hybrid 2 color)?white")
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ init script:
|
|||||||
pt_template := { input + "pt.jpg" }
|
pt_template := { input + "pt.jpg" }
|
||||||
|
|
||||||
# Use the normal tap symbol
|
# Use the normal tap symbol
|
||||||
small_mana_t := "mana_t.png"
|
mana_t := { "new" }
|
||||||
|
|
||||||
# Does the card have a color that requires a white font for copyright/artist?
|
# Does the card have a color that requires a white font for copyright/artist?
|
||||||
white_font_colors := filter_rule(match:"^(hybrid 2 color)?black|^land")
|
white_font_colors := filter_rule(match:"^(hybrid 2 color)?black|^land")
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ icon: card-sample.png
|
|||||||
############################################################## Extra scripts
|
############################################################## Extra scripts
|
||||||
|
|
||||||
init script:
|
init script:
|
||||||
# Use the normal tap symbol
|
# Use the old tap symbol
|
||||||
small_mana_t := "mana_t.png"
|
mana_t := { "old" }
|
||||||
|
|
||||||
############################################################## Set info fields
|
############################################################## Set info fields
|
||||||
info style:
|
info style:
|
||||||
|
|||||||
@@ -21,8 +21,7 @@ IMPLEMENT_REFLECTION(KeywordMode) {
|
|||||||
REFLECT(description);
|
REFLECT(description);
|
||||||
}
|
}
|
||||||
IMPLEMENT_REFLECTION(KeywordExpansion) {
|
IMPLEMENT_REFLECTION(KeywordExpansion) {
|
||||||
REFLECT(before);
|
REFLECT(match);
|
||||||
REFLECT(after);
|
|
||||||
REFLECT(reminder);
|
REFLECT(reminder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,15 +35,17 @@ void read_compat(Reader& tag, Keyword* k) {
|
|||||||
if (!separator.empty() || !parameter.empty() || !reminder.empty()) {
|
if (!separator.empty() || !parameter.empty() || !reminder.empty()) {
|
||||||
// old style keyword declaration, no separate expansion
|
// old style keyword declaration, no separate expansion
|
||||||
KeywordExpansionP e(new KeywordExpansion);
|
KeywordExpansionP e(new KeywordExpansion);
|
||||||
|
e->match = k->keyword;
|
||||||
size_t start = separator.find_first_of('[');
|
size_t start = separator.find_first_of('[');
|
||||||
size_t end = separator.find_first_of(']');
|
size_t end = separator.find_first_of(']');
|
||||||
if (start != String::npos && end != String::npos) {
|
if (start != String::npos && end != String::npos) {
|
||||||
e->after += separator.substr(start + 1, end - start - 1);
|
e->match += separator.substr(start + 1, end - start - 1);
|
||||||
}
|
}
|
||||||
if (!parameter.empty()) {
|
if (!parameter.empty()) {
|
||||||
e->after += _("<param>") + parameter + _("</param>");
|
e->match += _("<param>") + parameter + _("</param>");
|
||||||
}
|
}
|
||||||
e->reminder.set(reminder);
|
e->reminder.set(reminder);
|
||||||
|
k->expansions.push_back(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,11 +46,11 @@ class KeywordMode {
|
|||||||
/// A way to use a keyword
|
/// A way to use a keyword
|
||||||
class KeywordExpansion {
|
class KeywordExpansion {
|
||||||
public:
|
public:
|
||||||
String before; ///< Components before the keyword: parameters and separators (tagged string)
|
String match; ///< String to match, <param> tags are used for parameters
|
||||||
String after; ///< Components after the keyword: parameters and separators
|
|
||||||
vector<KeywordParamP> parameters; ///< The types of parameters
|
vector<KeywordParamP> parameters; ///< The types of parameters
|
||||||
wxRegEx splitter; ///< Regular expression to split/match the components, automatically generated
|
// wxRegEx splitter; ///< Regular expression to split/match the components, automatically generated
|
||||||
StringScript reminder; ///< Reminder text of the keyword
|
StringScript reminder; ///< Reminder text of the keyword
|
||||||
|
String mode; ///< Mode of use, can be used by scripts (only gives the name). Default is the mode of the Keyword.
|
||||||
|
|
||||||
DECLARE_REFLECTION();
|
DECLARE_REFLECTION();
|
||||||
};
|
};
|
||||||
|
|||||||
+52
-4
@@ -7,6 +7,9 @@
|
|||||||
// ----------------------------------------------------------------------------- : Includes
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
#include <data/locale.hpp>
|
#include <data/locale.hpp>
|
||||||
|
#include <data/game.hpp>
|
||||||
|
#include <data/stylesheet.hpp>
|
||||||
|
#include <data/symbol_font.hpp>
|
||||||
#include <util/io/package_manager.hpp>
|
#include <util/io/package_manager.hpp>
|
||||||
#include <script/to_value.hpp>
|
#include <script/to_value.hpp>
|
||||||
|
|
||||||
@@ -32,19 +35,64 @@ IMPLEMENT_REFLECTION(Locale) {
|
|||||||
REFLECT_N("error", translations[LOCALE_CAT_ERROR]);
|
REFLECT_N("error", translations[LOCALE_CAT_ERROR]);
|
||||||
REFLECT_N("type", translations[LOCALE_CAT_TYPE]);
|
REFLECT_N("type", translations[LOCALE_CAT_TYPE]);
|
||||||
REFLECT_N("game", game_translations);
|
REFLECT_N("game", game_translations);
|
||||||
|
REFLECT_N("stylesheet", stylesheet_translations);
|
||||||
|
REFLECT_N("symbol font", symbol_font_translations);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_REFLECTION_NAMELESS(GameLocale) {
|
IMPLEMENT_REFLECTION_NAMELESS(SubLocale) {
|
||||||
REFLECT_NAMELESS(translations);
|
REFLECT_NAMELESS(translations);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Translation
|
// ----------------------------------------------------------------------------- : Translation
|
||||||
|
|
||||||
|
String SubLocale::tr(const String& key) {
|
||||||
|
map<String,String>::const_iterator it = translations.find(key);
|
||||||
|
if (it == translations.end()) {
|
||||||
|
return _("missing:") + key;
|
||||||
|
} else {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String SubLocale::tr(const String& key, const String& def) {
|
||||||
|
map<String,String>::const_iterator it = translations.find(key);
|
||||||
|
if (it == translations.end()) {
|
||||||
|
return def;
|
||||||
|
} else {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// from util/locale.hpp
|
// from util/locale.hpp
|
||||||
|
|
||||||
String tr(LocaleCategory cat, const String& key) {
|
String tr(LocaleCategory cat, const String& key) {
|
||||||
if (!the_locale) return key; // no locale loaded (yet)
|
if (!the_locale) return key; // no locale loaded (yet)
|
||||||
map<String,String>::const_iterator it = the_locale->translations[cat].find(key);
|
return the_locale->translations[cat].tr(key);
|
||||||
if (it == the_locale->translations[cat].end()) return _("missing:") + key;
|
}
|
||||||
return it->second;
|
|
||||||
|
|
||||||
|
String tr(const Game& g, const String& key) {
|
||||||
|
if (!the_locale) return key; // no locale loaded (yet)
|
||||||
|
return the_locale->game_translations[g.name()]->tr(key);
|
||||||
|
}
|
||||||
|
String tr(const StyleSheet& s, const String& key) {
|
||||||
|
if (!the_locale) return key; // no locale loaded (yet)
|
||||||
|
return the_locale->stylesheet_translations[s.name()]->tr(key);
|
||||||
|
}
|
||||||
|
String tr(const SymbolFont& f, const String& key) {
|
||||||
|
if (!the_locale) return key; // no locale loaded (yet)
|
||||||
|
return the_locale->symbol_font_translations[f.name()]->tr(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String tr(const Game& g, const String& key, const String& def) {
|
||||||
|
if (!the_locale) return key; // no locale loaded (yet)
|
||||||
|
return the_locale->game_translations[g.name()]->tr(key, def);
|
||||||
|
}
|
||||||
|
String tr(const StyleSheet& s, const String& key, const String& def) {
|
||||||
|
if (!the_locale) return key; // no locale loaded (yet)
|
||||||
|
return the_locale->stylesheet_translations[s.name()]->tr(key, def);
|
||||||
|
}
|
||||||
|
String tr(const SymbolFont& f, const String& key, const String& def) {
|
||||||
|
if (!the_locale) return key; // no locale loaded (yet)
|
||||||
|
return the_locale->symbol_font_translations[f.name()]->tr(key, def);
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-6
@@ -15,14 +15,20 @@
|
|||||||
#include <util/io/package.hpp>
|
#include <util/io/package.hpp>
|
||||||
|
|
||||||
DECLARE_POINTER_TYPE(Locale);
|
DECLARE_POINTER_TYPE(Locale);
|
||||||
DECLARE_POINTER_TYPE(GameLocale);
|
DECLARE_POINTER_TYPE(SubLocale);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Locale class
|
// ----------------------------------------------------------------------------- : Locale class
|
||||||
|
|
||||||
/// Translations of the texts of a game
|
/// Translations of the texts of a game/stylesheet/symbolfont
|
||||||
class GameLocale {
|
class SubLocale {
|
||||||
public:
|
public:
|
||||||
map<String,String> translations;
|
map<String,String> translations;
|
||||||
|
|
||||||
|
/// Translate a key
|
||||||
|
String tr(const String& key);
|
||||||
|
/// Translate a key with a default value
|
||||||
|
String tr(const String& key, const String& def);
|
||||||
|
|
||||||
DECLARE_REFLECTION();
|
DECLARE_REFLECTION();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -30,9 +36,13 @@ class GameLocale {
|
|||||||
class Locale : public Packaged {
|
class Locale : public Packaged {
|
||||||
public:
|
public:
|
||||||
/// Translations of UI strings in each category
|
/// Translations of UI strings in each category
|
||||||
map<String,String> translations[LOCALE_CAT_MAX];
|
SubLocale translations[LOCALE_CAT_MAX];
|
||||||
/// Translations of game specific texts, by game name
|
/// Translations of Game specific texts, by game name
|
||||||
map<String,GameLocaleP> game_translations;
|
map<String,SubLocaleP> game_translations;
|
||||||
|
/// Translations of StyleSheet specific texts, by stylesheet name
|
||||||
|
map<String,SubLocaleP> stylesheet_translations;
|
||||||
|
/// Translations of SymbolFont specific texts, by symbol font name
|
||||||
|
map<String,SubLocaleP> symbol_font_translations;
|
||||||
|
|
||||||
/// Open a locale with the given name
|
/// Open a locale with the given name
|
||||||
static LocaleP byName(const String& name);
|
static LocaleP byName(const String& name);
|
||||||
|
|||||||
+172
-9
@@ -10,12 +10,14 @@
|
|||||||
#include <util/dynamic_arg.hpp>
|
#include <util/dynamic_arg.hpp>
|
||||||
#include <util/io/package_manager.hpp>
|
#include <util/io/package_manager.hpp>
|
||||||
#include <util/rotation.hpp>
|
#include <util/rotation.hpp>
|
||||||
|
#include <util/error.hpp>
|
||||||
|
#include <util/window_id.hpp>
|
||||||
#include <render/text/element.hpp> // fot CharInfo
|
#include <render/text/element.hpp> // fot CharInfo
|
||||||
#include <script/image.hpp>
|
#include <script/image.hpp>
|
||||||
#include <util/error.hpp>
|
|
||||||
|
|
||||||
DECLARE_TYPEOF_COLLECTION(SymbolFont::DrawableSymbol);
|
DECLARE_TYPEOF_COLLECTION(SymbolFont::DrawableSymbol);
|
||||||
DECLARE_TYPEOF_COLLECTION(SymbolInFontP);
|
DECLARE_TYPEOF_COLLECTION(SymbolInFontP);
|
||||||
|
DECLARE_TYPEOF_COLLECTION(InsertSymbolMenuP);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : SymbolFont
|
// ----------------------------------------------------------------------------- : SymbolFont
|
||||||
|
|
||||||
@@ -31,8 +33,13 @@ SymbolFont::SymbolFont()
|
|||||||
, text_margin_top(0), text_margin_bottom(0)
|
, text_margin_top(0), text_margin_bottom(0)
|
||||||
, text_alignment(ALIGN_MIDDLE_CENTER)
|
, text_alignment(ALIGN_MIDDLE_CENTER)
|
||||||
, merge_numbers(false)
|
, merge_numbers(false)
|
||||||
|
, processed_insert_symbol_menu(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
SymbolFont::~SymbolFont() {
|
||||||
|
delete processed_insert_symbol_menu;
|
||||||
|
}
|
||||||
|
|
||||||
String SymbolFont::typeNameStatic() { return _("symbol-font"); }
|
String SymbolFont::typeNameStatic() { return _("symbol-font"); }
|
||||||
String SymbolFont::typeName() const { return _("symbol-font"); }
|
String SymbolFont::typeName() const { return _("symbol-font"); }
|
||||||
|
|
||||||
@@ -57,6 +64,7 @@ IMPLEMENT_REFLECTION(SymbolFont) {
|
|||||||
REFLECT(text_margin_top);
|
REFLECT(text_margin_top);
|
||||||
REFLECT(text_margin_bottom);
|
REFLECT(text_margin_bottom);
|
||||||
REFLECT(text_alignment);
|
REFLECT(text_alignment);
|
||||||
|
REFLECT(insert_symbol_menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : SymbolInFont
|
// ----------------------------------------------------------------------------- : SymbolInFont
|
||||||
@@ -69,15 +77,21 @@ class SymbolInFont {
|
|||||||
/// Get a shrunk, zoomed bitmap
|
/// Get a shrunk, zoomed bitmap
|
||||||
Bitmap getBitmap(Context& ctx, Package& pkg, double size);
|
Bitmap getBitmap(Context& ctx, Package& pkg, double size);
|
||||||
|
|
||||||
|
/// Get a bitmap with the given size
|
||||||
|
Bitmap getBitmap(Context& ctx, Package& pkg, wxSize size);
|
||||||
|
|
||||||
/// Size of a (zoomed) bitmap
|
/// Size of a (zoomed) bitmap
|
||||||
/** This is the size of the resulting image, it does NOT convert back to internal coordinates */
|
/** This is the size of the resulting image, it does NOT convert back to internal coordinates */
|
||||||
RealSize size(Context& ctx, Package& pkg, double size);
|
RealSize size(Context& ctx, Package& pkg, double size);
|
||||||
|
|
||||||
String code; ///< Code for this symbol
|
void update(Context& ctx);
|
||||||
|
|
||||||
|
String code; ///< Code for this symbol
|
||||||
|
Scriptable<bool> enabled; ///< Is this symbol enabled?
|
||||||
private:
|
private:
|
||||||
ScriptableImage image; ///< The image for this symbol
|
ScriptableImage image; ///< The image for this symbol
|
||||||
double img_size; ///< Font size used by the image
|
double img_size; ///< Font size used by the image
|
||||||
wxSize actual_size; ///< Actual image size, only known after loading the image
|
wxSize actual_size; ///< Actual image size, only known after loading the image
|
||||||
/// Cached bitmaps for different sizes
|
/// Cached bitmaps for different sizes
|
||||||
map<double, Bitmap> bitmaps;
|
map<double, Bitmap> bitmaps;
|
||||||
|
|
||||||
@@ -86,6 +100,7 @@ class SymbolInFont {
|
|||||||
|
|
||||||
SymbolInFont::SymbolInFont()
|
SymbolInFont::SymbolInFont()
|
||||||
: actual_size(0,0)
|
: actual_size(0,0)
|
||||||
|
, enabled(true)
|
||||||
{
|
{
|
||||||
assert(symbol_font_for_reading());
|
assert(symbol_font_for_reading());
|
||||||
img_size = symbol_font_for_reading()->img_size;
|
img_size = symbol_font_for_reading()->img_size;
|
||||||
@@ -112,6 +127,18 @@ Bitmap SymbolInFont::getBitmap(Context& ctx, Package& pkg, double size) {
|
|||||||
}
|
}
|
||||||
return bmp;
|
return bmp;
|
||||||
}
|
}
|
||||||
|
Bitmap SymbolInFont::getBitmap(Context& ctx, Package& pkg, wxSize size) {
|
||||||
|
// generate new bitmap
|
||||||
|
if (!image) {
|
||||||
|
throw Error(_("No image specified for symbol with code '") + code + _("' in symbol font."));
|
||||||
|
}
|
||||||
|
Image img = image.generate(ctx, pkg)->image;
|
||||||
|
actual_size = wxSize(img.GetWidth(), img.GetHeight());
|
||||||
|
// scale to match expected size
|
||||||
|
Image resampled_image(size.GetWidth(), size.GetHeight(), false);
|
||||||
|
resample_preserve_aspect(img, resampled_image);
|
||||||
|
return Bitmap(resampled_image);
|
||||||
|
}
|
||||||
|
|
||||||
RealSize SymbolInFont::size(Context& ctx, Package& pkg, double size) {
|
RealSize SymbolInFont::size(Context& ctx, Package& pkg, double size) {
|
||||||
if (actual_size.GetWidth() == 0) {
|
if (actual_size.GetWidth() == 0) {
|
||||||
@@ -121,9 +148,14 @@ RealSize SymbolInFont::size(Context& ctx, Package& pkg, double size) {
|
|||||||
return wxSize(actual_size * size / img_size);
|
return wxSize(actual_size * size / img_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SymbolInFont::update(Context& ctx) {
|
||||||
|
enabled.update(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
IMPLEMENT_REFLECTION(SymbolInFont) {
|
IMPLEMENT_REFLECTION(SymbolInFont) {
|
||||||
REFLECT(code);
|
REFLECT(code);
|
||||||
REFLECT(image);
|
REFLECT(image);
|
||||||
|
REFLECT(enabled);
|
||||||
REFLECT_N("image font size", img_size);
|
REFLECT_N("image font size", img_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +171,11 @@ class SymbolFont::DrawableSymbol {
|
|||||||
SymbolInFont* symbol; ///< Symbol to draw, if nullptr, use the default symbol and draw the text
|
SymbolInFont* symbol; ///< Symbol to draw, if nullptr, use the default symbol and draw the text
|
||||||
};
|
};
|
||||||
|
|
||||||
void SymbolFont::split(const String& text, SplitSymbols& out) const {
|
void SymbolFont::split(const String& text, Context& ctx, SplitSymbols& out) const {
|
||||||
|
// update all symbol-in-fonts
|
||||||
|
FOR_EACH_CONST(sym, symbols) {
|
||||||
|
sym->update(ctx);
|
||||||
|
}
|
||||||
// read a single symbol until we are done with the text
|
// read a single symbol until we are done with the text
|
||||||
for (size_t pos = 0 ; pos < text.size() ; ) {
|
for (size_t pos = 0 ; pos < text.size() ; ) {
|
||||||
// 1. check merged numbers
|
// 1. check merged numbers
|
||||||
@@ -154,7 +190,7 @@ void SymbolFont::split(const String& text, SplitSymbols& out) const {
|
|||||||
}
|
}
|
||||||
// 2. check symbol list
|
// 2. check symbol list
|
||||||
FOR_EACH_CONST(sym, symbols) {
|
FOR_EACH_CONST(sym, symbols) {
|
||||||
if (!sym->code.empty() && is_substr(text, pos, sym->code)) { // symbol matches
|
if (!sym->code.empty() && sym->enabled && is_substr(text, pos, sym->code)) { // symbol matches
|
||||||
out.push_back(DrawableSymbol(sym->code, sym.get()));
|
out.push_back(DrawableSymbol(sym->code, sym.get()));
|
||||||
pos += sym->code.size();
|
pos += sym->code.size();
|
||||||
goto next_symbol; // continue two levels
|
goto next_symbol; // continue two levels
|
||||||
@@ -178,7 +214,7 @@ SymbolInFont* SymbolFont::defaultSymbol() const {
|
|||||||
|
|
||||||
void SymbolFont::draw(RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, const String& text) {
|
void SymbolFont::draw(RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, const String& text) {
|
||||||
SplitSymbols symbols;
|
SplitSymbols symbols;
|
||||||
split(text, symbols);
|
split(text, ctx, symbols);
|
||||||
draw(dc, ctx, rect, font_size, align, symbols);
|
draw(dc, ctx, rect, font_size, align, symbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,7 +289,7 @@ void SymbolFont::drawWithText(RotatedDC& dc, Context& ctx, const RealRect& rect,
|
|||||||
|
|
||||||
void SymbolFont::getCharInfo(RotatedDC& dc, Context& ctx, double font_size, const String& text, vector<CharInfo>& out) {
|
void SymbolFont::getCharInfo(RotatedDC& dc, Context& ctx, double font_size, const String& text, vector<CharInfo>& out) {
|
||||||
SplitSymbols symbols;
|
SplitSymbols symbols;
|
||||||
split(text, symbols);
|
split(text, ctx, symbols);
|
||||||
getCharInfo(dc, ctx, font_size, symbols, out);
|
getCharInfo(dc, ctx, font_size, symbols, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,6 +319,133 @@ RealSize SymbolFont::defaultSymbolSize(Context& ctx, double font_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : InsertSymbolMenu
|
||||||
|
|
||||||
|
wxMenu* SymbolFont::insertSymbolMenu(Context& ctx) {
|
||||||
|
if (!processed_insert_symbol_menu && insert_symbol_menu) {
|
||||||
|
// Make menu
|
||||||
|
processed_insert_symbol_menu = insert_symbol_menu->makeMenu(ID_INSERT_SYMBOL_MENU_MIN, ctx, *this);
|
||||||
|
}
|
||||||
|
return processed_insert_symbol_menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
String SymbolFont::insertSymbolCode(int menu_id) const {
|
||||||
|
// find item
|
||||||
|
if (insert_symbol_menu) {
|
||||||
|
return insert_symbol_menu->getCode(menu_id - ID_INSERT_SYMBOL_MENU_MIN, *this);
|
||||||
|
} else {
|
||||||
|
return wxEmptyString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
InsertSymbolMenu::InsertSymbolMenu()
|
||||||
|
: type(ITEM_CODE)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int InsertSymbolMenu::size() const {
|
||||||
|
if (type == ITEM_CODE || type == ITEM_CUSTOM) {
|
||||||
|
return 1;
|
||||||
|
} else if (type == ITEM_SUBMENU) {
|
||||||
|
int count = 0;
|
||||||
|
FOR_EACH_CONST(i, items) {
|
||||||
|
count += i->size();
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String InsertSymbolMenu::getCode(int id, const SymbolFont& font) const {
|
||||||
|
if (type == ITEM_SUBMENU) {
|
||||||
|
FOR_EACH_CONST(i, items) {
|
||||||
|
int id2 = id - i->size();
|
||||||
|
if (id2 < 0) {
|
||||||
|
return i->getCode(id, font);
|
||||||
|
}
|
||||||
|
id = id2;
|
||||||
|
}
|
||||||
|
} else if (id == 0 && type == ITEM_CODE) {
|
||||||
|
return name;
|
||||||
|
} else if (id == 0 && type == ITEM_CUSTOM) {
|
||||||
|
String message = tr(font,name,name);
|
||||||
|
return wxGetTextFromUser(message, message);
|
||||||
|
}
|
||||||
|
return wxEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxMenu* InsertSymbolMenu::makeMenu(int id, Context& ctx, SymbolFont& font) const {
|
||||||
|
if (type == ITEM_SUBMENU) {
|
||||||
|
wxMenu* menu = new wxMenu();
|
||||||
|
FOR_EACH_CONST(i, items) {
|
||||||
|
menu->Append(i->makeMenuItem(menu, id, ctx, font));
|
||||||
|
id += i->size();
|
||||||
|
}
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
wxMenuItem* InsertSymbolMenu::makeMenuItem(wxMenu* parent, int first_id, Context& ctx, SymbolFont& font) const {
|
||||||
|
if (type == ITEM_SUBMENU) {
|
||||||
|
wxMenuItem* item = new wxMenuItem(parent, wxID_ANY, tr(font, _("menu item ") + name, name),
|
||||||
|
wxEmptyString, wxITEM_NORMAL,
|
||||||
|
makeMenu(first_id, ctx, font));
|
||||||
|
item->SetBitmap(wxNullBitmap);
|
||||||
|
return item;
|
||||||
|
} else if (type == ITEM_LINE) {
|
||||||
|
wxMenuItem* item = new wxMenuItem(parent, wxID_SEPARATOR);
|
||||||
|
return item;
|
||||||
|
} else {
|
||||||
|
wxMenuItem* item = new wxMenuItem(parent, first_id, tr(font, _("menu item ") + name, name));
|
||||||
|
// Generate bitmap for use on this item
|
||||||
|
SymbolInFont* symbol = nullptr;
|
||||||
|
if (type == ITEM_CUSTOM) {
|
||||||
|
symbol = font.defaultSymbol();
|
||||||
|
} else {
|
||||||
|
FOR_EACH(sym, font.symbols) {
|
||||||
|
if (!sym->code.empty() && sym->enabled && name == sym->code) {
|
||||||
|
symbol = sym.get();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (symbol) {
|
||||||
|
item->SetBitmap(symbol->getBitmap(ctx, font, wxSize(16,16)));
|
||||||
|
} else {
|
||||||
|
item->SetBitmap(wxNullBitmap);
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IMPLEMENT_REFLECTION_ENUM(MenuItemType) {
|
||||||
|
VALUE_N("code", ITEM_CODE);
|
||||||
|
VALUE_N("custom", ITEM_CUSTOM);
|
||||||
|
VALUE_N("line", ITEM_LINE);
|
||||||
|
VALUE_N("submenu", ITEM_SUBMENU);
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_REFLECTION_NO_GET_MEMBER(InsertSymbolMenu) {
|
||||||
|
if (!items.empty() || (tag.reading() && tag.isComplex())) {
|
||||||
|
// complex values are groups
|
||||||
|
REFLECT(type);
|
||||||
|
REFLECT(name);
|
||||||
|
REFLECT(items);
|
||||||
|
if (!items.empty()) type = ITEM_SUBMENU;
|
||||||
|
} else {
|
||||||
|
REFLECT_NAMELESS(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <> void GetDefaultMember::handle(const InsertSymbolMenu& m) {
|
||||||
|
handle(m.name);
|
||||||
|
}
|
||||||
|
template <> void GetMember::handle(const InsertSymbolMenu& m) {
|
||||||
|
handle(_("type"), m.type);
|
||||||
|
handle(_("name"), m.name);
|
||||||
|
handle(_("items"), m.items);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : SymbolFontRef
|
// ----------------------------------------------------------------------------- : SymbolFontRef
|
||||||
|
|
||||||
SymbolFontRef::SymbolFontRef()
|
SymbolFontRef::SymbolFontRef()
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
DECLARE_POINTER_TYPE(Font);
|
DECLARE_POINTER_TYPE(Font);
|
||||||
DECLARE_POINTER_TYPE(SymbolFont);
|
DECLARE_POINTER_TYPE(SymbolFont);
|
||||||
DECLARE_POINTER_TYPE(SymbolInFont);
|
DECLARE_POINTER_TYPE(SymbolInFont);
|
||||||
|
DECLARE_POINTER_TYPE(InsertSymbolMenu);
|
||||||
class RotatedDC;
|
class RotatedDC;
|
||||||
struct CharInfo;
|
struct CharInfo;
|
||||||
|
|
||||||
@@ -26,6 +27,7 @@ struct CharInfo;
|
|||||||
class SymbolFont : public Packaged {
|
class SymbolFont : public Packaged {
|
||||||
public:
|
public:
|
||||||
SymbolFont();
|
SymbolFont();
|
||||||
|
~SymbolFont();
|
||||||
|
|
||||||
/// Loads the symbol font with a given name, for example "magic-mana-large"
|
/// Loads the symbol font with a given name, for example "magic-mana-large"
|
||||||
static SymbolFontP byName(const String& name);
|
static SymbolFontP byName(const String& name);
|
||||||
@@ -33,7 +35,7 @@ class SymbolFont : public Packaged {
|
|||||||
class DrawableSymbol;
|
class DrawableSymbol;
|
||||||
typedef vector<DrawableSymbol> SplitSymbols;
|
typedef vector<DrawableSymbol> SplitSymbols;
|
||||||
/// Split a string into separate symbols for drawing and for determining their size
|
/// Split a string into separate symbols for drawing and for determining their size
|
||||||
void split(const String& text, SplitSymbols& out) const;
|
void split(const String& text, Context& ctx, SplitSymbols& out) const;
|
||||||
|
|
||||||
/// Draw a piece of text prepared using split
|
/// Draw a piece of text prepared using split
|
||||||
void draw(RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, const String& text);
|
void draw(RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, const String& text);
|
||||||
@@ -48,6 +50,16 @@ class SymbolFont : public Packaged {
|
|||||||
static String typeNameStatic();
|
static String typeNameStatic();
|
||||||
virtual String typeName() const;
|
virtual String typeName() const;
|
||||||
|
|
||||||
|
/// Generate a 'insert symbol' menu.
|
||||||
|
/** This class owns the menu!
|
||||||
|
* All ids used will be in the range ID_INSERT_SYMBOL_MENU_MIN...ID_INSERT_SYMBOL_MENU_MAX.
|
||||||
|
* If there is no insert symbol menu, returns nullptr.
|
||||||
|
*/
|
||||||
|
wxMenu* insertSymbolMenu(Context& ctx);
|
||||||
|
/// Process a choice from the insert symbol menu
|
||||||
|
/** Return the code representing the symbol */
|
||||||
|
String insertSymbolCode(int menu_id) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UInt img_size; ///< Font size that the images use
|
UInt img_size; ///< Font size that the images use
|
||||||
UInt min_size; ///< Minimum font size
|
UInt min_size; ///< Minimum font size
|
||||||
@@ -61,8 +73,11 @@ class SymbolFont : public Packaged {
|
|||||||
double text_margin_bottom;
|
double text_margin_bottom;
|
||||||
Alignment text_alignment;
|
Alignment text_alignment;
|
||||||
bool merge_numbers; ///< Merge numbers? e.g. "11" is a single symbol ('1' must not exist as a symbol)
|
bool merge_numbers; ///< Merge numbers? e.g. "11" is a single symbol ('1' must not exist as a symbol)
|
||||||
|
InsertSymbolMenuP insert_symbol_menu;
|
||||||
|
wxMenu* processed_insert_symbol_menu;
|
||||||
|
|
||||||
friend class SymbolInFont;
|
friend class SymbolInFont;
|
||||||
|
friend class InsertSymbolMenu;
|
||||||
vector<SymbolInFontP> symbols; ///< The individual symbols
|
vector<SymbolInFontP> symbols; ///< The individual symbols
|
||||||
|
|
||||||
/// Find the default symbol
|
/// Find the default symbol
|
||||||
@@ -83,6 +98,35 @@ class SymbolFont : public Packaged {
|
|||||||
DECLARE_REFLECTION();
|
DECLARE_REFLECTION();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : InsertSymbolMenu
|
||||||
|
|
||||||
|
enum MenuItemType
|
||||||
|
{ ITEM_CODE ///< Name gives the code to insert
|
||||||
|
, ITEM_CUSTOM ///< Use a dialog box
|
||||||
|
, ITEM_LINE ///< A menu separator
|
||||||
|
, ITEM_SUBMENU ///< A submenu
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Description of a menu to insert symbols from a symbol font into the text
|
||||||
|
class InsertSymbolMenu {
|
||||||
|
public:
|
||||||
|
InsertSymbolMenu();
|
||||||
|
|
||||||
|
MenuItemType type;
|
||||||
|
String name;
|
||||||
|
vector<InsertSymbolMenuP> items;
|
||||||
|
|
||||||
|
/// Number of ids used (recursive)
|
||||||
|
int size() const;
|
||||||
|
/// Get the code for an item, id relative to the start of this menu
|
||||||
|
String getCode(int id, const SymbolFont& font) const;
|
||||||
|
/// Make an actual menu
|
||||||
|
wxMenu* makeMenu(int first_id, Context& ctx, SymbolFont& font) const;
|
||||||
|
/// Make an actual menu item
|
||||||
|
wxMenuItem* makeMenuItem(wxMenu* parent, int first_id, Context& ctx, SymbolFont& font) const;
|
||||||
|
|
||||||
|
DECLARE_REFLECTION();
|
||||||
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : SymbolFontRef
|
// ----------------------------------------------------------------------------- : SymbolFontRef
|
||||||
|
|
||||||
|
|||||||
@@ -143,6 +143,20 @@ void DataEditor::doCopy() { if (current_editor) current_ed
|
|||||||
void DataEditor::doPaste() { if (current_editor) current_editor->doPaste(); }
|
void DataEditor::doPaste() { if (current_editor) current_editor->doPaste(); }
|
||||||
void DataEditor::doFormat(int type) { if (current_editor) current_editor->doFormat(type); }
|
void DataEditor::doFormat(int type) { if (current_editor) current_editor->doFormat(type); }
|
||||||
|
|
||||||
|
|
||||||
|
wxMenu* DataEditor::getMenu(int type) const {
|
||||||
|
if (current_editor) {
|
||||||
|
return current_editor->getMenu(type);
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void DataEditor::onCommand(int id) {
|
||||||
|
if (current_editor) {
|
||||||
|
current_editor->onCommand(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Mouse events
|
// ----------------------------------------------------------------------------- : Mouse events
|
||||||
|
|
||||||
void DataEditor::onLeftDown(wxMouseEvent& ev) {
|
void DataEditor::onLeftDown(wxMouseEvent& ev) {
|
||||||
@@ -274,7 +288,9 @@ void DataEditor::onContextMenu(wxContextMenuEvent& ev) {
|
|||||||
}
|
}
|
||||||
void DataEditor::onMenu(wxCommandEvent& ev) {
|
void DataEditor::onMenu(wxCommandEvent& ev) {
|
||||||
if (current_editor) {
|
if (current_editor) {
|
||||||
current_editor->onMenu(ev);
|
if (!current_editor->onCommand(ev.GetId())) {
|
||||||
|
ev.Skip();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ev.Skip();
|
ev.Skip();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ class DataEditor : public CardViewer {
|
|||||||
bool canFormat(int type) const;
|
bool canFormat(int type) const;
|
||||||
bool hasFormat(int type) const;
|
bool hasFormat(int type) const;
|
||||||
void doFormat (int type);
|
void doFormat (int type);
|
||||||
|
/// Get a special menu, events should be sent to onCommand
|
||||||
|
wxMenu* getMenu(int type) const;
|
||||||
|
/// A menu item from getMenu was selected
|
||||||
|
void onCommand(int id);
|
||||||
|
|
||||||
// --------------------------------------------------- : ValueViewers
|
// --------------------------------------------------- : ValueViewers
|
||||||
|
|
||||||
|
|||||||
@@ -282,7 +282,9 @@ void CardListBase::rebuild() {
|
|||||||
if (f.second->card_list_align & ALIGN_RIGHT) align = wxLIST_FORMAT_RIGHT;
|
if (f.second->card_list_align & ALIGN_RIGHT) align = wxLIST_FORMAT_RIGHT;
|
||||||
else if (f.second->card_list_align & ALIGN_CENTER) align = wxLIST_FORMAT_CENTRE;
|
else if (f.second->card_list_align & ALIGN_CENTER) align = wxLIST_FORMAT_CENTRE;
|
||||||
else align = wxLIST_FORMAT_LEFT;
|
else align = wxLIST_FORMAT_LEFT;
|
||||||
InsertColumn((long)column_fields.size(), capitalize(f.second->card_list_name), align, cs.width);
|
InsertColumn((long)column_fields.size(),
|
||||||
|
tr(*set->game, f.second->card_list_name, capitalize(f.second->card_list_name)),
|
||||||
|
align, cs.width);
|
||||||
column_fields.push_back(f.second);
|
column_fields.push_back(f.second);
|
||||||
}
|
}
|
||||||
// find field that determines color
|
// find field that determines color
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ void CardListColumnSelectDialog::initList() {
|
|||||||
// Init items
|
// Init items
|
||||||
Color window_color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
|
Color window_color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
|
||||||
FOR_EACH(c, columns) {
|
FOR_EACH(c, columns) {
|
||||||
list->Append(capitalize(c.field->card_list_name));
|
list->Append(tr(*game, c.field->card_list_name, capitalize(c.field->card_list_name)));
|
||||||
// check
|
// check
|
||||||
int i = list->GetCount() - 1;
|
int i = list->GetCount() - 1;
|
||||||
list->Check(i, c.settings.visible);
|
list->Check(i, c.settings.visible);
|
||||||
@@ -88,7 +88,7 @@ void CardListColumnSelectDialog::initList() {
|
|||||||
|
|
||||||
void CardListColumnSelectDialog::refreshItem(int i) {
|
void CardListColumnSelectDialog::refreshItem(int i) {
|
||||||
list->Check (i, columns[i].settings.visible);
|
list->Check (i, columns[i].settings.visible);
|
||||||
list->SetString(i, capitalize(columns[i].field->card_list_name));
|
list->SetString(i, tr(*game, columns[i].field->card_list_name, capitalize(columns[i].field->card_list_name)) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Events
|
// ----------------------------------------------------------------------------- : Events
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ void NativeLookEditor::drawViewer(RotatedDC& dc, ValueViewer& v) {
|
|||||||
dc.DrawRectangle(s.getRect().grow(1));
|
dc.DrawRectangle(s.getRect().grow(1));
|
||||||
// draw label
|
// draw label
|
||||||
dc.SetFont(*wxNORMAL_FONT);
|
dc.SetFont(*wxNORMAL_FONT);
|
||||||
dc.DrawText(capitalize_sentence(s.fieldP->name), RealPoint(margin_left, s.top + 1));
|
// TODO : tr using stylesheet or using game?
|
||||||
|
dc.DrawText(tr(*set->game, s.fieldP->name, capitalize_sentence(s.fieldP->name)),
|
||||||
|
RealPoint(margin_left, s.top + 1));
|
||||||
// draw 3D border
|
// draw 3D border
|
||||||
draw_control_border(this, dc.getDC(), RealRect(s.left - 1, s.top - 1, s.width + 2, s.height + 2));
|
draw_control_border(this, dc.getDC(), RealRect(s.left - 1, s.top - 1, s.width + 2, s.height + 2));
|
||||||
// draw viewer
|
// draw viewer
|
||||||
|
|||||||
@@ -77,6 +77,11 @@ void IconMenu::Append(int id, const String& text, const String& help, wxMenu* su
|
|||||||
wxMenu::Append(item);
|
wxMenu::Append(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IconMenu::Append(wxMenuItem* item) {
|
||||||
|
item->SetBitmap(wxNullBitmap);
|
||||||
|
wxMenu::Append(item);
|
||||||
|
}
|
||||||
|
|
||||||
void IconMenu::Insert(size_t pos, int id, const String& text, const String& help) {
|
void IconMenu::Insert(size_t pos, int id, const String& text, const String& help) {
|
||||||
wxMenuItem* item = new wxMenuItem (this, id, text, help);
|
wxMenuItem* item = new wxMenuItem (this, id, text, help);
|
||||||
item->SetBitmap(wxNullBitmap);
|
item->SetBitmap(wxNullBitmap);
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ class IconMenu : public wxMenu {
|
|||||||
void Append(int id, const String& text, const String& help);
|
void Append(int id, const String& text, const String& help);
|
||||||
/// Append a menu item, without an image
|
/// Append a menu item, without an image
|
||||||
void Append(int id, const String& text, const String& help, wxMenu* submenu);
|
void Append(int id, const String& text, const String& help, wxMenu* submenu);
|
||||||
|
/// Append a menu item, without an image
|
||||||
|
void Append(wxMenuItem* item);
|
||||||
/// Insert a menu item, without an image
|
/// Insert a menu item, without an image
|
||||||
void Insert(size_t pos, int id, const String& text, const String& help);
|
void Insert(size_t pos, int id, const String& text, const String& help);
|
||||||
};
|
};
|
||||||
|
|||||||
+57
-27
@@ -47,10 +47,49 @@ CardsPanel::CardsPanel(Window* parent, int id)
|
|||||||
s->Add(splitter, 1, wxEXPAND);
|
s->Add(splitter, 1, wxEXPAND);
|
||||||
s->SetSizeHints(this);
|
s->SetSizeHints(this);
|
||||||
SetSizer(s);
|
SetSizer(s);
|
||||||
|
|
||||||
|
// init menus
|
||||||
|
menuCard = new IconMenu();
|
||||||
|
menuCard->Append(ID_CARD_PREV, _("Select &Previous Card\tPgUp"), _("Selects the previous card in the list"));
|
||||||
|
menuCard->Append(ID_CARD_NEXT, _("Select &Next Card\tPgDn"), _("Selects the next card in the list"));
|
||||||
|
menuCard->AppendSeparator();
|
||||||
|
menuCard->Append(ID_CARD_ADD, _("card_add"), _("&Add Card\tCtrl++"), _("Add a new, blank, card to this set"));
|
||||||
|
menuCard->Append(ID_CARD_ADD_MULT, _("card_add_multiple"), _("Add &Multiple Cards..."), _("Add multiple cards to the set"));
|
||||||
|
// NOTE: space after "Del" prevents wx from making del an accellerator
|
||||||
|
// otherwise we delete a card when delete is pressed inside the editor
|
||||||
|
menuCard->Append(ID_CARD_REMOVE, _("card_del"), _("&Remove Select Card\tDel "), _("Delete the selected card from this set"));
|
||||||
|
menuCard->AppendSeparator();
|
||||||
|
IconMenu* menuRotate = new IconMenu();
|
||||||
|
menuRotate->Append(ID_CARD_ROTATE_0, _("card_rotate_0"), _("&Normal"), _("Display the card with the right side up"), wxITEM_CHECK);
|
||||||
|
menuRotate->Append(ID_CARD_ROTATE_270, _("card_rotate_270"), _("Rotated 90 &Clockwise"), _("Display the card rotated clockwise"), wxITEM_CHECK);
|
||||||
|
menuRotate->Append(ID_CARD_ROTATE_90, _("card_rotate_90"), _("Rotated 90 C&ounter Clockwise"), _("Display the card rotated counter-clockwise (anti-clockwise for the British)"), wxITEM_CHECK);
|
||||||
|
menuRotate->Append(ID_CARD_ROTATE_180, _("card_rotate_180"), _("Rotated 180, &Up Side Down"), _("Display the card up side down"), wxITEM_CHECK);
|
||||||
|
menuCard->Append(wxID_ANY, _("card_rotate"), _("&Orientation"), _("Orientation of the card display"), wxITEM_NORMAL, menuRotate);
|
||||||
|
menuCard->AppendSeparator();
|
||||||
|
// This probably belongs in the window menu, but there we can't remove the separator once it is added
|
||||||
|
menuCard->Append(ID_SELECT_COLUMNS, _("C&ard List Columns..."), _("Select what columns should be shown and in what order."));
|
||||||
|
|
||||||
|
menuFormat = new IconMenu();
|
||||||
|
menuFormat->Append(ID_FORMAT_BOLD, _("bold"), _("Bold\tCtrl+B"), _("Makes the selected text bold"), wxITEM_CHECK);
|
||||||
|
menuFormat->Append(ID_FORMAT_ITALIC, _("italic"), _("Italic\tCtrl+I"), _("Makes the selected text italic"), wxITEM_CHECK);
|
||||||
|
menuFormat->Append(ID_FORMAT_SYMBOL, _("symbol"), _("Symbols\tCtrl+M"), _("Draws the selected text with symbols"), wxITEM_CHECK);
|
||||||
|
menuFormat->Append(ID_FORMAT_REMINDER, _("reminder"), _("Reminder Text\tCtrl+R"), _("Show reminder text for the selected keyword"), wxITEM_CHECK);
|
||||||
|
menuFormat->AppendSeparator();
|
||||||
|
insertSymbolMenu = new wxMenuItem(menuFormat, ID_INSERT_SYMBOL, _("Insert Symbol"));
|
||||||
|
menuFormat->Append(insertSymbolMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
CardsPanel::~CardsPanel() {
|
CardsPanel::~CardsPanel() {
|
||||||
// settings.card_notes_height = splitter->GetSashPosition();
|
// settings.card_notes_height = splitter->GetSashPosition();
|
||||||
|
// we don't own the submenu
|
||||||
|
wxMenu* menu = insertSymbolMenu->GetSubMenu();
|
||||||
|
if (menu && menu->GetParent() == menuFormat) {
|
||||||
|
menu->SetParent(nullptr);
|
||||||
|
}
|
||||||
|
insertSymbolMenu->SetSubMenu(nullptr);
|
||||||
|
// delete menus
|
||||||
|
delete menuCard;
|
||||||
|
delete menuFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardsPanel::onChangeSet() {
|
void CardsPanel::onChangeSet() {
|
||||||
@@ -78,32 +117,7 @@ void CardsPanel::initUI(wxToolBar* tb, wxMenuBar* mb) {
|
|||||||
tb->AddTool(ID_CARD_ROTATE, _(""), load_resource_tool_image(_("card_rotate")), wxNullBitmap,wxITEM_NORMAL,_TOOL_("rotate card"));
|
tb->AddTool(ID_CARD_ROTATE, _(""), load_resource_tool_image(_("card_rotate")), wxNullBitmap,wxITEM_NORMAL,_TOOL_("rotate card"));
|
||||||
tb->Realize();
|
tb->Realize();
|
||||||
// Menus
|
// Menus
|
||||||
IconMenu* menuCard = new IconMenu();
|
|
||||||
menuCard->Append(ID_CARD_PREV, _("Select &Previous Card\tPgUp"), _("Selects the previous card in the list"));
|
|
||||||
menuCard->Append(ID_CARD_NEXT, _("Select &Next Card\tPgDn"), _("Selects the next card in the list"));
|
|
||||||
menuCard->AppendSeparator();
|
|
||||||
menuCard->Append(ID_CARD_ADD, _("card_add"), _("&Add Card\tCtrl++"), _("Add a new, blank, card to this set"));
|
|
||||||
menuCard->Append(ID_CARD_ADD_MULT, _("card_add_multiple"), _("Add &Multiple Cards..."), _("Add multiple cards to the set"));
|
|
||||||
// NOTE: space after "Del" prevents wx from making del an accellerator
|
|
||||||
// otherwise we delete a card when delete is pressed inside the editor
|
|
||||||
menuCard->Append(ID_CARD_REMOVE, _("card_del"), _("&Remove Select Card\tDel "), _("Delete the selected card from this set"));
|
|
||||||
menuCard->AppendSeparator();
|
|
||||||
IconMenu* menuRotate = new IconMenu();
|
|
||||||
menuRotate->Append(ID_CARD_ROTATE_0, _("card_rotate_0"), _("&Normal"), _("Display the card with the right side up"), wxITEM_CHECK);
|
|
||||||
menuRotate->Append(ID_CARD_ROTATE_270, _("card_rotate_270"), _("Rotated 90 &Clockwise"), _("Display the card rotated clockwise"), wxITEM_CHECK);
|
|
||||||
menuRotate->Append(ID_CARD_ROTATE_90, _("card_rotate_90"), _("Rotated 90 C&ounter Clockwise"), _("Display the card rotated counter-clockwise (anti-clockwise for the British)"), wxITEM_CHECK);
|
|
||||||
menuRotate->Append(ID_CARD_ROTATE_180, _("card_rotate_180"), _("Rotated 180, &Up Side Down"), _("Display the card up side down"), wxITEM_CHECK);
|
|
||||||
menuCard->Append(wxID_ANY, _("card_rotate"), _("&Orientation"), _("Orientation of the card display"), wxITEM_NORMAL, menuRotate);
|
|
||||||
menuCard->AppendSeparator();
|
|
||||||
// This probably belongs in the window menu, but there we can't remove the separator once it is added
|
|
||||||
menuCard->Append(ID_SELECT_COLUMNS, _("C&ard List Columns..."), _("Select what columns should be shown and in what order."));
|
|
||||||
mb->Insert(2, menuCard, _("&Cards"));
|
mb->Insert(2, menuCard, _("&Cards"));
|
||||||
|
|
||||||
IconMenu* menuFormat = new IconMenu();
|
|
||||||
menuFormat->Append(ID_FORMAT_BOLD, _("bold"), _("Bold\tCtrl+B"), _("Makes the selected text bold"), wxITEM_CHECK);
|
|
||||||
menuFormat->Append(ID_FORMAT_ITALIC, _("italic"), _("Italic\tCtrl+I"), _("Makes the selected text italic"), wxITEM_CHECK);
|
|
||||||
menuFormat->Append(ID_FORMAT_SYMBOL, _("symbol"), _("Symbols\tCtrl+M"), _("Draws the selected text with symbols"), wxITEM_CHECK);
|
|
||||||
menuFormat->Append(ID_FORMAT_REMINDER, _("reminder"), _("Reminder Text\tCtrl+R"), _("Show reminder text for the selected keyword"), wxITEM_CHECK);
|
|
||||||
mb->Insert(3, menuFormat, _("&Format"));
|
mb->Insert(3, menuFormat, _("&Format"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,8 +134,8 @@ void CardsPanel::destroyUI(wxToolBar* tb, wxMenuBar* mb) {
|
|||||||
tb->DeleteToolByPos(10); // delete separator
|
tb->DeleteToolByPos(10); // delete separator
|
||||||
tb->DeleteToolByPos(10); // delete separator
|
tb->DeleteToolByPos(10); // delete separator
|
||||||
// Menus
|
// Menus
|
||||||
delete mb->Remove(3);
|
mb->Remove(3);
|
||||||
delete mb->Remove(2);
|
mb->Remove(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardsPanel::onUpdateUI(wxUpdateUIEvent& ev) {
|
void CardsPanel::onUpdateUI(wxUpdateUIEvent& ev) {
|
||||||
@@ -148,6 +162,16 @@ void CardsPanel::onUpdateUI(wxUpdateUIEvent& ev) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ID_INSERT_SYMBOL: {
|
||||||
|
wxMenu* menu = editor->getMenu(ID_INSERT_SYMBOL);
|
||||||
|
ev.Enable(menu);
|
||||||
|
if (insertSymbolMenu->GetSubMenu() != menu || menu->GetParent() != menuFormat) {
|
||||||
|
// re-add the menu
|
||||||
|
menuFormat->Remove(insertSymbolMenu);
|
||||||
|
insertSymbolMenu->SetSubMenu(menu);
|
||||||
|
menuFormat->Append(insertSymbolMenu);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,6 +211,12 @@ void CardsPanel::onCommand(int id) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
default: {
|
||||||
|
if (id >= ID_INSERT_SYMBOL_MENU_MIN && id <= ID_INSERT_SYMBOL_MENU_MAX) {
|
||||||
|
// pass on to editor
|
||||||
|
editor->onCommand(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class wxSplitterWindow;
|
|||||||
class ImageCardList;
|
class ImageCardList;
|
||||||
class DataEditor;
|
class DataEditor;
|
||||||
class TextCtrl;
|
class TextCtrl;
|
||||||
|
class IconMenu;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : CardsPanel
|
// ----------------------------------------------------------------------------- : CardsPanel
|
||||||
|
|
||||||
@@ -95,7 +96,8 @@ class CardsPanel : public SetWindowPanel {
|
|||||||
TextCtrl* notes;
|
TextCtrl* notes;
|
||||||
|
|
||||||
// --------------------------------------------------- : Menus & tools
|
// --------------------------------------------------- : Menus & tools
|
||||||
wxMenu* cardMenu, formatMenu;
|
IconMenu* menuCard, *menuFormat;
|
||||||
|
wxMenuItem* insertSymbolMenu; // owned by menuFormat, but submenu owned by SymbolFont
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : EOF
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
|
|||||||
@@ -53,8 +53,10 @@ class ValueEditor {
|
|||||||
/// a context menu is requested, add extra items to the menu m
|
/// a context menu is requested, add extra items to the menu m
|
||||||
/** return false to suppress menu */
|
/** return false to suppress menu */
|
||||||
virtual bool onContextMenu(wxMenu& m, wxContextMenuEvent& ev) { return true; }
|
virtual bool onContextMenu(wxMenu& m, wxContextMenuEvent& ev) { return true; }
|
||||||
/// A menu item was selected
|
/// Get a special menu, events will be sent to onMenu
|
||||||
virtual void onMenu(wxCommandEvent& ev) { ev.Skip(); }
|
virtual wxMenu* getMenu(int type) const { return nullptr; }
|
||||||
|
/// A menu item was selected, return true if the command was processed
|
||||||
|
virtual bool onCommand(int id) { return false; }
|
||||||
|
|
||||||
// --------------------------------------------------- : Clipboard
|
// --------------------------------------------------- : Clipboard
|
||||||
|
|
||||||
|
|||||||
+27
-1
@@ -192,7 +192,7 @@ void TextValueEditor::onChar(wxKeyEvent& ev) {
|
|||||||
// TODO: Find a more correct way to determine normal characters,
|
// TODO: Find a more correct way to determine normal characters,
|
||||||
// this might not work for internationalized input.
|
// this might not work for internationalized input.
|
||||||
// It might also not be portable!
|
// It might also not be portable!
|
||||||
replaceSelection(String(ev.GetUnicodeKey(), 1), _("Typing"));
|
replaceSelection(escape(String(ev.GetUnicodeKey(), 1)), _("Typing"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,6 +224,31 @@ bool TextValueEditor::onContextMenu(wxMenu& m, wxContextMenuEvent& ev) {
|
|||||||
// always show the menu
|
// always show the menu
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
bool TextValueEditor::onCommand(int id) {
|
||||||
|
if (id >= ID_INSERT_SYMBOL_MENU_MIN && id <= ID_INSERT_SYMBOL_MENU_MAX) {
|
||||||
|
// Insert a symbol
|
||||||
|
if ((style().always_symbol || style().allow_formating) && style().symbol_font.valid()) {
|
||||||
|
String code = style().symbol_font.font->insertSymbolCode(id);
|
||||||
|
if (!style().always_symbol) {
|
||||||
|
code = _("<sym>") + code + _("</sym>");
|
||||||
|
}
|
||||||
|
replaceSelection(code, _("Insert Symbol"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
wxMenu* TextValueEditor::getMenu(int type) const {
|
||||||
|
if (type == ID_INSERT_SYMBOL && (style().always_symbol || style().allow_formating)
|
||||||
|
&& style().symbol_font.valid()) {
|
||||||
|
return style().symbol_font.font->insertSymbolMenu(viewer.getContext());
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
/// TODO : move to doFormat
|
||||||
void TextValueEditor::onMenu(wxCommandEvent& ev) {
|
void TextValueEditor::onMenu(wxCommandEvent& ev) {
|
||||||
if (ev.GetId() == ID_FORMAT_REMINDER) {
|
if (ev.GetId() == ID_FORMAT_REMINDER) {
|
||||||
// toggle reminder text
|
// toggle reminder text
|
||||||
@@ -235,6 +260,7 @@ void TextValueEditor::onMenu(wxCommandEvent& ev) {
|
|||||||
ev.Skip();
|
ev.Skip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Other overrides
|
// ----------------------------------------------------------------------------- : Other overrides
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ class TextValueEditor : public TextValueViewer, public ValueEditor {
|
|||||||
virtual void onMouseWheel(const RealPoint& pos, wxMouseEvent& ev);
|
virtual void onMouseWheel(const RealPoint& pos, wxMouseEvent& ev);
|
||||||
|
|
||||||
virtual bool onContextMenu(wxMenu& m, wxContextMenuEvent&);
|
virtual bool onContextMenu(wxMenu& m, wxContextMenuEvent&);
|
||||||
virtual void onMenu(wxCommandEvent&);
|
virtual wxMenu* getMenu(int type) const;
|
||||||
|
virtual bool onCommand(int);
|
||||||
|
|
||||||
virtual void onChar(wxKeyEvent&);
|
virtual void onChar(wxKeyEvent&);
|
||||||
|
|
||||||
@@ -98,6 +99,7 @@ class TextValueEditor : public TextValueViewer, public ValueEditor {
|
|||||||
void moveSelectionNoRedraw(IndexType t, size_t new_end, bool also_move_start=true, Movement dir = MOVE_MID);
|
void moveSelectionNoRedraw(IndexType t, size_t new_end, bool also_move_start=true, Movement dir = MOVE_MID);
|
||||||
|
|
||||||
/// Replace the current selection with 'replacement', name the action
|
/// Replace the current selection with 'replacement', name the action
|
||||||
|
/** replacement should be a tagged string (i.e. already escaped) */
|
||||||
void replaceSelection(const String& replacement, const String& name);
|
void replaceSelection(const String& replacement, const String& name);
|
||||||
|
|
||||||
/// Make sure the selection satisfies its constraints
|
/// Make sure the selection satisfies its constraints
|
||||||
|
|||||||
+24
-6
@@ -24,7 +24,8 @@ String Error::what() const {
|
|||||||
|
|
||||||
// Errors for which a message box was already shown
|
// Errors for which a message box was already shown
|
||||||
vector<String> previous_errors;
|
vector<String> previous_errors;
|
||||||
String pending_error;
|
String pending_errors;
|
||||||
|
String pending_warnings;
|
||||||
DECLARE_TYPEOF_COLLECTION(String);
|
DECLARE_TYPEOF_COLLECTION(String);
|
||||||
|
|
||||||
void handle_error(const String& e, bool allow_duplicate = true, bool now = true) {
|
void handle_error(const String& e, bool allow_duplicate = true, bool now = true) {
|
||||||
@@ -38,8 +39,8 @@ void handle_error(const String& e, bool allow_duplicate = true, bool now = true)
|
|||||||
}
|
}
|
||||||
// Only show errors in the main thread
|
// Only show errors in the main thread
|
||||||
if (!now || !wxThread::IsMain()) {
|
if (!now || !wxThread::IsMain()) {
|
||||||
if (!pending_error.empty()) pending_error += _("\n\n");
|
if (!pending_errors.empty()) pending_errors += _("\n\n");
|
||||||
pending_error += e;
|
pending_errors += e;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// show message
|
// show message
|
||||||
@@ -50,10 +51,27 @@ void handle_error(const Error& e, bool allow_duplicate, bool now) {
|
|||||||
handle_error(e.what(), allow_duplicate, now);
|
handle_error(e.what(), allow_duplicate, now);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_warning(const String& w, bool now) {
|
||||||
|
// Check duplicates
|
||||||
|
// TODO: thread safety
|
||||||
|
// Only show errors in the main thread
|
||||||
|
if (!now || !wxThread::IsMain()) {
|
||||||
|
if (!pending_warnings.empty()) pending_warnings += _("\n\n");
|
||||||
|
pending_warnings += w;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// show message
|
||||||
|
wxMessageBox(w, _("Warning"), wxOK | wxICON_EXCLAMATION);
|
||||||
|
}
|
||||||
|
|
||||||
void handle_pending_errors() {
|
void handle_pending_errors() {
|
||||||
assert(wxThread::IsMain());
|
assert(wxThread::IsMain());
|
||||||
if (!pending_error.empty()) {
|
if (!pending_errors.empty()) {
|
||||||
handle_error(pending_error);
|
handle_error(pending_errors);
|
||||||
pending_error.clear();
|
pending_errors.clear();
|
||||||
|
}
|
||||||
|
if (!pending_warnings.empty()) {
|
||||||
|
handle_warning(pending_warnings);
|
||||||
|
pending_warnings.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -96,7 +96,10 @@ class ScriptError : public Error {
|
|||||||
*/
|
*/
|
||||||
void handle_error(const Error& e, bool allow_duplicate = true, bool now = true);
|
void handle_error(const Error& e, bool allow_duplicate = true, bool now = true);
|
||||||
|
|
||||||
/// Handle errors that were not handled immediatly in handleError
|
/// Handle a warning by showing a message box
|
||||||
|
void handle_warning(const String& w, bool now = true);
|
||||||
|
|
||||||
|
/// Handle errors and warnings that were not handled immediatly in handleError
|
||||||
/** Should be called repeatedly (e.g. in an onIdle event handler) */
|
/** Should be called repeatedly (e.g. in an onIdle event handler) */
|
||||||
void handle_pending_errors();
|
void handle_pending_errors();
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class Package {
|
|||||||
bool needSaveAs() const;
|
bool needSaveAs() const;
|
||||||
/// Determines the short name of this package: the filename without path or extension
|
/// Determines the short name of this package: the filename without path or extension
|
||||||
String name() const;
|
String name() const;
|
||||||
/// Return the full name of this package, by default equal to name()
|
/// Return the (user friendly) full name of this package, by default equal to name()
|
||||||
virtual String fullName() const;
|
virtual String fullName() const;
|
||||||
/// Return the absolute filename of this file
|
/// Return the absolute filename of this file
|
||||||
const String& absoluteFilename() const;
|
const String& absoluteFilename() const;
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ void Reader::handleAppVersion() {
|
|||||||
if (enterBlock(_("mse_version"))) {
|
if (enterBlock(_("mse_version"))) {
|
||||||
handle(file_app_version);
|
handle(file_app_version);
|
||||||
if (app_version < file_app_version) {
|
if (app_version < file_app_version) {
|
||||||
wxMessageBox(_ERROR_2_("newer version", filename, file_app_version.toString()), _("Warning"), wxOK | wxICON_EXCLAMATION);
|
handle_warning(_ERROR_2_("newer version", filename, file_app_version.toString()), false);
|
||||||
}
|
}
|
||||||
exitBlock();
|
exitBlock();
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ void Reader::warning(const String& msg) {
|
|||||||
|
|
||||||
void Reader::showWarnings() {
|
void Reader::showWarnings() {
|
||||||
if (!warnings.empty()) {
|
if (!warnings.empty()) {
|
||||||
wxMessageBox(_("Warnings while reading file:\n") + filename + _("\n") + warnings, _("Warning"), wxOK | wxICON_EXCLAMATION);
|
handle_warning(_("Warnings while reading file:\n") + filename + _("\n") + warnings, false);
|
||||||
warnings.clear();
|
warnings.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,10 @@
|
|||||||
#include <util/prec.hpp>
|
#include <util/prec.hpp>
|
||||||
#include <util/string.hpp>
|
#include <util/string.hpp>
|
||||||
|
|
||||||
|
class Game;
|
||||||
|
class StyleSheet;
|
||||||
|
class SymbolFont;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Localisation macros
|
// ----------------------------------------------------------------------------- : Localisation macros
|
||||||
|
|
||||||
enum LocaleCategory
|
enum LocaleCategory
|
||||||
@@ -37,6 +41,24 @@ enum LocaleCategory
|
|||||||
/// Translate 'key' in the category 'cat' using the current locale
|
/// Translate 'key' in the category 'cat' using the current locale
|
||||||
String tr(LocaleCategory cat, const String& key);
|
String tr(LocaleCategory cat, const String& key);
|
||||||
|
|
||||||
|
/// Translate 'key' in the for a Game using the current locale
|
||||||
|
String tr(const Game&, const String& key);
|
||||||
|
/// Translate 'key' in the for a StyleSheet using the current locale
|
||||||
|
String tr(const StyleSheet&, const String& key);
|
||||||
|
/// Translate 'key' in the for a SymbolFont using the current locale
|
||||||
|
String tr(const SymbolFont&, const String& key);
|
||||||
|
|
||||||
|
/// Translate 'key' in the for a Game using the current locale
|
||||||
|
/** If the key is not found, use the default value */
|
||||||
|
String tr(const Game&, const String& key, const String& def);
|
||||||
|
/// Translate 'key' in the for a StyleSheet using the current locale
|
||||||
|
/** If the key is not found, use the default value */
|
||||||
|
String tr(const StyleSheet&, const String& key, const String& def);
|
||||||
|
/// Translate 'key' in the for a SymbolFont using the current locale
|
||||||
|
/** If the key is not found, use the default value */
|
||||||
|
String tr(const SymbolFont&, const String& key, const String& def);
|
||||||
|
|
||||||
|
|
||||||
/// A localized string for menus/toolbar buttons
|
/// A localized string for menus/toolbar buttons
|
||||||
#define _MENU_(s) tr(LOCALE_CAT_MENU, _(s))
|
#define _MENU_(s) tr(LOCALE_CAT_MENU, _(s))
|
||||||
/// A localized string for help/statusbar text
|
/// A localized string for help/statusbar text
|
||||||
|
|||||||
+7
-3
@@ -141,13 +141,17 @@ String cannocial_name_form(const String& str) {
|
|||||||
ret.reserve(str.size());
|
ret.reserve(str.size());
|
||||||
bool leading = true;
|
bool leading = true;
|
||||||
FOR_EACH_CONST(c, str) {
|
FOR_EACH_CONST(c, str) {
|
||||||
if ((c == _('_') || c == _(' ')) && !leading) {
|
if ((c == _('_') || c == _(' '))) {
|
||||||
ret += _(' ');
|
if (!leading) ret += _(' ');
|
||||||
|
} else {
|
||||||
|
ret += c;
|
||||||
|
leading = false;
|
||||||
|
/*
|
||||||
} else if (isAlnum(c) || c == _('-')) {
|
} else if (isAlnum(c) || c == _('-')) {
|
||||||
ret += toLower(c);
|
ret += toLower(c);
|
||||||
leading = false;
|
leading = false;
|
||||||
} else {
|
} else {
|
||||||
// ignore non alpha numeric
|
// ignore non alpha numeric*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -331,7 +331,7 @@ String tagged_substr_replace(const String& input, size_t start, size_t end, cons
|
|||||||
return simplify_tagged(
|
return simplify_tagged(
|
||||||
substr_replace(input, start, end,
|
substr_replace(input, start, end,
|
||||||
get_tags(input, start, end, true) + // close tags
|
get_tags(input, start, end, true) + // close tags
|
||||||
escape(replacement) +
|
replacement +
|
||||||
get_tags(input, start, end, false) // open tags
|
get_tags(input, start, end, false) // open tags
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ String remove_tag_contents(const String& str, const String& tag);
|
|||||||
* This function makes sure tags still match. It also attempts to cancel out tags.
|
* This function makes sure tags still match. It also attempts to cancel out tags.
|
||||||
* This means that when removing "<x>a</x>" nothing is left,
|
* This means that when removing "<x>a</x>" nothing is left,
|
||||||
* but with input "<x>a" -> "<x>" and "</>a" -> "</>".
|
* but with input "<x>a" -> "<x>" and "</>a" -> "</>".
|
||||||
* Escapes the replacement, i.e. all < in become \1.
|
* Does not escape the replacement.
|
||||||
*/
|
*/
|
||||||
String tagged_substr_replace(const String& input, size_t start, size_t end, const String& replacement);
|
String tagged_substr_replace(const String& input, size_t start, size_t end, const String& replacement);
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ enum MenuID {
|
|||||||
enum ChildMenuID {
|
enum ChildMenuID {
|
||||||
|
|
||||||
ID_CHILD_MIN = 1000
|
ID_CHILD_MIN = 1000
|
||||||
, ID_CHILD_MAX = 2999
|
, ID_CHILD_MAX = 3999
|
||||||
|
|
||||||
// Cards menu
|
// Cards menu
|
||||||
, ID_CARD_ADD = 1001
|
, ID_CARD_ADD = 1001
|
||||||
@@ -106,6 +106,7 @@ enum ChildMenuID {
|
|||||||
, ID_FORMAT_ITALIC
|
, ID_FORMAT_ITALIC
|
||||||
, ID_FORMAT_SYMBOL
|
, ID_FORMAT_SYMBOL
|
||||||
, ID_FORMAT_REMINDER
|
, ID_FORMAT_REMINDER
|
||||||
|
, ID_INSERT_SYMBOL
|
||||||
|
|
||||||
// SymbolSelectEditor toolbar/menu
|
// SymbolSelectEditor toolbar/menu
|
||||||
, ID_PART = 2001
|
, ID_PART = 2001
|
||||||
@@ -146,6 +147,10 @@ enum ChildMenuID {
|
|||||||
|
|
||||||
// Style
|
// Style
|
||||||
, ID_STYLE_USE_FOR_ALL = 3201
|
, ID_STYLE_USE_FOR_ALL = 3201
|
||||||
|
|
||||||
|
// SymbolFont (Format menu)
|
||||||
|
, ID_INSERT_SYMBOL_MENU_MIN = 3301
|
||||||
|
, ID_INSERT_SYMBOL_MENU_MAX = 3999
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user