Commit 4b0058cc authored by twanvl's avatar twanvl

Added new_card function;

Added parameter to ScriptValue::next to recieve the key of the item.
Finished Add Multiple Cards behaviour.
parent 406029a1
...@@ -45,14 +45,11 @@ Image generateDisabledImage(const Image& imgIn) { ...@@ -45,14 +45,11 @@ Image generateDisabledImage(const Image& imgIn) {
return imgOut; return imgOut;
} }
// ----------------------------------------------------------------------------- : set_menu_item_image
// ----------------------------------------------------------------------------- : IconMenu void set_menu_item_image(wxMenuItem* item, const String& resource) {
void IconMenu::Append(int id, const String& resource, const String& text, const String& help, int style, wxMenu* submenu) {
// create menu, load icon
wxMenuItem* item = new wxMenuItem(this, id, text, help, style, submenu);
Bitmap bitmap = load_resource_tool_image(resource);
// load bitmap // load bitmap
Bitmap bitmap = load_resource_tool_image(resource);
#ifdef __WXMSW__ #ifdef __WXMSW__
// make greyed bitmap // make greyed bitmap
bitmap = bitmap.GetSubBitmap(wxRect(0,0,16,16)); bitmap = bitmap.GetSubBitmap(wxRect(0,0,16,16));
...@@ -61,10 +58,19 @@ void IconMenu::Append(int id, const String& resource, const String& text, const ...@@ -61,10 +58,19 @@ void IconMenu::Append(int id, const String& resource, const String& text, const
item->SetDisabledBitmap(disabledImage); item->SetDisabledBitmap(disabledImage);
#else #else
// Check items can't have bitmaps :( // Check items can't have bitmaps :(
if (item->GetKind() == wxITEM_NORMAL) if (item->GetKind() == wxITEM_NORMAL) {
item->SetBitmap(bitmap); item->SetBitmap(bitmap);
}
#endif #endif
// add menu }
// ----------------------------------------------------------------------------- : IconMenu
void IconMenu::Append(int id, const String& resource, const String& text, const String& help, int style, wxMenu* submenu) {
// create menu, load icon
wxMenuItem* item = new wxMenuItem(this, id, text, help, style, submenu);
set_menu_item_image(item, resource);
// add to menu
wxMenu::Append(item); wxMenu::Append(item);
} }
......
...@@ -33,5 +33,7 @@ class IconMenu : public wxMenu { ...@@ -33,5 +33,7 @@ class IconMenu : public wxMenu {
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);
}; };
void set_menu_item_image(wxMenuItem* menuitem, const String& resource);
// ----------------------------------------------------------------------------- : EOF // ----------------------------------------------------------------------------- : EOF
#endif #endif
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include <util/window_id.hpp> #include <util/window_id.hpp>
#include <wx/splitter.h> #include <wx/splitter.h>
DECLARE_TYPEOF_COLLECTION(AddCardsScriptP);
// ----------------------------------------------------------------------------- : CardsPanel // ----------------------------------------------------------------------------- : CardsPanel
CardsPanel::CardsPanel(Window* parent, int id) CardsPanel::CardsPanel(Window* parent, int id)
...@@ -70,7 +72,9 @@ CardsPanel::CardsPanel(Window* parent, int id) ...@@ -70,7 +72,9 @@ CardsPanel::CardsPanel(Window* parent, int id)
menuCard->Append(ID_CARD_NEXT, _MENU_("next card"), _HELP_("next card")); menuCard->Append(ID_CARD_NEXT, _MENU_("next card"), _HELP_("next card"));
menuCard->AppendSeparator(); menuCard->AppendSeparator();
menuCard->Append(ID_CARD_ADD, _("card_add"), _MENU_("add card"), _HELP_("add card")); menuCard->Append(ID_CARD_ADD, _("card_add"), _MENU_("add card"), _HELP_("add card"));
menuCard->Append(ID_CARD_ADD_MULT, _("card_add_multiple"), _MENU_("add cards"), _HELP_("add cards")); insertManyCardsMenu = new wxMenuItem(menuCard, ID_CARD_ADD_MULT, _MENU_("add cards"), _HELP_("add cards"));
set_menu_item_image(insertManyCardsMenu, _("card_add_multiple"));
((wxMenu*)menuCard)->Append(insertManyCardsMenu);
// NOTE: space after "Del" prevents wx from making del an accellerator // NOTE: space after "Del" prevents wx from making del an accellerator
// otherwise we delete a card when delete is pressed inside the editor // otherwise we delete a card when delete is pressed inside the editor
// Adding a space never hurts, please keep it just to be safe. // Adding a space never hurts, please keep it just to be safe.
...@@ -140,10 +144,23 @@ void CardsPanel::onChangeSet() { ...@@ -140,10 +144,23 @@ void CardsPanel::onChangeSet() {
editor->setSet(set); editor->setSet(set);
notes->setSet(set); notes->setSet(set);
card_list->setSet(set); card_list->setSet(set);
/* // resize editor
Sizer* s = sizer; // change insertManyCardsMenu
minSize = s->minSize; delete insertManyCardsMenu->GetSubMenu();
layout();*/ if (!set->game->add_cards_scripts.empty()) {
// create menu for add_cards_scripts
int id = ID_ADD_CARDS_MENU_MIN;
IconMenu* cards_scripts_menu = new IconMenu;
FOR_EACH(cs, set->game->add_cards_scripts) {
cards_scripts_menu->Append(id++, cs->name, cs->description);
}
insertManyCardsMenu->SetSubMenu(cards_scripts_menu);
} else {
insertManyCardsMenu->SetSubMenu(nullptr);
}
// re-add the menu
menuCard->Remove(ID_CARD_ADD_MULT);
((wxMenu*)menuCard)->Insert(4,insertManyCardsMenu); // HACK: the position is hardcoded
} }
// ----------------------------------------------------------------------------- : UI // ----------------------------------------------------------------------------- : UI
...@@ -200,7 +217,10 @@ void CardsPanel::onUpdateUI(wxUpdateUIEvent& ev) { ...@@ -200,7 +217,10 @@ void CardsPanel::onUpdateUI(wxUpdateUIEvent& ev) {
ev.Check(ss.card_angle() == a); ev.Check(ss.card_angle() == a);
break; break;
} }
case ID_CARD_ADD_MULT: ev.Enable(false); break; // not implemented case ID_CARD_ADD_MULT: {
ev.Enable(insertManyCardsMenu->GetSubMenu() != nullptr);
break;
}
case ID_CARD_REMOVE: ev.Enable(card_list->canDelete()); break; case ID_CARD_REMOVE: ev.Enable(card_list->canDelete()); break;
case ID_FORMAT_BOLD: case ID_FORMAT_ITALIC: case ID_FORMAT_SYMBOL: case ID_FORMAT_REMINDER: { case ID_FORMAT_BOLD: case ID_FORMAT_ITALIC: case ID_FORMAT_SYMBOL: case ID_FORMAT_REMINDER: {
if (focused_control(this) == ID_EDITOR) { if (focused_control(this) == ID_EDITOR) {
......
...@@ -2573,6 +2573,9 @@ ...@@ -2573,6 +2573,9 @@
<File <File
RelativePath=".\script\functions\basic.cpp"> RelativePath=".\script\functions\basic.cpp">
</File> </File>
<File
RelativePath=".\script\functions\construction.cpp">
</File>
<File <File
RelativePath=".\script\functions\editor.cpp"> RelativePath=".\script\functions\editor.cpp">
<FileConfiguration <FileConfiguration
......
...@@ -479,9 +479,10 @@ void Context::makeObject(size_t n) { ...@@ -479,9 +479,10 @@ void Context::makeObject(size_t n) {
for (size_t i = 0 ; i < n ; ++i) { for (size_t i = 0 ; i < n ; ++i) {
const ScriptValueP& key = stack[begin + 2 * i]; const ScriptValueP& key = stack[begin + 2 * i];
const ScriptValueP& val = stack[begin + 2 * i + 1]; const ScriptValueP& val = stack[begin + 2 * i + 1];
ret->value.push_back(val);
if (key != script_nil) { // valid key if (key != script_nil) { // valid key
ret->key_value[key->toString()] = val; ret->key_value[key->toString()] = val;
} else {
ret->value.push_back(val);
} }
} }
stack.resize(begin); stack.resize(begin);
......
...@@ -28,7 +28,7 @@ class DependencyDummy : public ScriptIterator { ...@@ -28,7 +28,7 @@ class DependencyDummy : public ScriptIterator {
public: public:
virtual ScriptType type() const { return SCRIPT_DUMMY; } virtual ScriptType type() const { return SCRIPT_DUMMY; }
virtual String typeName() const { return _("dummy"); } virtual String typeName() const { return _("dummy"); }
virtual ScriptValueP next() { return ScriptValueP(); } virtual ScriptValueP next(ScriptValueP*) { return ScriptValueP(); }
virtual ScriptValueP dependencyName(const ScriptValue&, const Dependency&) const { return dependency_dummy; } virtual ScriptValueP dependencyName(const ScriptValue&, const Dependency&) const { return dependency_dummy; }
}; };
......
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2008 Twan van Laarhoven and "coppro" |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <script/functions/functions.hpp>
#include <script/functions/util.hpp>
#include <data/field.hpp>
#include <data/field/text.hpp>
#include <data/field/choice.hpp>
#include <data/field/package_choice.hpp>
#include <data/field/color.hpp>
#include <data/game.hpp>
#include <data/card.hpp>
#include <util/error.hpp>
// ----------------------------------------------------------------------------- : new_card
SCRIPT_FUNCTION(new_card) {
SCRIPT_PARAM(GameP, game);
CardP new_card = new_intrusive1<Card>(*game);
// set field values
SCRIPT_PARAM(ScriptValueP, input);
ScriptValueP it = input->makeIterator(input);
ScriptValueP key;
while (ScriptValueP v = it->next(&key)) {
assert(key);
String name = key->toString();
// find value to update
IndexMap<FieldP,ValueP>::const_iterator value_it = new_card->data.find(name);
if (value_it == new_card->data.end()) {
throw ScriptError(format_string(_("Card doesn't have a field named '%s'"),name));
}
Value* value = value_it->get();
// set the value
if (TextValue* tvalue = dynamic_cast<TextValue*>(value)) {
tvalue->value = v->toString();
} else if (ChoiceValue* cvalue = dynamic_cast<ChoiceValue*>(value)) {
cvalue->value = v->toString();
} else if (PackageChoiceValue* pvalue = dynamic_cast<PackageChoiceValue*>(value)) {
pvalue->package_name = v->toString();
} else if (ColorValue* cvalue = dynamic_cast<ColorValue*>(value)) {
cvalue->value = (AColor)*v;
} else {
throw ScriptError(format_string(_("Can not set value '%s', it is not of the right type"),name));
}
}
SCRIPT_RETURN(new_card);
}
// ----------------------------------------------------------------------------- : Init
void init_script_construction_functions(Context& ctx) {
ctx.setVariable(_("new card"), script_new_card);
}
...@@ -26,6 +26,7 @@ void init_script_image_functions(Context& ctx); ...@@ -26,6 +26,7 @@ void init_script_image_functions(Context& ctx);
void init_script_editor_functions(Context& ctx); void init_script_editor_functions(Context& ctx);
void init_script_export_functions(Context& ctx); void init_script_export_functions(Context& ctx);
void init_script_english_functions(Context& ctx); void init_script_english_functions(Context& ctx);
void init_script_construction_functions(Context& ctx);
/// Initialize all built in functions for a context /// Initialize all built in functions for a context
inline void init_script_functions(Context& ctx) { inline void init_script_functions(Context& ctx) {
...@@ -35,6 +36,7 @@ inline void init_script_functions(Context& ctx) { ...@@ -35,6 +36,7 @@ inline void init_script_functions(Context& ctx) {
init_script_editor_functions(ctx); init_script_editor_functions(ctx);
init_script_export_functions(ctx); init_script_export_functions(ctx);
init_script_english_functions(ctx); init_script_english_functions(ctx);
init_script_construction_functions(ctx);
} }
// ----------------------------------------------------------------------------- : EOF // ----------------------------------------------------------------------------- : EOF
......
...@@ -92,7 +92,7 @@ struct ScriptIterator : public ScriptValue { ...@@ -92,7 +92,7 @@ struct ScriptIterator : public ScriptValue {
virtual CompareWhat compareAs(String&, void const*&) const; // { return COMPARE_NO; } virtual CompareWhat compareAs(String&, void const*&) const; // { return COMPARE_NO; }
/// Return the next item for this iterator, or ScriptValueP() if there is no such item /// Return the next item for this iterator, or ScriptValueP() if there is no such item
virtual ScriptValueP next() = 0; virtual ScriptValueP next(ScriptValueP* key_out = nullptr) = 0;
}; };
// make an iterator over a range // make an iterator over a range
...@@ -100,6 +100,8 @@ ScriptValueP rangeIterator(int start, int end); ...@@ -100,6 +100,8 @@ ScriptValueP rangeIterator(int start, int end);
// ----------------------------------------------------------------------------- : Collections // ----------------------------------------------------------------------------- : Collections
ScriptValueP to_script(int);
class ScriptCollectionBase : public ScriptValue { class ScriptCollectionBase : public ScriptValue {
public: public:
virtual ScriptType type() const { return SCRIPT_COLLECTION; } virtual ScriptType type() const { return SCRIPT_COLLECTION; }
...@@ -111,8 +113,9 @@ template <typename Collection> ...@@ -111,8 +113,9 @@ template <typename Collection>
class ScriptCollectionIterator : public ScriptIterator { class ScriptCollectionIterator : public ScriptIterator {
public: public:
ScriptCollectionIterator(const Collection* col) : pos(0), col(col) {} ScriptCollectionIterator(const Collection* col) : pos(0), col(col) {}
virtual ScriptValueP next() { virtual ScriptValueP next(ScriptValueP* key_out) {
if (pos < col->size()) { if (pos < col->size()) {
if (key_out) *key_out = to_script((int)pos);
return to_script(col->at(pos++)); return to_script(col->at(pos++));
} else { } else {
return ScriptValueP(); return ScriptValueP();
...@@ -213,7 +216,7 @@ class ScriptCustomCollection : public ScriptCollectionBase { ...@@ -213,7 +216,7 @@ class ScriptCustomCollection : public ScriptCollectionBase {
return COMPARE_AS_POINTER; return COMPARE_AS_POINTER;
} }
/// The collection as a list (contains all values) /// The collection as a list (contains only the values that don't have a key)
vector<ScriptValueP> value; vector<ScriptValueP> value;
/// The collection as a map (contains only the values that have a key) /// The collection as a map (contains only the values that have a key)
map<String,ScriptValueP> key_value; map<String,ScriptValueP> key_value;
......
...@@ -25,7 +25,7 @@ ScriptValue::operator bool() const { throw Script ...@@ -25,7 +25,7 @@ ScriptValue::operator bool() const { throw Script
ScriptValue::operator double() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("double" ))); } ScriptValue::operator double() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("double" ))); }
ScriptValue::operator AColor() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("color" ))); } ScriptValue::operator AColor() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("color" ))); }
ScriptValueP ScriptValue::eval(Context&) const { return delayError(_ERROR_2_("can't convert", typeName(), _TYPE_("function"))); } ScriptValueP ScriptValue::eval(Context&) const { return delayError(_ERROR_2_("can't convert", typeName(), _TYPE_("function"))); }
ScriptValueP ScriptValue::next() { throw InternalError(_("Can't convert from ")+typeName()+_(" to iterator")); } ScriptValueP ScriptValue::next(ScriptValueP* key_out) { throw InternalError(_("Can't convert from ")+typeName()+_(" to iterator")); }
ScriptValueP ScriptValue::makeIterator(const ScriptValueP&) const { return delayError(_ERROR_2_("can't convert", typeName(), _TYPE_("collection"))); } ScriptValueP ScriptValue::makeIterator(const ScriptValueP&) const { return delayError(_ERROR_2_("can't convert", typeName(), _TYPE_("collection"))); }
int ScriptValue::itemCount() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("collection"))); } int ScriptValue::itemCount() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("collection"))); }
GeneratedImageP ScriptValue::toImage(const ScriptValueP&) const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("image" ))); } GeneratedImageP ScriptValue::toImage(const ScriptValueP&) const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("image" ))); }
...@@ -129,8 +129,9 @@ class ScriptRangeIterator : public ScriptIterator { ...@@ -129,8 +129,9 @@ class ScriptRangeIterator : public ScriptIterator {
// Construct a range iterator with the given bounds (inclusive) // Construct a range iterator with the given bounds (inclusive)
ScriptRangeIterator(int start, int end) ScriptRangeIterator(int start, int end)
: pos(start), end(end) {} : pos(start), end(end) {}
virtual ScriptValueP next() { virtual ScriptValueP next(ScriptValueP* key_out) {
if (pos <= end) { if (pos <= end) {
if (key_out) *key_out = to_script(pos);
return to_script(pos++); return to_script(pos++);
} else { } else {
return ScriptValueP(); return ScriptValueP();
...@@ -359,6 +360,7 @@ String ScriptCollectionBase::toCode() const { ...@@ -359,6 +360,7 @@ String ScriptCollectionBase::toCode() const {
while (ScriptValueP v = it->next()) { while (ScriptValueP v = it->next()) {
if (!first) ret += _(","); if (!first) ret += _(",");
first = false; first = false;
// todo: include keys
ret += v->toCode(); ret += v->toCode();
} }
ret += _("]"); ret += _("]");
...@@ -370,19 +372,23 @@ String ScriptCollectionBase::toCode() const { ...@@ -370,19 +372,23 @@ String ScriptCollectionBase::toCode() const {
// Iterator over a custom collection // Iterator over a custom collection
class ScriptCustomCollectionIterator : public ScriptIterator { class ScriptCustomCollectionIterator : public ScriptIterator {
public: public:
ScriptCustomCollectionIterator(const vector<ScriptValueP>* col, ScriptValueP colP) ScriptCustomCollectionIterator(ScriptCustomCollectionP col)
: pos(0), col(col), colP(colP) {} : col(col), pos(0), it(col->key_value.begin()) {}
virtual ScriptValueP next() { virtual ScriptValueP next(ScriptValueP* key_out) {
if (pos < col->size()) { if (pos < col->value.size()) {
return col->at(pos++); if (key_out) *key_out = to_script((int)pos);
return col->value.at(pos++);
} else if (it != col->key_value.end()) {
if (key_out) *key_out = to_script(it->first);
return (it++)->second;
} else { } else {
return ScriptValueP(); return ScriptValueP();
} }
} }
private: private:
ScriptCustomCollectionP col;
size_t pos; size_t pos;
const vector<ScriptValueP>* col; map<String,ScriptValueP>::const_iterator it;
ScriptValueP colP; // for ownership of the collection
}; };
ScriptValueP ScriptCustomCollection::getMember(const String& name) const { ScriptValueP ScriptCustomCollection::getMember(const String& name) const {
...@@ -401,7 +407,9 @@ ScriptValueP ScriptCustomCollection::getIndex(int index) const { ...@@ -401,7 +407,9 @@ ScriptValueP ScriptCustomCollection::getIndex(int index) const {
} }
} }
ScriptValueP ScriptCustomCollection::makeIterator(const ScriptValueP& thisP) const { ScriptValueP ScriptCustomCollection::makeIterator(const ScriptValueP& thisP) const {
return new_intrusive2<ScriptCustomCollectionIterator>(&value, thisP); return new_intrusive1<ScriptCustomCollectionIterator>(
static_pointer_cast<ScriptCustomCollection>(thisP)
);
} }
// ----------------------------------------------------------------------------- : Concat collection // ----------------------------------------------------------------------------- : Concat collection
...@@ -411,13 +419,14 @@ class ScriptConcatCollectionIterator : public ScriptIterator { ...@@ -411,13 +419,14 @@ class ScriptConcatCollectionIterator : public ScriptIterator {
public: public:
ScriptConcatCollectionIterator(const ScriptValueP& itA, const ScriptValueP& itB) ScriptConcatCollectionIterator(const ScriptValueP& itA, const ScriptValueP& itB)
: itA(itA), itB(itB) {} : itA(itA), itB(itB) {}
virtual ScriptValueP next() { virtual ScriptValueP next(ScriptValueP* key_out) {
if (itA) { if (itA) {
ScriptValueP v = itA->next(); ScriptValueP v = itA->next(key_out);
if (v) return v; if (v) return v;
else itA = ScriptValueP(); else itA = ScriptValueP();
} }
return itB->next(); // TODO: somehow fix up the keys
return itB->next(key_out);
} }
private: private:
ScriptValueP itA, itB; ScriptValueP itA, itB;
......
...@@ -105,7 +105,8 @@ class ScriptValue : public IntrusivePtrBaseWithDelete { ...@@ -105,7 +105,8 @@ class ScriptValue : public IntrusivePtrBaseWithDelete {
/** thisP can be used to prevent destruction of the collection */ /** thisP can be used to prevent destruction of the collection */
virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const; virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const;
/// Return the next item for this iterator, or ScriptValueP() if there is no such item /// Return the next item for this iterator, or ScriptValueP() if there is no such item
virtual ScriptValueP next(); /** If key_out != 0, then it will recieve the key of the item */
virtual ScriptValueP next(ScriptValueP* key_out = nullptr);
/// Return the number of items in this value (assuming it is a collection) /// Return the number of items in this value (assuming it is a collection)
virtual int itemCount() const; virtual int itemCount() const;
/// Get a member at the given index /// Get a member at the given index
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment