Card data in images (minimum viable)

* remove wxEmptyString

* improve style tab carousel

* create web request window

* add drop target and drop source
This commit is contained in:
GenevensiS
2025-11-28 10:42:30 +01:00
committed by GitHub
parent f5b5c0968d
commit cf0a84a8a7
49 changed files with 815 additions and 399 deletions
+4 -4
View File
@@ -753,8 +753,8 @@ SCRIPT_FUNCTION(get_card_stylesheet) {
SCRIPT_PARAM_C(ScriptValueP, set);
ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(input.get());
ScriptObject<Set*>* s = dynamic_cast<ScriptObject<Set*>*>(set.get());
if (s && c) {
return to_script(&s->getValue()->stylesheetFor(c->getValue()));
if (s && c) {
return to_script(s->getValue()->stylesheetForP(c->getValue()));
}
throw ScriptError(_("invalid set or card argument"));
}
@@ -777,8 +777,8 @@ SCRIPT_FUNCTION(get_card_from_link) {
card->linked_relation_2 == trimmed_input ? card->linked_card_2 :
card->linked_relation_3 == trimmed_input ? card->linked_card_3 :
card->linked_relation_4 == trimmed_input ? card->linked_card_4 :
wxEmptyString;
if (uid == wxEmptyString) return script_nil;
_("");
if (uid.empty()) return script_nil;
FOR_EACH(other_card, set->cards) {
if (other_card->uid == uid) SCRIPT_RETURN(other_card);
}
+11 -2
View File
@@ -29,9 +29,18 @@ SCRIPT_FUNCTION(new_card) {
// create a new card object
CardP new_card = make_intrusive<Card>(*game);
// iterate on the given key/value pairs
SCRIPT_PARAM(ScriptValueP, input);
SCRIPT_PARAM(ScriptValueP, input);
// check for a stylesheet first, since other things depend on it
ScriptValueP it = input->makeIterator();
ScriptValueP key;
while (ScriptValueP value = it->next(&key)) {
assert(key);
if (key == script_nil) continue;
String key_name = key->toString();
if (set_stylesheet_container(*game, new_card, value, key_name, ignore_field_not_found)) break;
}
// set the rest of the key/value pairs
it = input->makeIterator();
while (ScriptValueP value = it->next(&key)) {
assert(key);
if (key == script_nil) continue;
@@ -67,7 +76,7 @@ SCRIPT_FUNCTION(new_card) {
set_container(script_container, script_value, script_key_name);
}
}
// if the script result is not a collection, simply set the field value to the script value
// if the script result is not a collection, simply set the field value to the script result
else {
set_container(container, script_input, key_name);
}
+49 -42
View File
@@ -89,55 +89,62 @@ inline static void set_container(Value* container, ScriptValueP& value, String k
}
}
inline static bool set_builtin_container(const Game& game, CardP& card, ScriptValueP& value, String key_name, bool ignore_field_not_found) {
// check if the given value is for a built-in field, if found set it and return true
inline static bool set_stylesheet_container(const Game& game, CardP& card, ScriptValueP& value, String key_name, bool ignore_field_not_found) {
// check if the given value is for a stylesheet, if found set it and return true
key_name = unified_form(key_name);
if (key_name == _("notes") || key_name == _("note")) {
card->notes = value->toString();
return true;
} else if (key_name == _("style") || key_name == _("stylesheet") || key_name == _("template")) {
if (key_name == _("style") || key_name == _("stylesheet") || key_name == _("template")) {
if (!trim(value->toString()).empty()) {
card->stylesheet = StyleSheet::byGameAndName(game, value->toString());
if (card->stylesheet) card->styling_data.init(card->stylesheet->styling_fields);
}
return true;
}
//else if (key_name == _("id") || key_name == _("uid")) {
// card->uid = value->toString();
// return true;
//}
//else if (key_name == _("linked_card") || key_name == _("linked_card_1")) {
// card->linked_card_1 = value->toString();
// return true;
//}
//else if (key_name == _("linked_card_2")) {
// card->linked_card_2 = value->toString();
// return true;
//}
//else if (key_name == _("linked_card_3")) {
// card->linked_card_3 = value->toString();
// return true;
//}
//else if (key_name == _("linked_card_4")) {
// card->linked_card_4 = value->toString();
// return true;
//}
//else if (key_name == _("linked_relation") || key_name == _("linked_relation_1")) {
// card->linked_relation_1 = value->toString();
// return true;
//}
//else if (key_name == _("linked_relation_2")) {
// card->linked_relation_2 = value->toString();
// return true;
//}
//else if (key_name == _("linked_relation_3")) {
// card->linked_relation_3 = value->toString();
// return true;
//}
//else if (key_name == _("linked_relation_4")) {
// card->linked_relation_4 = value->toString();
// return true;
//}
return false;
}
inline static bool set_builtin_container(const Game& game, CardP& card, ScriptValueP& value, String key_name, bool ignore_field_not_found) {
// check if the given value is for a built-in field, if found set it and return true
key_name = unified_form(key_name);
if (key_name == _("notes") || key_name == _("note")) {
card->notes = value->toString();
return true;
}
else if (key_name == _("id") || key_name == _("uid")) {
card->uid = value->toString();
return true;
}
else if (key_name == _("linked_card") || key_name == _("linked_card_1")) {
card->linked_card_1 = value->toString();
return true;
}
else if (key_name == _("linked_card_2")) {
card->linked_card_2 = value->toString();
return true;
}
else if (key_name == _("linked_card_3")) {
card->linked_card_3 = value->toString();
return true;
}
else if (key_name == _("linked_card_4")) {
card->linked_card_4 = value->toString();
return true;
}
else if (key_name == _("linked_relation") || key_name == _("linked_relation_1")) {
card->linked_relation_1 = value->toString();
return true;
}
else if (key_name == _("linked_relation_2")) {
card->linked_relation_2 = value->toString();
return true;
}
else if (key_name == _("linked_relation_3")) {
card->linked_relation_3 = value->toString();
return true;
}
else if (key_name == _("linked_relation_4")) {
card->linked_relation_4 = value->toString();
return true;
}
else if (key_name == _("styling_data") || key_name == _("style_data") || key_name == _("stylesheet_data") || key_name == _("template_data") || key_name == _("styling")
|| key_name == _("styling_fields") || key_name == _("style_fields") || key_name == _("stylesheet_fields") || key_name == _("template_fields")
|| key_name == _("extra_data") || key_name == _("extra_fields") || key_name == _("extra_card_data") || key_name == _("extra_card_fields")) {
+29 -30
View File
@@ -184,15 +184,15 @@ inline static CardP json_to_mse_card(boost::json::object& jv, Set* set) {
read(card->time_created, jv, "time_created");
read(card->time_modified, jv, "time_modified");
read(card->notes, jv, "notes");
//read(card->uid, jv, "uid");
//read(card->linked_card_1, jv, "linked_card_1");
//read(card->linked_card_2, jv, "linked_card_2");
//read(card->linked_card_3, jv, "linked_card_3");
//read(card->linked_card_4, jv, "linked_card_4");
//read(card->linked_relation_1, jv, "linked_relation_1");
//read(card->linked_relation_2, jv, "linked_relation_2");
//read(card->linked_relation_3, jv, "linked_relation_3");
//read(card->linked_relation_4, jv, "linked_relation_4");
read(card->uid, jv, "uid");
read(card->linked_card_1, jv, "linked_card_1");
read(card->linked_card_2, jv, "linked_card_2");
read(card->linked_card_3, jv, "linked_card_3");
read(card->linked_card_4, jv, "linked_card_4");
read(card->linked_relation_1, jv, "linked_relation_1");
read(card->linked_relation_2, jv, "linked_relation_2");
read(card->linked_relation_3, jv, "linked_relation_3");
read(card->linked_relation_4, jv, "linked_relation_4");
// card fields
if (jv.contains("data") && jv["data"].is_object()) {
boost::json::object datav = jv["data"].as_object();
@@ -315,9 +315,8 @@ inline static ScriptValueP json_to_mse(const boost::json::value& jv, Set* set) {
return to_script(integer);
}
else if (jv.is_string()) {
std::string stdstring = boost::json::value_to<std::string>(jv);
String wxstring(stdstring.c_str(), wxConvUTF8);
return to_script(wxstring);
std::string string = boost::json::value_to<std::string>(jv);
return to_script(String(string.c_str()));
}
else if (jv.is_array()) {
boost::json::array array = jv.get_array();
@@ -364,7 +363,7 @@ inline static ScriptValueP json_to_mse(const String& string, Set* set) {
boost::json::parse_options options;
options.allow_invalid_utf8 = true;
boost::json::value jv = boost::json::parse(string.ToStdString(), ec, {}, options);
if(ec) queue_message(MESSAGE_ERROR, _ERROR_("json cant parse") + _("\n\n") + ec.message());
if(ec) return script_nil; //queue_message(MESSAGE_ERROR, _ERROR_("json cant parse") + _("\n\n") + ec.message());
return json_to_mse(jv, set);
}
catch (...) {
@@ -415,7 +414,7 @@ static void write(boost::json::object& out, const String& name, DelayedIndexMaps
if (!delayedindexmapv.empty()) out.emplace(name.ToStdString(), delayedindexmapv);
}
inline static boost::json::object mse_to_json(PackItemP& item) {
inline static boost::json::object mse_to_json(const PackItemP& item) {
boost::json::object itemv;
itemv.emplace("mse_object_type", "pack_item");
write(itemv, "name", item->name);
@@ -424,7 +423,7 @@ inline static boost::json::object mse_to_json(PackItemP& item) {
return itemv;
}
inline static boost::json::object mse_to_json(PackTypeP& pack) {
inline static boost::json::object mse_to_json(const PackTypeP& pack) {
boost::json::object packv;
packv.emplace("mse_object_type", "pack_type");
write(packv, "name", pack->name);
@@ -441,7 +440,7 @@ inline static boost::json::object mse_to_json(PackTypeP& pack) {
return packv;
}
inline static boost::json::object mse_to_json(KeywordP& keyword) {
inline static boost::json::object mse_to_json(const KeywordP& keyword) {
boost::json::object keywordv;
keywordv.emplace("mse_object_type", "keyword");
write(keywordv, "keyword", keyword->keyword);
@@ -452,22 +451,22 @@ inline static boost::json::object mse_to_json(KeywordP& keyword) {
return keywordv;
}
inline static boost::json::object mse_to_json(CardP& card, Set* set) {
inline static boost::json::object mse_to_json(const CardP& card, const Set* set) {
boost::json::object cardv;
cardv.emplace("mse_object_type", "card");
// built-in values
write(cardv, "time_created", card->time_created);
write(cardv, "time_modified", card->time_modified);
write(cardv, "notes", card->notes);
//write(cardv, "uid", card->uid);
//write(cardv, "linked_card_1", card->linked_card_1);
//write(cardv, "linked_card_2", card->linked_card_2);
//write(cardv, "linked_card_3", card->linked_card_3);
//write(cardv, "linked_card_4", card->linked_card_4);
//write(cardv, "linked_relation_1", card->linked_relation_1);
//write(cardv, "linked_relation_2", card->linked_relation_2);
//write(cardv, "linked_relation_3", card->linked_relation_3);
//write(cardv, "linked_relation_4", card->linked_relation_4);
write(cardv, "uid", card->uid);
write(cardv, "linked_card_1", card->linked_card_1);
write(cardv, "linked_card_2", card->linked_card_2);
write(cardv, "linked_card_3", card->linked_card_3);
write(cardv, "linked_card_4", card->linked_card_4);
write(cardv, "linked_relation_1", card->linked_relation_1);
write(cardv, "linked_relation_2", card->linked_relation_2);
write(cardv, "linked_relation_3", card->linked_relation_3);
write(cardv, "linked_relation_4", card->linked_relation_4);
// card fields
write(cardv, "data", card->data);
// stylesheet
@@ -494,7 +493,7 @@ inline static boost::json::object mse_to_json(CardP& card, Set* set) {
return cardv;
}
inline static boost::json::object mse_to_json(Set* set) {
inline static boost::json::object mse_to_json(const Set* set) {
boost::json::object setv;
setv.emplace("mse_object_type", "set");
// built-in values
@@ -509,19 +508,19 @@ inline static boost::json::object mse_to_json(Set* set) {
write(setv, "styling", set->styling_data);
// cards
boost::json::array cardsv;
for (auto card : set->cards) {
for (const CardP& card : set->cards) {
cardsv.emplace_back(mse_to_json(card, set));
}
setv.emplace("cards", cardsv);
// keywords
boost::json::array keywordsv;
for (auto keyword : set->keywords) {
for (const KeywordP& keyword : set->keywords) {
keywordsv.emplace_back(mse_to_json(keyword));
}
if (!keywordsv.empty()) setv.emplace("keywords", keywordsv);
// pack types
boost::json::array pack_typesv;
for (auto pack_type : set->pack_types) {
for (const PackTypeP& pack_type : set->pack_types) {
pack_typesv.emplace_back(mse_to_json(pack_type));
}
if (!pack_typesv.empty()) setv.emplace("pack_types", pack_typesv);
+1 -1
View File
@@ -31,7 +31,7 @@ Context& SetScriptContext::getContext(const StyleSheetP& stylesheet) {
auto it = contexts.try_emplace(stylesheet.get());
Context& ctx = it.first->second;
if (it.second) {
// we created a new context
// try_emplace created a new context, we now initialize it
// variables
// NOTE: do not use a smart pointer for the pointer to the set, because the set owns this
// which would lead to a reference cycle.
+2 -1
View File
@@ -129,7 +129,8 @@ public:
inline bool isScripted() const { return script; }
/// Has this value been read from a Reader?
inline bool hasBeenRead() const { return !script.unparsed.empty(); }
inline String unparsed() const { return script.unparsed; }
/// Updates the value by executing the script, returns true if the value has changed
inline bool update(Context& ctx) {
return script.invokeOn(ctx, value);