Cleaned up Set::Styling/Card::Styling by spliting that functionality into a 'DelayedIndexMaps' class;

Added 'right' and 'bottom' properties to style as an alternative way of specifying width/height;
Added content_width, content_height and content_lines properties that give feedback on text rendering;
Always show warnings when showing errors and vice-versa, this prevents script errors from appearing before the reader/parse error that caused them;
Finally some preliminairy work on export templates

git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@428 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
twanvl
2007-06-22 23:12:41 +00:00
parent 97e0e8d6d6
commit e46cbe66b2
33 changed files with 384 additions and 138 deletions
+68
View File
@@ -0,0 +1,68 @@
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2007 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#ifndef HEADER_UTIL_DELAYED_INDEX_MAPS
#define HEADER_UTIL_DELAYED_INDEX_MAPS
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <util/smart_ptr.hpp>
#include <util/index_map.hpp>
#include <util/reflect.hpp>
#include <wx/sstream.h>
// ----------------------------------------------------------------------------- : DelayedIndexMaps
template <typename Key, typename Value>
IndexMap<Key,Value>& DelayedIndexMaps<Key,Value>::get(const String& name, const vector<Key>& init_with) {
intrusive_ptr<DelayedIndexMapsData<Key,Value> >& item = data[name];
if (!item) { // no item, make a new one
item = new_intrusive<DelayedIndexMapsData<Key,Value> >();
item->read_data.init(init_with);
} else if (!item->unread_data.empty()) { // not read, read now
item->read_data.init(init_with);
Reader reader(new_shared1<wxStringInputStream>(item->unread_data), _("delayed data for ") + name);
reader.handle_greedy(item->read_data);
item->unread_data.clear();
}
return item->read_data;
}
// ----------------------------------------------------------------------------- : Reflection
// custom reflection : it's a template class
template <typename Key, typename Value> void Reader::handle(DelayedIndexMaps<Key,Value>& dim) {
handle(dim.data);
}
template <typename Key, typename Value> void Writer::handle(const DelayedIndexMaps<Key,Value>& dim) {
handle(dim.data);
}
template <typename Key, typename Value> void GetMember::handle(const DelayedIndexMaps<Key,Value>& dim) {
handle(dim.data);
}
// custom reflection : read into unread_data
template <typename Key, typename Value>
void Reader::handle(DelayedIndexMapsData<Key,Value>& d) {
handle(d.unread_data);
if (d.unread_data.empty()) d.unread_data = _("\n"); // never empty (invariant)
}
template <typename Key, typename Value>
void Writer::handle(const DelayedIndexMapsData<Key,Value>& d) {
handle(d.read_data);
}
template <typename Key, typename Value>
void GetMember::handle(const DelayedIndexMapsData<Key,Value>& d) {
handle(d.read_data);
}
template <typename Key, typename Value>
void GetDefaultMember::handle(const DelayedIndexMapsData<Key,Value>&) {
handle(d.read_data);
}
// ----------------------------------------------------------------------------- : EOF
#endif
+28 -15
View File
@@ -57,6 +57,9 @@ String pending_warnings;
DECLARE_TYPEOF_COLLECTION(String);
wxCriticalSection crit_error_handling;
void show_pending_errors();
void show_pending_warnings();
void handle_error(const String& e, bool allow_duplicate = true, bool now = true) {
// Thread safety
wxCriticalSectionLocker lock(crit_error_handling);
@@ -68,13 +71,13 @@ void handle_error(const String& e, bool allow_duplicate = true, bool now = true)
previous_errors.push_back(e);
}
// Only show errors in the main thread
if (!now || !wxThread::IsMain()) {
if (!pending_errors.empty()) pending_errors += _("\n\n");
pending_errors += e;
return;
if (!pending_errors.empty()) pending_errors += _("\n\n");
pending_errors += e;
// show messages
if (now && wxThread::IsMain()) {
show_pending_warnings(); // warnings are older, show them first
show_pending_errors();
}
// show message
wxMessageBox(e, _("Error"), wxOK | wxICON_ERROR);
}
void handle_error(const Error& e, bool allow_duplicate, bool now) {
@@ -83,25 +86,35 @@ void handle_error(const Error& e, bool allow_duplicate, bool now) {
void handle_warning(const String& w, bool now) {
// Check duplicates
// TODO: thread safety
wxCriticalSectionLocker lock(crit_error_handling);
// Only show errors in the main thread
if (!now || !wxThread::IsMain()) {
if (!pending_warnings.empty()) pending_warnings += _("\n\n");
pending_warnings += w;
return;
if (!pending_warnings.empty()) pending_warnings += _("\n\n");
pending_warnings += w;
// show messages
if (now && wxThread::IsMain()) {
show_pending_errors();
show_pending_warnings();
}
// show message
wxMessageBox(w, _("Warning"), wxOK | wxICON_EXCLAMATION);
}
void handle_pending_errors() {
show_pending_errors();
show_pending_warnings();
}
void show_pending_errors() {
assert(wxThread::IsMain());
wxCriticalSectionLocker lock(crit_error_handling);
if (!pending_errors.empty()) {
handle_error(pending_errors);
wxMessageBox(pending_errors, _("Error"), wxOK | wxICON_ERROR);
pending_errors.clear();
}
}
void show_pending_warnings() {
assert(wxThread::IsMain());
wxCriticalSectionLocker lock(crit_error_handling);
if (!pending_warnings.empty()) {
handle_warning(pending_warnings);
wxMessageBox(pending_warnings, _("Warning"), wxOK | wxICON_EXCLAMATION);
pending_warnings.clear();
}
}
+31
View File
@@ -10,6 +10,8 @@
// ----------------------------------------------------------------------------- : Includes
#include <vector>
#include <map>
#include <util/string.hpp>
// ----------------------------------------------------------------------------- : IndexMap
@@ -117,5 +119,34 @@ class IndexMap : private vector<Value> {
};
// ----------------------------------------------------------------------------- : DelayedIndexMaps
// The data for a specific name.
/* Invariant: read_data is initialized <=> unread_data.empty()
*/
template <typename Key, typename Value>
struct DelayedIndexMapsData : public IntrusivePtrBase<DelayedIndexMapsData> {
String unread_data;
IndexMap<Key,Value> read_data;
};
/// A map<String,IndexMap> where the reading of the index map depends on the name.
/** The reading is delayed until the data to initialize the map with is known.
* The only way to access data is using get()
*/
template <typename Key, typename Value>
class DelayedIndexMaps {
public:
/// Get the data for a specific name. Initialize the map with init_with (if it is not alread initialized)
IndexMap<Key,Value>& get(const String& name, const vector<Key>& init_with);
private:
map<String, intrusive_ptr<DelayedIndexMapsData<Key,Value> > > data;
friend class Reader;
friend class Writer;
friend class GetDefaultMember;
friend class GetMember;
};
// ----------------------------------------------------------------------------- : EOF
#endif
+4
View File
@@ -53,6 +53,8 @@ class GetDefaultMember {
template <typename T> void handle(const vector<T>& c) { value = to_script(&c); }
template <typename K, typename V> void handle(const map<K,V>& c) { value = to_script(&c); }
template <typename K, typename V> void handle(const IndexMap<K,V>& c) { value = to_script(&c); }
template <typename K, typename V> void handle(const DelayedIndexMaps<K,V>&) {}
template <typename K, typename V> void handle(const DelayedIndexMapsData<K,V>& c);
template <typename T> void handle(const intrusive_ptr<T>& p) { value = to_script(p); }
void handle(const ScriptValueP&);
void handle(const ScriptP&);
@@ -103,6 +105,8 @@ class GetMember : private GetDefaultMember {
}
}
}
template <typename K, typename V> void handle(const DelayedIndexMaps<K,V>&);
template <typename K, typename V> void handle(const DelayedIndexMapsData<K,V>&);
private:
const String& target_name; ///< The name we are looking for
+6 -4
View File
@@ -88,13 +88,15 @@ class Reader {
void handle(const Char* name, vector<T>& vector);
/// Reads an object of type T from the input stream
template <typename T> void handle(T& object);
template <typename T> void handle(T&);
/// Reads a intrusive_ptr from the input stream
template <typename T> void handle(intrusive_ptr<T>& pointer);
template <typename T> void handle(intrusive_ptr<T>&);
/// Reads a map from the input stream
template <typename V> void handle(map<String,V>& m);
template <typename V> void handle(map<String,V>&);
/// Reads an IndexMap from the input stream, reads only keys that already exist in the map
template <typename K, typename V> void handle(IndexMap<K,V>& m);
template <typename K, typename V> void handle(IndexMap<K,V>&);
template <typename K, typename V> void handle(DelayedIndexMaps<K,V>&);
template <typename K, typename V> void handle(DelayedIndexMapsData<K,V>&);
/// Reads a Defaultable from the input stream
template <typename T> void handle(Defaultable<T>&);
/// Reads a Scriptable from the input stream
+6 -4
View File
@@ -58,13 +58,15 @@ class Writer {
void handle(const Char* str) { handle(String(str)); }
/// Write an object of type T to the output stream
template <typename T> void handle(const T& object);
template <typename T> void handle(const T&);
/// Write a intrusive_ptr to the output stream
template <typename T> void handle(const intrusive_ptr<T>& pointer);
template <typename T> void handle(const intrusive_ptr<T>&);
/// Write a map to the output stream
template <typename K, typename V> void handle(const map<K,V>& map);
template <typename K, typename V> void handle(const map<K,V>&);
/// Write an IndexMap to the output stream
template <typename K, typename V> void handle(const IndexMap<K,V>& map);
template <typename K, typename V> void handle(const IndexMap<K,V>&);
template <typename K, typename V> void handle(const DelayedIndexMaps<K,V>&);
template <typename K, typename V> void handle(const DelayedIndexMapsData<K,V>&);
/// Write an object of type Defaultable<T> to the output stream
template <typename T> void handle(const Defaultable<T>&);
/// Write an object of type Scriptable<T> to the output stream
+1
View File
@@ -191,6 +191,7 @@ enum ControlID {
, ID_GAME_LIST
, ID_STYLESHEET_LIST
, ID_KEYWORD_LIST
, ID_EXPORT_LIST
, ID_NOTES
, ID_KEYWORD
, ID_MATCH