1 static Xcls_WindowRooView _WindowRooView;
3 public class Xcls_WindowRooView : Object
6 private Xcls_WindowRooView _this;
8 public static Xcls_WindowRooView singleton()
10 if (_WindowRooView == null) {
11 _WindowRooView= new Xcls_WindowRooView();
13 return _WindowRooView;
15 public Xcls_notebook notebook;
16 public Xcls_label_preview label_preview;
17 public Xcls_label_code label_code;
18 public Xcls_paned paned;
19 public Xcls_viewbox viewbox;
20 public Xcls_AutoRedraw AutoRedraw;
21 public Xcls_viewcontainer viewcontainer;
22 public Xcls_view view;
23 public Xcls_inspectorcontainer inspectorcontainer;
24 public Xcls_sourceview sourceview;
25 public Xcls_buffer buffer;
28 public Gtk.Widget lastObj;
30 public int last_search_end;
31 public Gtk.SourceSearchContext searchcontext;
32 public JsRender.JsRender file;
34 public Xcls_MainWindow main_window;
37 public Xcls_WindowRooView()
40 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
45 this.last_search_end = 0;
50 this.el.hexpand = true;
51 var child_0 = new Xcls_notebook( _this );
53 this.el.pack_start ( child_0.el , true,true,0 );
56 // user defined functions
57 public void scroll_to_line (int line) {
58 this.notebook.el.page = 1;// code preview...
60 GLib.Timeout.add(500, () => {
65 var buf = this.sourceview.el.get_buffer();
67 var sbuf = (Gtk.SourceBuffer) buf;
71 sbuf.get_iter_at_line(out iter, line);
72 this.sourceview.el.scroll_to_iter(iter, 0.1f, true, 0.0f, 0.5f);
78 public void createThumb () {
81 if (this.file == null) {
84 if (this.notebook.el.page > 0 ) {
88 var filename = this.file.getIconFileName(false);
90 var win = this.el.get_parent_window();
91 var width = win.get_width();
92 // var height = win.get_height();
94 Gdk.Pixbuf screenshot = Gdk.pixbuf_get_from_window(win, 0, 0, width, this.paned.el.position);
95 screenshot.save(filename,"png");
105 public void loadFile (JsRender.JsRender file)
108 this.view.renderJS(true);
109 this.notebook.el.page = 0;// gtk preview
110 this.sourceview.loadFile();
113 public int search (string txt) {
114 this.notebook.el.page = 1;
115 var s = new Gtk.SourceSearchSettings();
116 var buf = (Gtk.SourceBuffer) this.sourceview.el.get_buffer();
117 this.searchcontext = new Gtk.SourceSearchContext(buf,s);
118 this.searchcontext.set_highlight(true);
119 s.set_search_text(txt);
121 Gtk.TextIter beg, st,en;
123 buf.get_start_iter(out beg);
124 this.searchcontext.forward(beg, out st, out en);
125 this.last_search_end = 0;
126 return this.searchcontext.get_occurrences_count();
130 public void requestRedraw () {
131 this.view.renderJS(false);
132 this.sourceview.loadFile();
134 public void forwardSearch (bool change_focus) {
136 if (this.searchcontext == null) {
139 this.notebook.el.page = 1;
140 Gtk.TextIter beg, st,en, stl;
142 var buf = this.sourceview.el.get_buffer();
143 buf.get_iter_at_offset(out beg, this.last_search_end);
144 if (!this.searchcontext.forward(beg, out st, out en)) {
145 this.last_search_end = 0;
148 this.last_search_end = en.get_offset();
150 this.sourceview.el.grab_focus();
152 buf.place_cursor(st);
153 var ln = st.get_line();
154 buf.get_iter_at_line(out stl,ln);
156 this.sourceview.el.scroll_to_iter(stl, 0.0f, true, 0.0f, 0.5f);
161 var node = _this.file.lineToNode(ln+1);
164 //print("can not find node\n");
167 var prop = node.lineToProp(ln+1);
168 print("prop : %s", prop == null ? "???" : prop);
171 // ---------- this selects the tree's node...
173 var ltree = _this.main_window.windowstate.left_tree;
174 var tp = ltree.model.treePathFromNode(node);
175 print("got tree path %s\n", tp);
179 //_this.sourceview.allow_node_scroll = false; /// block node scrolling..
182 //print("changing cursor on tree..\n");
186 // let's try allowing editing on the methods.
187 // a little klunky at present..
188 _this.sourceview.prop_selected = "";
190 //see if we can find it..
191 var kv = prop.split(":");
194 //var k = prop.get_key(kv[1]);
195 // fixme -- need to determine if it's an editable property...
196 _this.sourceview.prop_selected = prop;
198 } else if (kv[0] == "l") {
199 _this.sourceview.prop_selected = prop;
203 ltree.view.setCursor(tp, "editor");
204 // ltree.view.el.set_cursor(new Gtk.TreePath.from_string(tp), null, false);
205 _this.sourceview.nodeSelected(node,false);
207 // scrolling is disabled... as node selection calls scroll 10ms after it changes.
208 // GLib.Timeout.add_full(GLib.Priority.DEFAULT,100 , () => {
209 // this.allow_node_scroll = true;
225 public class Xcls_notebook : Object
227 public Gtk.Notebook el;
228 private Xcls_WindowRooView _this;
234 public Xcls_notebook(Xcls_WindowRooView _owner )
237 _this.notebook = this;
238 this.el = new Gtk.Notebook();
242 // set gobject values
243 var child_0 = new Xcls_label_preview( _this );
245 var child_1 = new Xcls_label_code( _this );
247 var child_2 = new Xcls_paned( _this );
249 this.el.append_page ( child_2.el , _this.label_preview.el );
250 var child_3 = new Xcls_ScrolledWindow14( _this );
252 this.el.append_page ( child_3.el , _this.label_code.el );
255 // user defined functions
257 public class Xcls_label_preview : Object
260 private Xcls_WindowRooView _this;
266 public Xcls_label_preview(Xcls_WindowRooView _owner )
269 _this.label_preview = this;
270 this.el = new Gtk.Label( "Preview" );
274 // set gobject values
277 // user defined functions
280 public class Xcls_label_code : Object
283 private Xcls_WindowRooView _this;
289 public Xcls_label_code(Xcls_WindowRooView _owner )
292 _this.label_code = this;
293 this.el = new Gtk.Label( "Preview Generated Code" );
297 // set gobject values
300 // user defined functions
303 public class Xcls_paned : Object
306 private Xcls_WindowRooView _this;
312 public Xcls_paned(Xcls_WindowRooView _owner )
316 this.el = new Gtk.Paned( Gtk.Orientation.VERTICAL );
320 // set gobject values
321 var child_0 = new Xcls_viewbox( _this );
323 this.el.pack1 ( child_0.el , true,true );
324 var child_1 = new Xcls_inspectorcontainer( _this );
326 this.el.pack2 ( child_1.el , true,true );
329 // user defined functions
331 public class Xcls_viewbox : Object
334 private Xcls_WindowRooView _this;
340 public Xcls_viewbox(Xcls_WindowRooView _owner )
343 _this.viewbox = this;
344 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
348 // set gobject values
349 this.el.homogeneous = false;
350 var child_0 = new Xcls_Box7( _this );
352 this.el.pack_start ( child_0.el , false,true,0 );
353 var child_1 = new Xcls_viewcontainer( _this );
355 this.el.pack_end ( child_1.el , true,true,0 );
358 // user defined functions
360 public class Xcls_Box7 : Object
363 private Xcls_WindowRooView _this;
369 public Xcls_Box7(Xcls_WindowRooView _owner )
372 this.el = new Gtk.Box( Gtk.Orientation.HORIZONTAL, 0 );
376 // set gobject values
377 this.el.homogeneous = true;
378 this.el.height_request = 20;
379 this.el.vexpand = false;
380 var child_0 = new Xcls_Button8( _this );
382 this.el.pack_start ( child_0.el , false,false,0 );
383 var child_1 = new Xcls_AutoRedraw( _this );
385 this.el.pack_start ( child_1.el , false,false,0 );
386 var child_2 = new Xcls_Button10( _this );
388 this.el.pack_start ( child_2.el , false,false,0 );
391 // user defined functions
393 public class Xcls_Button8 : Object
395 public Gtk.Button el;
396 private Xcls_WindowRooView _this;
402 public Xcls_Button8(Xcls_WindowRooView _owner )
405 this.el = new Gtk.Button();
409 // set gobject values
410 this.el.label = "Redraw";
413 this.el.clicked.connect( ( ) => {
414 _this.view.renderJS( true);
418 // user defined functions
421 public class Xcls_AutoRedraw : Object
423 public Gtk.CheckButton el;
424 private Xcls_WindowRooView _this;
430 public Xcls_AutoRedraw(Xcls_WindowRooView _owner )
433 _this.AutoRedraw = this;
434 this.el = new Gtk.CheckButton();
438 // set gobject values
439 this.el.active = true;
440 this.el.label = "Auto Redraw On";
443 this.el.toggled.connect( (state) => {
444 this.el.set_label(this.el.active ? "Auto Redraw On" : "Auto Redraw Off");
448 // user defined functions
451 public class Xcls_Button10 : Object
453 public Gtk.Button el;
454 private Xcls_WindowRooView _this;
460 public Xcls_Button10(Xcls_WindowRooView _owner )
463 this.el = new Gtk.Button();
467 // set gobject values
468 this.el.label = "Full Redraw";
471 this.el.clicked.connect( () => {
472 _this.view.redraws = 99;
473 _this.view.el.web_context.clear_cache();
474 //_this.view.renderJS(true);
475 FakeServerCache.clear();
481 // user defined functions
485 public class Xcls_viewcontainer : Object
487 public Gtk.ScrolledWindow el;
488 private Xcls_WindowRooView _this;
494 public Xcls_viewcontainer(Xcls_WindowRooView _owner )
497 _this.viewcontainer = this;
498 this.el = new Gtk.ScrolledWindow( null, null );
502 // set gobject values
503 this.el.shadow_type = Gtk.ShadowType.IN;
504 var child_0 = new Xcls_view( _this );
506 this.el.add ( child_0.el );
510 this.el.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
513 // user defined functions
515 public class Xcls_view : Object
517 public WebKit.WebView el;
518 private Xcls_WindowRooView _this;
522 public string renderedData;
523 public bool refreshRequired;
524 public WebKit.WebInspector inspector;
527 public GLib.DateTime lastRedraw;
528 public string runhtml;
529 public bool pendingRedraw;
532 public Xcls_view(Xcls_WindowRooView _owner )
536 this.el = new WebKit.WebView();
539 this.renderedData = "";
540 this.refreshRequired = false;
543 this.lastRedraw = null;
545 this.pendingRedraw = false;
547 // set gobject values
552 // this may not work!?
553 var settings = this.el.get_settings();
554 settings.enable_developer_extras = true;
557 var fs= new FakeServer(this.el);
559 // this was an attempt to change the url perms.. did not work..
560 // settings.enable_file_access_from_file_uris = true;
561 // settings.enable_offline_web_application_cache - true;
562 // settings.enable_universal_access_from_file_uris = true;
569 // FIXME - base url of script..
570 // we need it so some of the database features work.
571 this.el.load_html( "Render not ready" ,
572 //fixme - should be a config option!
573 // or should we catch stuff and fix it up..
574 "http://localhost/app.Builder/"
578 //this.el.open('file:///' + __script_path__ + '/../builder.html');
583 Gtk.DestDefaults.MOTION | Gtk.DestDefaults.HIGHLIGHT,
584 null, // list of targets
585 Gdk.DragAction.COPY // what to do with data after dropped
588 // print("RB: TARGETS : " + LeftTree.atoms["STRING"]);
589 Gtk.drag_dest_set_target_list(this.el, this.get('/Window').targetList);
591 GLib.Timeout.add_seconds(1, () =>{
592 //print("run refresh?");
593 if (this.el == null) {
604 this.el.script_dialog.connect( (dialog) => {
607 if (this.el == null) {
611 var msg = dialog.get_message();
612 if (msg.length < 4) {
615 if (msg.substring(0,4) != "IPC:") {
618 var ar = msg.split(":", 3);
625 print("GOT saveHTML %d?\n", ar[2].length);
626 _this.file.saveHTML(ar[2]);
633 this.el.show.connect( ( ) => {
634 this.initInspector();;
636 this.el.drag_drop.connect( ( ctx, x, y,time, ud) => {
639 print("TARGET: drag-drop");
640 var is_valid_drop_site = true;
645 w, // will receive 'drag-data-received' signal
646 ctx, /* represents the current state of the DnD
647 this.get('/Window').atoms["STRING"], /* the target type we want
652 /* No target offered by source => error
655 return is_valid_drop_site;
658 this.el.load_changed.connect( (le) => {
659 if (le != WebKit.LoadEvent.FINISHED) {
662 if (this.runjs.length < 1) {
665 // this.el.run_javascript(this.runjs, null);
666 FakeServerCache.remove( this.runjs);
671 // user defined functions
672 public void reInit () {
674 // if this happens destroy the webkit..
676 this.el.stop_loading();
678 if (_this.viewbox.el.get_parent() == null) {
683 _this.viewbox.el.remove(_this.viewcontainer.el);
684 _this.paned.el.remove(_this.inspectorcontainer.el);
686 // destory seems to cause problems.
688 //_this.viewcontainer.el.destroy();
689 //_this.inspectorcontainer.el.destroy();
690 var inv =new Xcls_inspectorcontainer(_this);
692 _this.paned.el.pack2(inv.el,true,true);
696 var nv =new Xcls_viewcontainer(_this);
698 _this.viewbox.el.pack_end(nv.el,true,true,0);
703 //while(Gtk.events_pending ()) Gtk.main_iteration ();
704 //_this.view.renderJS(true);
705 _this.view.refreshRequired = true;
707 public void runRefresh ()
709 // this is run every 2 seconds from the init..
713 if (!this.refreshRequired) {
714 // print("no refresh required");
718 if (this.lastRedraw != null) {
719 // do not redraw if last redraw was less that 5 seconds ago.
720 if ((int64)(new DateTime.now_local()).difference(this.lastRedraw) < 5000 ) {
725 if (_this.file == null) {
730 this.refreshRequired = false;
731 // print("HTML RENDERING");
734 //this.get('/BottomPane').el.show();
735 //this.get('/BottomPane').el.set_current_page(2);// webkit inspector
736 _this.file.webkit_page_id = this.el.get_page_id();
738 var js = _this.file.toSourcePreview();
747 var project = _this.file.project;
749 //print (project.fn);
750 // set it to non-empty.
752 // runhtml = runhtml.length ? runhtml : '<script type="text/javascript"></script>';
755 // this.runhtml = this.runhtml || '';
758 // then we need to reload the browser using
759 // load_html_string..
761 // then trigger a redraw once it's loaded..
762 this.pendingRedraw = true;
764 var runhtml = "<script type=\"text/javascript\">\n" ;
768 GLib.FileUtils.get_contents(BuilderApplication.configDirectory() + "/resources/roo.builder.js", out builderhtml);
773 runhtml += builderhtml + "\n";
774 runhtml += "</script>\n" ;
776 // fix to make sure they are the same..
777 this.runhtml = project.runhtml;
778 // need to modify paths
781 var base_template = _this.file.project.base_template;
783 if (base_template.length > 0 && !FileUtils.test(
784 BuilderApplication.configDirectory() + "/resources/" + base_template, FileTest.EXISTS)
786 print("invalid base_template name - using default: %s\n", base_template);
791 GLib.FileUtils.get_contents(
792 BuilderApplication.configDirectory() + "/resources/" +
793 (base_template.length > 0 ? base_template : "roo.builder.html")
799 this.renderedData = js;
802 string js_src = js + "\n" +
803 "Roo.onReady(function() {\n" +
804 "if (" + _this.file.name +".show) " + _this.file.name +".show({});\n" +
805 "Roo.XComponent.build();\n" +
808 // print("render js: " + js);
810 // console.log('not loaded yet');
812 this.lastRedraw = new DateTime.now_local();
815 //this.runjs = js_src;
816 var fc = FakeServerCache.factory_with_data(js_src);
817 this.runjs = fc.fname;
819 var html = inhtml.replace("</head>", runhtml + this.runhtml +
820 "<script type=\"text/javascript\" src=\"xhttp://localhost" + fc.fname + "\"></script>" +
821 // "<script type=\"text/javascript\">\n" +
826 //print("LOAD HTML " + html);
828 var rootURL = _this.file.project.rootURL;
832 this.el.load_html( html ,
833 //fixme - should be a config option!
834 (rootURL.length > 0 ? rootURL : "xhttp://localhost/roobuilder/")
837 // force the inspector...
838 // this.initInspector();
840 // - no need for this, the builder javascript will call it when build is complete
841 //GLib.Timeout.add_seconds(1, () => {
842 // this.el.run_javascript("Builder.saveHTML()",null);
845 // print( "before render" + this.lastRedraw);
846 // print( "after render" + (new Date()));
849 public void initInspector () {
851 /* if (this.inspector == this.el.get_inspector()) {
852 this.inspector.show();
853 this.inspector.open_window();
854 print("init inspecter called, and inspector is the same as existing\n");
857 print("new inspector?\n");
859 this.inspector = this.el.get_inspector();
860 this.inspector.ref();
862 // got a new inspector...
864 this.inspector.open_window.connect(() => {
865 this.inspector = this.el.get_inspector();
866 print("inspector attach\n");
867 var wv = this.inspector.get_web_view();
869 print("got inspector web view\n");
871 var cn = _this.inspectorcontainer.el.get_child();
873 _this.inspectorcontainer.el.remove(cn);
876 _this.inspectorcontainer.el.add(wv);
879 //this.inspector.close();
881 //this.inspector = null;
889 this.inspector.closed.connect(() => {
890 print("inspector closed?!?");
891 // if this happens destroy the webkit..
893 this.el.stop_loading();
895 if (_this.viewbox.el.get_parent() == null) {
900 _this.viewbox.el.remove(_this.viewcontainer.el);
901 _this.el.remove(_this.inspectorcontainer.el);
903 // destory seems to cause problems.
905 //_this.viewcontainer.el.destroy();
906 //_this.inspectorcontainer.el.destroy();
909 var nv =new Xcls_viewcontainer(_this);
911 _this.viewbox.el.pack_end(nv.el,true,true,0);
913 var inv =new Xcls_inspectorcontainer(_this);
915 _this.el.pack2(inv.el,true,true);
919 //while(Gtk.events_pending ()) Gtk.main_iteration ();
920 //_this.view.renderJS(true);
921 _this.view.refreshRequired = true;
926 this.inspector.show();
928 public void renderJS (bool force) {
930 // this is the public redraw call..
931 // we refresh in a loop privately..
932 var autodraw = _this.AutoRedraw.el.active;
933 if (!autodraw && !force) {
934 print("Skipping redraw - no force, and autodraw off");
938 this.refreshRequired = true;
944 public class Xcls_inspectorcontainer : Object
946 public Gtk.ScrolledWindow el;
947 private Xcls_WindowRooView _this;
953 public Xcls_inspectorcontainer(Xcls_WindowRooView _owner )
956 _this.inspectorcontainer = this;
957 this.el = new Gtk.ScrolledWindow( null, null );
961 // set gobject values
962 this.el.shadow_type = Gtk.ShadowType.IN;
966 this.el.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
969 // user defined functions
973 public class Xcls_ScrolledWindow14 : Object
975 public Gtk.ScrolledWindow el;
976 private Xcls_WindowRooView _this;
982 public Xcls_ScrolledWindow14(Xcls_WindowRooView _owner )
985 this.el = new Gtk.ScrolledWindow( null, null );
989 // set gobject values
990 var child_0 = new Xcls_sourceview( _this );
992 this.el.add ( child_0.el );
995 // user defined functions
997 public class Xcls_sourceview : Object
999 public Gtk.SourceView el;
1000 private Xcls_WindowRooView _this;
1004 public bool loading;
1005 public bool button_is_pressed;
1006 public string prop_selected;
1007 public bool key_is_pressed;
1008 public JsRender.Node? node_selected;
1009 public int editable_start_pos;
1012 public Xcls_sourceview(Xcls_WindowRooView _owner )
1015 _this.sourceview = this;
1016 this.el = new Gtk.SourceView();
1019 this.loading = true;
1020 this.button_is_pressed = false;
1021 this.prop_selected = "";
1022 this.key_is_pressed = false;
1023 this.node_selected = null;
1024 this.editable_start_pos = -1;
1026 // set gobject values
1027 this.el.editable = false;
1028 this.el.show_line_marks = true;
1029 this.el.show_line_numbers = true;
1030 var child_0 = new Xcls_buffer( _this );
1032 this.el.set_buffer ( child_0.el );
1038 var description = Pango.FontDescription.from_string("monospace");
1039 description.set_size(8000);
1040 this.el.override_font(description);
1042 this.loading = true;
1043 //var buf = this.el.get_buffer();
1044 //buf.notify.connect(this.onCursorChanged);
1048 var attrs = new Gtk.SourceMarkAttributes();
1049 var pink = Gdk.RGBA();
1050 pink.parse ( "pink");
1051 attrs.set_background ( pink);
1052 attrs.set_icon_name ( "process-stop");
1053 attrs.query_tooltip_text.connect(( mark) => {
1054 //print("tooltip query? %s\n", mark.name);
1058 this.el.set_mark_attributes ("ERR", attrs, 1);
1060 var wattrs = new Gtk.SourceMarkAttributes();
1061 var blue = Gdk.RGBA();
1062 blue.parse ( "#ABF4EB");
1063 wattrs.set_background ( blue);
1064 wattrs.set_icon_name ( "process-stop");
1065 wattrs.query_tooltip_text.connect(( mark) => {
1066 //print("tooltip query? %s\n", mark.name);
1070 this.el.set_mark_attributes ("WARN", wattrs, 1);
1074 var dattrs = new Gtk.SourceMarkAttributes();
1075 var purple = Gdk.RGBA();
1076 purple.parse ( "#EEA9FF");
1077 dattrs.set_background ( purple);
1078 dattrs.set_icon_name ( "process-stop");
1079 dattrs.query_tooltip_text.connect(( mark) => {
1080 //print("tooltip query? %s\n", mark.name);
1084 this.el.set_mark_attributes ("DEPR", dattrs, 1);
1087 var gattrs = new Gtk.SourceMarkAttributes();
1088 var grey = Gdk.RGBA();
1089 grey.parse ( "#ccc");
1090 gattrs.set_background ( grey);
1093 this.el.set_mark_attributes ("grey", gattrs, 1);
1103 this.el.button_release_event.connect( () => {
1105 print("BUTTON RELEASE EVENT\n");
1106 this.onCursorChanged();
1107 this.button_is_pressed = false;
1110 this.el.button_press_event.connect( () => {
1115 this.button_is_pressed = true;
1118 this.el.key_press_event.connect( (src, key) => {
1119 this.key_is_pressed = true;
1120 // is it ctrl-G -- find next?
1121 // which will will still ignore..
1123 if (key.str == "g" && key.state == Gdk.ModifierType.CONTROL_MASK) {
1124 this.key_is_pressed = false;
1127 // if cursor postion is 'at start' of editing range,
1128 // and backspace is pressed...
1131 var buf = this.el.get_buffer();
1132 //print("cursor changed : %d\n", buf.cursor_position);
1134 if (buf.cursor_position <= this.editable_start_pos && key.keyval == Gdk.Key.BackSpace) {
1135 return true; // block...
1137 // what about 'last line of 'grey...'
1138 // get the buffer - find the line, find the next line ?? see if it's grey?
1141 print("KEY PRESS EVENT \n");
1142 this.onCursorChanged();
1145 this.el.key_release_event.connect( () => {
1146 this.key_is_pressed = false;
1151 // user defined functions
1152 public void onCursorChanged (/*ParamSpec ps*/) {
1154 if (!this.key_is_pressed && !this.button_is_pressed) {
1161 // if (ps.name != "cursor-position") {
1165 var buf = this.el.get_buffer();
1166 //print("cursor changed : %d\n", buf.cursor_position);
1168 buf.get_iter_at_offset(out cpos, buf.cursor_position);
1170 var ln = cpos.get_line();
1173 // --- select node at line....
1175 var node = _this.file.lineToNode(ln+1);
1178 print("can not find node\n");
1181 var prop = node.lineToProp(ln+1);
1182 print("prop : %s", prop == null ? "???" : prop);
1185 // ---------- this selects the tree's node...
1187 var ltree = _this.main_window.windowstate.left_tree;
1188 var tp = ltree.model.treePathFromNode(node);
1189 print("got tree path %s\n", tp);
1193 //print("changing cursor on tree..\n");
1197 // let's try allowing editing on the methods.
1198 // a little klunky at present..
1199 this.prop_selected = "";
1201 //see if we can find it..
1202 var kv = prop.split(":");
1205 //var k = prop.get_key(kv[1]);
1206 // fixme -- need to determine if it's an editable property...
1207 this.prop_selected = prop;
1209 } else if (kv[0] == "l") {
1210 this.prop_selected = prop;
1214 ltree.view.setCursor(tp, "editor");
1215 // ltree.view.el.set_cursor(new Gtk.TreePath.from_string(tp), null, false);
1216 this.nodeSelected(node,false);
1218 // scrolling is disabled... as node selection calls scroll 10ms after it changes.
1222 // highlight the node..
1224 public void clearGreySelection () {
1225 // clear all the marks..
1226 var sbuf = (Gtk.SourceBuffer)this.el.buffer;
1231 sbuf.get_bounds (out start, out end);
1232 sbuf.remove_source_marks (start, end, "grey");
1236 public void nodeSelected (JsRender.Node? sel, bool scroll ) {
1240 // this is connected in widnowstate
1244 while(Gtk.events_pending()) {
1245 Gtk.main_iteration();
1248 this.node_selected = sel;
1250 this.updateGreySelection(scroll);
1255 public string toString () {
1258 this.el.get_buffer().get_start_iter(out s);
1259 this.el.get_buffer().get_end_iter(out e);
1260 var ret = this.el.get_buffer().get_text(s,e,true);
1261 //print("TO STRING? " + ret);
1264 public void loadFile ( ) {
1265 this.loading = true;
1268 // get the cursor and scroll position....
1269 var buf = this.el.get_buffer();
1270 var cpos = buf.cursor_position;
1272 print("BEFORE LOAD cursor = %d\n", cpos);
1274 var vadj_pos = this.el.get_vadjustment().get_value();
1279 var sbuf = (Gtk.SourceBuffer) buf;
1283 if (_this.file == null || _this.file.xtype != "Roo") {
1284 print("xtype != Roo");
1285 this.loading = false;
1289 // get the string from the rendered tree...
1291 var str = _this.file.toSource();
1293 // print("setting str %d\n", str.length);
1294 buf.set_text(str, str.length);
1295 var lm = Gtk.SourceLanguageManager.get_default();
1297 //?? is javascript going to work as js?
1299 ((Gtk.SourceBuffer)(buf)) .set_language(lm.get_language(_this.file.language));
1305 sbuf.get_bounds (out start, out end);
1306 sbuf.remove_source_marks (start, end, null); // remove all marks..
1308 GLib.Timeout.add(500, () => {
1310 print("RESORTING cursor to = %d\n", cpos);
1311 Gtk.TextIter cpos_iter;
1312 buf.get_iter_at_offset(out cpos_iter, cpos);
1313 buf.place_cursor(cpos_iter);
1315 this.el.get_vadjustment().set_value(vadj_pos);;
1318 this.onCursorChanged();
1321 _this.buffer.checkSyntax();
1325 this.loading = false;
1326 _this.buffer.dirty = false;
1328 public void updateGreySelection (bool scroll) {
1329 var sel = this.node_selected;
1330 print("node selected\n");
1331 var buf = this.el.get_buffer();
1332 var sbuf = (Gtk.SourceBuffer) buf;
1335 this.clearGreySelection();
1340 print("no selected node\n");
1341 // no highlighting..
1345 print("highlight region %d to %d\n", sel.line_start,sel.line_end);
1347 sbuf.get_iter_at_line(out iter, sel.line_start);
1350 Gtk.TextIter cur_iter;
1351 sbuf.get_iter_at_offset(out cur_iter, sbuf.cursor_position);
1353 var cursor_at_line = cur_iter.get_line();
1356 //var cur_line = cur_iter.get_line();
1357 //if (cur_line > sel.line_start && cur_line < sel.line_end) {
1361 print("scrolling to node -- should occur on node picking.\n");
1362 this.el.scroll_to_iter(iter, 0.1f, true, 0.0f, 0.5f);
1365 var start_line = sel.line_start;
1366 var end_line = sel.line_end;
1369 this.el.editable = false;
1371 //var colon_pos = 0;
1373 this.editable_start_pos = -1;
1375 // now if we have selected a property...
1376 if (this.prop_selected.length> 0 ) {
1379 if (sel.getPropertyRange(this.prop_selected, out nstart, out nend) && nend > nstart) {
1380 start_line = nstart;
1382 this.el.editable = true;
1383 print("start line = %d, end line = %d\n", start_line, end_line);
1385 // see if we are 'right of ':'
1386 // get an iter for the start of the line.
1387 Gtk.TextIter start_first_line_iter,end_first_line_iter;
1388 this.el.buffer.get_iter_at_line(out start_first_line_iter, start_line -1);
1389 this.el.buffer.get_iter_at_line(out end_first_line_iter, start_line -1);
1394 if (end_first_line_iter.forward_to_line_end()) {
1395 var first_line = this.el.buffer.get_text(start_first_line_iter, end_first_line_iter, false);
1397 print("first line = %s\n", first_line);
1398 if (first_line.contains(":")) {
1399 this.editable_start_pos = start_first_line_iter.get_offset() + first_line.index_of(":") + 1;
1400 print("colon_pos = %d\n", this.editable_start_pos);
1404 //Gtk.TextIter colon_iter;
1405 //sbuf.get_iter_at_offset (out colon_iter, colon_pos);
1406 //sbuf.create_source_mark(null, "active_text", colon_iter);
1411 //print("is cursor at line? %d ?= %d\n", start_line -1 , cursor_at_line);
1412 //if (start_line - 1 == cursor_at_line) {
1413 // should be ok - current_posssion can not be less than '-1'...
1414 if (sbuf.cursor_position < this.editable_start_pos) {
1416 print("cursor is before start pos.. - turn off editable...\n");
1417 //var before_cursor_string = this.el.buffer.get_text(start_line_iter, cur_iter, false);
1418 //print("before cursor string = %s\n", before_cursor_string);
1419 //if (!before_cursor_string.contains(":")) {
1420 this.el.editable = false;
1429 print("propSelected = %s range %d -> %d\n", this.prop_selected, start_line, end_line);
1434 print("checking selection\n");
1437 // check selection - if it's out of 'bounds'
1438 if (this.el.editable && sbuf.get_has_selection()) {
1439 Gtk.TextIter sel_start_iter, sel_end_iter;
1440 sbuf.get_selection_bounds(out sel_start_iter, out sel_end_iter);
1442 if (sel_start_iter.get_line() < start_line || sel_end_iter.get_line() > end_line ||
1443 sel_start_iter.get_line() > end_line || sel_end_iter.get_line() < start_line ) {
1445 this.el.editable = false;
1447 if (this.editable_start_pos > 0 &&
1448 (sel_start_iter.get_offset() < this.editable_start_pos || sel_end_iter.get_offset() < this.editable_start_pos)
1451 this.el.editable = false;
1461 for (var i = 0; i < buf.get_line_count();i++) {
1462 if (i < (start_line -1) || i > (end_line -1)) {
1464 sbuf.get_iter_at_line(out iter, i);
1465 sbuf.create_source_mark(null, "grey", iter);
1470 if (scroll && (cursor_at_line > end_line || cursor_at_line < start_line)) {
1471 Gtk.TextIter cpos_iter;
1472 buf.get_iter_at_line(out cpos_iter, start_line);
1474 buf.place_cursor(cpos_iter);
1479 public void highlightErrorsJson (string type, Json.Object obj) {
1480 // this is a hook for the vala code - it has no value in javascript
1481 // as we only have one error ususally....
1489 public class Xcls_buffer : Object
1491 public Gtk.SourceBuffer el;
1492 private Xcls_WindowRooView _this;
1497 public int error_line;
1500 public Xcls_buffer(Xcls_WindowRooView _owner )
1503 _this.buffer = this;
1504 this.el = new Gtk.SourceBuffer( null );
1508 this.error_line = -1;
1510 // set gobject values
1513 this.el.changed.connect( () => {
1518 // _this.save_button.el.sensitive = true;
1519 ///?? has changed occured during loading?
1521 // only trigger this if
1526 if (_this.sourceview.loading) {
1532 print("- PREVIEW EDITOR CHANGED--");
1535 this.checkSyntax(); // this calls backs and highlights errors.. in theory...
1539 if (!_this.sourceview.button_is_pressed && !_this.sourceview.key_is_pressed) {
1540 print("button or key not pressed to generate change?!\n");
1545 // what are we editing??
1546 if (null == _this.sourceview.node_selected || _this.sourceview.prop_selected.length < 1) {
1550 // find the colon on the first line...
1552 if (_this.sourceview.editable_start_pos > -1) {
1554 var buf = (Gtk.SourceBuffer)_this.sourceview.el.get_buffer();
1556 //print("cursor changed : %d\n", buf.cursor_position);
1557 Gtk.TextIter spos,epos;
1558 buf.get_iter_at_offset(out spos, _this.sourceview.editable_start_pos);
1559 buf.get_iter_at_offset(out epos, _this.sourceview.editable_start_pos); // initialize epos..
1562 var line = spos.get_line();
1563 var endline = buf.get_line_count();
1564 while (line < endline) {
1566 buf.get_iter_at_line(out epos, line);
1567 if (buf.get_source_marks_at_line(line, "grey").length() > 0) {
1568 buf.get_iter_at_line(out epos, line);
1575 print("End Offset = %d/%d\n", epos.get_line(), epos.get_offset());
1577 // in theory the last char will be '}' or '},' .. or ','
1578 // we should chop the ',' of the end...
1579 var str = buf.get_text(spos, epos, false);
1580 print("got string\n%s\n", str);
1588 // user defined functions
1589 public bool highlightErrors ( Gee.HashMap<int,string> validate_res) {
1591 this.error_line = validate_res.size;
1593 if (this.error_line < 1) {
1596 var tlines = this.el.get_line_count ();
1598 var valiter = validate_res.map_iterator();
1599 while (valiter.next()) {
1601 // print("get inter\n");
1602 var eline = valiter.get_key();
1603 if (eline > tlines) {
1606 this.el.get_iter_at_line( out iter, eline);
1607 //print("mark line\n");
1608 this.el.create_source_mark(valiter.get_value(), "ERR", iter);
1612 public string toString () {
1616 this.el.get_start_iter(out s);
1617 this.el.get_end_iter(out e);
1618 var ret = this.el.get_text(s,e,true);
1619 //print("TO STRING? " + ret);
1622 public bool checkSyntax () {
1625 var str = this.toString();
1628 if (this.error_line > 0) {
1631 this.el.get_bounds (out start, out end);
1633 this.el.remove_source_marks (start, end, "WARN");
1634 this.el.remove_source_marks (start, end, "ERR");
1638 if (str.length < 1) {
1639 print("checkSyntax - empty string?\n");
1643 if (_this.file == null) {
1646 var p = _this.file.project.palete;
1649 if (_this.file.language != "js") {
1650 return false; // fake syntax error.
1653 //Gee.HashMap<int,string> ret_x;
1655 return p.javascriptHasErrors(
1656 _this.main_window.windowstate,
1659 "file", //_this.ptype,