diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/livecode/api/api.h | 2 | ||||
| -rw-r--r-- | src/livecode/api/context.cpp | 43 | ||||
| -rw-r--r-- | src/livecode/api/input.cpp | 1 | ||||
| -rw-r--r-- | src/livecode/api/point.cpp | 27 | ||||
| -rw-r--r-- | src/livecode/context.cpp | 116 | ||||
| -rw-r--r-- | src/livecode/context.h | 34 | ||||
| -rw-r--r-- | src/ui/tools/livecode-tool.cpp | 4 |
7 files changed, 164 insertions, 63 deletions
diff --git a/src/livecode/api/api.h b/src/livecode/api/api.h index 94694ca56..4df3f40be 100644 --- a/src/livecode/api/api.h +++ b/src/livecode/api/api.h @@ -21,7 +21,7 @@ extern const JanetAbstractType geom_point_type; Janet janet_wrap_point(Geom::Point const &x); Janet janet_wrap_point(Geom::IntPoint const &x); -Geom::Point janet_unwrap_point(Janet x); +Geom::Point &janet_unwrap_point(Janet x); /* input.cpp */ void janet_lib_input(JanetTable *env); diff --git a/src/livecode/api/context.cpp b/src/livecode/api/context.cpp index 43c6881d1..f5da3f7cd 100644 --- a/src/livecode/api/context.cpp +++ b/src/livecode/api/context.cpp @@ -13,8 +13,51 @@ Context &ctx() { return *_context; } +extern "C" Janet cfun_input_point(int32_t argc, Janet *argv) { + janet_fixarity(argc, 2); + ctx().input_point(janet_getcstring(argv, 0), + &janet_unwrap_point(argv[1])); + return janet_wrap_nil(); +} + +extern "C" Janet cfun_input_line(int32_t argc, Janet *argv) { + janet_fixarity(argc, 3); + ctx().input_line(janet_getcstring(argv, 0), + &janet_unwrap_point(argv[1]), + &janet_unwrap_point(argv[2])); + return janet_wrap_nil(); +} + +extern "C" Janet cfun_input_arrow(int32_t argc, Janet *argv) { + janet_fixarity(argc, 3); + ctx().input_arrow(janet_getcstring(argv, 0), + &janet_unwrap_point(argv[1]), + &janet_unwrap_point(argv[2])); + return janet_wrap_nil(); +} + +const JanetReg it_cfuns[] = { + { + "input/point", cfun_input_point, + "(input/point id p)\n\nMake p modifiable via a handle.\n" + "This function mutates p." + }, + { + "input/line", cfun_input_line, + "(input/line id p1 p2)\n\nMake a modifiable line between p1 and p2\n" + "This function mutates p1 and p2." + }, + { + "input/arrow", cfun_input_arrow, + "(input/arrow id from to)\n\nMake a modifiable arrow between from and to\n" + "This function mutates from and to." + }, + {NULL, NULL, NULL} +}; + void janet_lib_context(JanetTable *env, Context &context) { _context = &context; + janet_cfuns(env, NULL, it_cfuns); } } diff --git a/src/livecode/api/input.cpp b/src/livecode/api/input.cpp index 0fc820bbd..1677e68eb 100644 --- a/src/livecode/api/input.cpp +++ b/src/livecode/api/input.cpp @@ -106,6 +106,7 @@ const JanetReg it_cfuns[] = { void janet_lib_input(JanetTable *env) { + janet_printf("yoloading"); janet_cfuns(env, NULL, it_cfuns); } diff --git a/src/livecode/api/point.cpp b/src/livecode/api/point.cpp index 6eab6af1d..25d03d4bb 100644 --- a/src/livecode/api/point.cpp +++ b/src/livecode/api/point.cpp @@ -10,13 +10,13 @@ extern "C" void geom_point_set(void *p, Janet key, Janet value); extern "C" void geom_point_tostring(void *p, JanetBuffer *buffer) { std::stringstream stream; - stream << "<2geom/point " << *static_cast<Geom::Point *>(p) << ">"; + stream << "<geom/point " << *static_cast<Geom::Point *>(p) << ">"; janet_buffer_push_cstring(buffer, stream.str().c_str()); } const JanetAbstractType geom_point_type = { - "2geom/point", + "geom/point", NULL, NULL, geom_point_get, @@ -39,7 +39,7 @@ Janet janet_wrap_point(Geom::IntPoint const &x) { return janet_wrap_abstract(box); } -Geom::Point janet_unwrap_point(Janet x) { +Geom::Point &janet_unwrap_point(Janet x) { if (janet_checktype(x, JANET_ABSTRACT)) { void *abst = janet_unwrap_abstract(x); if (janet_abstract_type(abst) == &geom_point_type) @@ -62,17 +62,6 @@ Geom::Point janet_unwrap_point_or_scalar(Janet x) { janet_panic("expected a geom/point"); } - -Geom::Point& janet_unwrap_point_ref(Janet x) { - if (janet_checktype(x, JANET_ABSTRACT)) { - void *abst = janet_unwrap_abstract(x); - if (janet_abstract_type(abst) == &geom_point_type) - return *(Geom::Point *)abst; - } - - janet_panic("expected a geom/point"); -} - extern "C" Janet cfun_geom_point_new(int32_t argc, Janet *argv) { janet_arity(argc, 0, 2); double x = 0; @@ -89,7 +78,7 @@ extern "C" Janet cfun_geom_point_new(int32_t argc, Janet *argv) { const JanetReg it_cfuns[] = { { - "point", cfun_geom_point_new, + "geom/point", cfun_geom_point_new, "(geom/point x y)\n\nCreate a Point from x/y coordinate values." }, {NULL, NULL, NULL} @@ -177,15 +166,15 @@ static Janet cfun_geom_point_div_mut(int32_t argc, Janet *argv) { static Janet cfun_geom_point_eq(int32_t argc, Janet *argv) { janet_fixarity(argc, 2); - Geom::Point& v1 = janet_unwrap_point_ref(argv[0]); - Geom::Point& v2 = janet_unwrap_point_ref(argv[1]); + Geom::Point &v1 = janet_unwrap_point(argv[0]); + Geom::Point &v2 = janet_unwrap_point(argv[1]); return janet_wrap_boolean(v1 == v2); } static Janet cfun_geom_point_lt(int32_t argc, Janet *argv) { janet_fixarity(argc, 2); - Geom::Point& v1 = janet_unwrap_point_ref(argv[0]); - Geom::Point& v2 = janet_unwrap_point_ref(argv[1]); + Geom::Point &v1 = janet_unwrap_point(argv[0]); + Geom::Point &v2 = janet_unwrap_point(argv[1]); return janet_wrap_boolean(v1 < v2); } diff --git a/src/livecode/context.cpp b/src/livecode/context.cpp index a4b59e9b0..a22191400 100644 --- a/src/livecode/context.cpp +++ b/src/livecode/context.cpp @@ -9,7 +9,7 @@ * Released under GNU GPL v2+, read the file 'COPYING' for more information. */ -#include <giomm/file.h> +#include <memory> #include "svg/stringstream.h" #include "svg/svg-color.h" @@ -23,12 +23,56 @@ namespace Inkscape { namespace Livecode { +Script::Script(JanetTable *env, std::string const &path) + : env(env) + , function(nullptr) + , file(Gio::File::create_for_path(path)) + , monitor(file->monitor_file()) +{ + monitor->signal_changed().connect(sigc::mem_fun(this, &Script::file_changed)); + reload(); +} + +void Script::frame() { + if (function) { + Janet result; + janet_pcall(function, 0, NULL, &result, NULL); + } +} + +void Script::commit() { +} + +void Script::reload() { + try { + uint8_t *data; + size_t length; + file->load_contents((char *&)data, (gsize &)length); + + Janet result; + janet_dobytes(env, data, length, file->get_path().c_str(), &result); + if (janet_checktype(result, JANET_FUNCTION)) { + function = janet_unwrap_function(result); + } else { + g_message("Janet script didn't return a function"); + } + } catch (...) { + g_message("error loading file"); + } +} + +void Script::file_changed(const Glib::RefPtr<Gio::File>& file, + const Glib::RefPtr<Gio::File>& other_file, + Gio::FileMonitorEvent event) +{ + reload(); +} + Context::Context(SPDesktop *desktop) : desktop(desktop) + , _mouse(*this) , doc_root(nullptr) , ui_root(nullptr) - , _mouse(*this) - , script_function(nullptr) { janet_init(); @@ -122,8 +166,8 @@ Inkscape::XML::Node *Context::make_arrow(Geom::Point const &from, Geom::Point co Geom::Point back = from - to; back.normalize(); - Geom::Point const cross_a = back.cw() + back * 2.0; - Geom::Point const cross_b = back.cw() + back * 2.0; + Geom::Point const cross_a = back.cw() * 5.0 + back * 10.0; + Geom::Point const cross_b = back.ccw() * 5.0 + back * 10.0; gchar* d = g_strdup_printf("M %f,%f %f,%f l %f,%f M %f,%f l %f,%f", from.x(), from.y(), @@ -134,14 +178,12 @@ Inkscape::XML::Node *Context::make_arrow(Geom::Point const &from, Geom::Point co repr->setAttribute("d", d); g_free(d); - Glib::ustring css_str; if (css) { + Glib::ustring css_str; sp_repr_css_write_string(css, css_str); sp_repr_css_attr_unref(css); - } else { - css_str = "stroke: #000000;"; + repr->setAttribute("style", css_str.c_str()); } - repr->setAttribute("style", css_str.c_str()); return repr; } @@ -200,7 +242,12 @@ bool Context::input_line(Glib::ustring const &id, Geom::Point *p1, Geom::Point * if (input_point(id + "_p2", p2)) { change = true; } - draw_doc("", make_line(*p1, *p2)); + + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, "stroke-width", "1"); + sp_repr_css_set_property(css, "stroke", "#000000"); + sp_repr_css_set_property(css, "fill", "none"); + draw_doc("", make_line(*p1, *p2, css)); return change; } @@ -212,7 +259,12 @@ bool Context::input_arrow(Glib::ustring const &id, Geom::Point *from, Geom::Poin if (input_point(id + "_to", to)) { change = true; } - draw_doc("", make_line(*from, *to)); + + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, "stroke-width", "1"); + sp_repr_css_set_property(css, "stroke", "#000000"); + sp_repr_css_set_property(css, "fill", "none"); + draw_doc("", make_arrow(*from, *to, css)); return change; } @@ -243,6 +295,16 @@ void Context::push_event(GdkEvent *event) { _mouse.push_event(event); } +void Context::frame() { + setup_frame(); + + if (_script) { + _script->frame(); + } + + finish_frame(); +} + void Context::setup_frame() { hot = ""; @@ -267,27 +329,6 @@ void Context::setup_frame() { ui_root = SP_ITEM(desktop->currentLayer()->appendChildRepr(rui)); ui_root->doWriteTransform(ui2doc(), nullptr, true); Inkscape::GC::release(rui); - - if (script_file) { - try { - char *data; - gsize length; - script_file->load_contents(data, length); - - Janet result; - janet_dobytes(env, (uint8_t *)data, length, script_file->get_path().c_str(), &result); - if (janet_checktype(result, JANET_FUNCTION)) { - script_function = janet_unwrap_function(result); - } - } catch (...) { - g_message("error loading file"); - } - } - - if (script_function) { - Janet result; - janet_pcall(script_function, 0, NULL, &result, NULL); - } } void Context::finish_frame() { @@ -297,8 +338,15 @@ void Context::finish_frame() { } void Context::load_script(Glib::ustring const &path) { - g_message("loading file %s", path.c_str()); - script_file = Gio::File::create_for_path(path); + g_message("loading script %s", path.c_str()); + _script = nullptr; + + try { + _script.reset(new Script(env, path)); + g_message("loaded."); + } catch (...) { + g_message("error creating script"); + } } void Context::draw_doc(Glib::ustring const &id, Inkscape::XML::Node *repr) { diff --git a/src/livecode/context.h b/src/livecode/context.h index fb6b59ff7..4ebb73609 100644 --- a/src/livecode/context.h +++ b/src/livecode/context.h @@ -16,6 +16,8 @@ #include <2geom/point.h> #include <2geom/rect.h> #include <gdk/gdk.h> +#include <giomm/file.h> +#include <giomm/filemonitor.h> #include <janet.h> #include "xml/repr.h" @@ -26,15 +28,30 @@ class SPDocument; class SPItem; -namespace Gio { -class File; -}; - namespace Inkscape { namespace Livecode { class Mouse; +class Script { +public: + Script(JanetTable *env, std::string const &path); + + void frame(); + void commit(); + +private: + JanetTable *env; + JanetFunction *function; + Glib::RefPtr<Gio::File> file; + Glib::RefPtr<Gio::FileMonitor> monitor; + + void reload(); + void file_changed(const Glib::RefPtr<Gio::File>& file, + const Glib::RefPtr<Gio::File>& other_file, + Gio::FileMonitorEvent event); +}; + class Context { public: Context(SPDesktop *desktop); @@ -54,8 +71,7 @@ public: void draw_ui(Glib::ustring const &id, Inkscape::XML::Node *item); void push_event(GdkEvent *event); - void setup_frame(); - void finish_frame(); + void frame(); inline Geom::Affine ui2dt() const { return doc_root->i2doc_affine(); @@ -81,13 +97,15 @@ public: void load_script(Glib::ustring const &path); private: + void setup_frame(); + void finish_frame(); + SPDesktop *desktop; SPItem *doc_root, *ui_root; JanetTable *env; - JanetFunction *script_function; - Glib::RefPtr<Gio::File> script_file; + std::unique_ptr<Script> _script; Mouse _mouse; Glib::ustring hot, active; diff --git a/src/ui/tools/livecode-tool.cpp b/src/ui/tools/livecode-tool.cpp index 8b096dbf0..ae332b13c 100644 --- a/src/ui/tools/livecode-tool.cpp +++ b/src/ui/tools/livecode-tool.cpp @@ -100,13 +100,15 @@ static Geom::Rect rect(Geom::Point(20, 200), Geom::Point(220, 20)); bool LivecodeTool::handle_tick(Glib::RefPtr<Gdk::FrameClock> const &frame_clock) { - context.setup_frame(); + context.frame(); +/* context.input_point("p", &p); context.input_arrow("a->b", &a, &b); context.input_rect("rect", &rect); context.finish_frame(); +*/ return true; } |
