diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/livecode/api/context.cpp | 89 | ||||
| -rw-r--r-- | src/livecode/context.cpp | 14 | ||||
| -rw-r--r-- | src/livecode/context.h | 1 | ||||
| -rw-r--r-- | src/livecode/script.cpp | 5 |
4 files changed, 105 insertions, 4 deletions
diff --git a/src/livecode/api/context.cpp b/src/livecode/api/context.cpp index f5da3f7cd..0c062ec50 100644 --- a/src/livecode/api/context.cpp +++ b/src/livecode/api/context.cpp @@ -36,6 +36,87 @@ extern "C" Janet cfun_input_arrow(int32_t argc, Janet *argv) { return janet_wrap_nil(); } +SPCSSAttr *get_css(Janet table) { + JanetKV const *kv = NULL; + SPCSSAttr *css = sp_repr_css_attr_new(); + JanetDictView style = janet_getdictionary(&table, 0); + while ((kv = janet_dictionary_next(style.kvs, style.cap, kv))) { + if (!janet_checktype(kv->key, JANET_KEYWORD)) { + janet_panic(":style keys have to be keywords"); + } + if (!janet_checktype(kv->value, JANET_STRING)) { + janet_panic(":style values have to be strings"); + } + char const *key = (char const *)janet_unwrap_keyword(kv->key); + char const *value = (char const *)janet_unwrap_string(kv->value); + sp_repr_css_set_property(css, key, value); + } + + return css; +} + +Inkscape::XML::Node *get_node(int32_t argc, Janet *argv) { + janet_fixarity(argc, 2); + char const *element = (char const *)janet_unwrap_keyword(argv[0]); + JanetDictView attrs = janet_getdictionary(argv, 1); + + Inkscape::XML::Node *repr = ctx().createElement(element); + + g_message("+ new node '%s'", element); + + JanetKV const *kv = NULL; + while ((kv = janet_dictionary_next(attrs.kvs, attrs.cap, kv))) { + if (!janet_checktype(kv->key, JANET_KEYWORD)) { + janet_panic("attribute keys have to be keywords"); + } + char const *key = (char const *)janet_unwrap_keyword(kv->key); + + switch (janet_type(kv->value)) { + case JANET_NUMBER: + g_message(" setting '%s' = %f", key, janet_unwrap_number(kv->value)); + sp_repr_set_svg_double(repr, key, janet_unwrap_number(kv->value)); + break; + case JANET_STRING: + g_message(" setting '%s' = '%s'", key, janet_unwrap_string(kv->value)); + repr->setAttribute(key, (gchar const *)janet_unwrap_string(kv->value)); + break; + case JANET_STRUCT: + case JANET_TABLE: { + if (strcmp(key, "style") != 0) { + janet_panic("struct/table values are only allowed for :style"); + } + + Glib::ustring css_str; + SPCSSAttr *css = get_css(kv->value); + sp_repr_css_write_string(css, css_str); + sp_repr_css_attr_unref(css); + repr->setAttribute("style", css_str.c_str()); + g_message(" setting '%s' = '%s'", key, css_str.c_str()); + break; + } + default: + janet_panic("unsupported value type in attributes dict!"); + break; + } + } + + return repr; +} + +extern "C" Janet cfun_draw_doc(int32_t argc, Janet *argv) { + char const *id = janet_getcstring(argv, 0); + ctx().draw_doc(id, get_node(argc - 1, argv + 1)); + g_message("+ draw_doc id=%s", id); + return argv[0]; +} + +extern "C" Janet cfun_draw_ui(int32_t argc, Janet *argv) { + char const *id = janet_getcstring(argv, 0); + ctx().draw_ui(id, get_node(argc - 1, argv + 1)); + g_message("+ draw_ui id=%s", id); + return argv[0]; +} + const JanetReg it_cfuns[] = { { "input/point", cfun_input_point, @@ -52,6 +133,14 @@ const JanetReg it_cfuns[] = { "(input/arrow id from to)\n\nMake a modifiable arrow between from and to\n" "This function mutates from and to." }, + { + "draw/doc", cfun_draw_doc, + "(draw/doc id elem [attrs])\n\nDraw an SVG element to the document layer" + }, + { + "draw/ui", cfun_draw_ui, + "(draw/ui id elem [attrs])\n\nDraw an SVG element to the UI layer" + }, {NULL, NULL, NULL} }; diff --git a/src/livecode/context.cpp b/src/livecode/context.cpp index b63641411..040e23ac7 100644 --- a/src/livecode/context.cpp +++ b/src/livecode/context.cpp @@ -52,6 +52,15 @@ Context::~Context() { } } + +Inkscape::XML::Node *Context::createElement(gchar const *element) { + SPDocument *doc = desktop->getDocument(); + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + + Inkscape::XML::Node *repr = xml_doc->createElement("svg:rect"); + return repr; +} + Inkscape::XML::Node *Context::make_rect(Geom::Rect const &rect, SPCSSAttr *css) { SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); @@ -283,19 +292,18 @@ void Context::setup_frame() { Inkscape::GC::release(rdoc); ui_root = SP_ITEM(desktop->currentLayer()->appendChildRepr(rui)); - ui_root->doWriteTransform(ui2doc(), nullptr, true); + doc_root->updateRepr(); Inkscape::GC::release(rui); } void Context::finish_frame() { doc_root->updateRepr(); - ui_root->updateRepr(); + ui_root->doWriteTransform(ui2doc(), nullptr, true); _mouse.finish_frame(); } void Context::load_script(Glib::ustring const &path) { g_message("loading script %s", path.c_str()); - _script = nullptr; try { _script.reset(new Script(env, path)); diff --git a/src/livecode/context.h b/src/livecode/context.h index 520074968..f7fb1a537 100644 --- a/src/livecode/context.h +++ b/src/livecode/context.h @@ -36,6 +36,7 @@ public: Context(SPDesktop *desktop); ~Context(); + Inkscape::XML::Node *createElement(gchar const *element); Inkscape::XML::Node *make_rect(Geom::Rect const &rect, SPCSSAttr *css = nullptr); Inkscape::XML::Node *make_line(Geom::Point const &p1, Geom::Point const &p2, SPCSSAttr *css = nullptr); Inkscape::XML::Node *make_path(Glib::ustring d, Geom::Point const &pos = Geom::Point(), SPCSSAttr *css = nullptr); diff --git a/src/livecode/script.cpp b/src/livecode/script.cpp index d4761847a..90d0de1cd 100644 --- a/src/livecode/script.cpp +++ b/src/livecode/script.cpp @@ -27,7 +27,10 @@ Script::Script(JanetTable *env, std::string const &path) void Script::frame() { if (function) { Janet result; - janet_pcall(function, 0, NULL, &result, NULL); + JanetSignal status = janet_pcall(function, 0, NULL, &result, NULL); + if (status == JANET_SIGNAL_ERROR && janet_checktype(result, JANET_STRING)) { + g_message("error executing Janet Script: %s", (gchar const *)janet_unwrap_string(result)); + } } } |
