Fix #8098 - refinements to code navigator
authorAlan <alan@roojs.com>
Wed, 20 Mar 2024 02:54:51 +0000 (10:54 +0800)
committerAlan <alan@roojs.com>
Wed, 20 Mar 2024 02:54:51 +0000 (10:54 +0800)
src/Builder4/Editor.bjs
src/Builder4/Editor.vala

index 0db9e57..2127fc9 100644 (file)
                "\tvar lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();",
                "\tvar sym = (Lsp.DocumentSymbol) lr.get_item();",
                "\t",
-               "\tGLib.debug(\"got %d children for %s\" , (int)sym.children.get_n_items(), sym.name);",
+               "\tsym.set_data<Gtk.Widget>(\"widget\", expand.get_parent());",
+               "\texpand.get_parent().get_parent().set_data<Lsp.DocumentSymbol>(\"symbol\", sym);",
+               "\t",
+               "\tGLib.debug(\"save sym on %s\", expand.get_parent().get_parent().get_type().name());",
+               "\t",
+               "\t//GLib.debug(\"got %d children for %s\" , (int)sym.children.get_n_items(), sym.name);",
                "    ",
                "    expand.set_hide_expander( sym.children.get_n_items()  < 1);",
                " \texpand.set_list_row(lr);",
              ]
             }
            ],
-           "xtype" : "NoSelection",
-           "| Lsp.DocumentSymbol? getSymbollAtOLD" : [
-            "(uint row) {",
-            "",
-            "   var tr = (Gtk.TreeListRow)this.el.get_item(row);",
-            "   ",
-            "   var a = tr.get_item();;   ",
-            "   GLib.debug(\"get_item (2) = %s\", a.get_type().name());",
-            "  \t",
-            "   ",
-            "   return (Lsp.DocumentSymbol)tr.get_item();",
-            "\t ",
-            "}"
-           ],
-           "| int getRowFromSymbolx" : [
-            "(Lsp.DocumentSymbol sym) {",
-            "",
-            "\tfor (var i=0;i < this.el.get_n_items(); i++) {",
-            "\t\tvar tr = (Gtk.TreeListRow)this.el.get_item(i);",
-            "\t   ",
-            "\t\tif (sym.equals( (Lsp.DocumentSymbol)tr.get_item())) {",
-            "\t\t\treturn i;",
-            "\t\t}",
-            "\t}",
-            "   \treturn -1;",
-            "}"
-           ]
+           "xtype" : "NoSelection"
           },
           {
            "$ xns" : "Gtk",
             "pressed" : [
              "(n_press, x, y) => {",
              "\tstring pos;",
-             "  \tvar row = _this.navigation.getRowAt(x,y, out pos );",
-             "    if (row < 0) {",
+             "  \tvar row = _this.navigation.getRowWidgetAt(x,y, out pos );",
+             "",
+             "    if (row == null) {",
              "\t    GLib.debug(\"no row selected items\");",
              "\t    return;",
              "    }",
+             "\tGLib.debug(\"got click on %s\", row.get_type().name());    ",
              "    //Lsp.DocumentSymbol",
-             "    var sym =   _this.navigationsort.getSymbolAt(row);",
+             "    var sym =  row.get_data<Lsp.DocumentSymbol>(\"symbol\");",
              "    if (sym == null) {",
              "    \treturn;",
              "\t}",
              "        */",
              "     GLib.debug(\"goto line %d\",   (int)sym.range.start.line); ",
              "    _this.scroll_to_line((int)sym.range.start.line);",
+             "    Gtk.TextIter iter;",
+             "    _this.buffer.el.get_iter_at_line_offset(out iter, ",
+             "    \t(int)sym.range.start.line,",
+             "    \t(int)sym.range.start.character",
+             "\t);",
+             "    _this.buffer.el.place_cursor(iter);",
              "\t",
              "}"
             ]
          ],
          "string name" : "editor-navigation",
          "xtype" : "ColumnView",
-         "| Gtk.Widget? getWidgetAtRow" : [
-          "(uint row) {",
-          "/*",
-          "    \t",
-          "from    \thttps://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465",
-          "    \tvar colview = gesture.widget;",
-          "    \tvar line_no = check_list_widget(colview, x,y);",
-          "         if (line_no > -1) {",
-          "    \t\tvar item = colview.model.get_item(line_no);",
-          "    \t\t ",
-          "    \t}",
-          "    \t*/",
-          "\t\t//GLib.debug(\"Get Widget At Row %d\", (int)row);",
-          "        var  child = this.el.get_first_child(); ",
-          "    \tvar line_no = -1; ",
-          "    \tvar reading_header = true;",
-          "\t ",
-          "    \twhile (child != null) {",
-          "\t\t\t//GLib.debug(\"Got %s\", child.get_type().name());",
-          "    \t   ",
-          "    \t   if (reading_header) {",
-          "\t\t\t\t",
-          "",
-          "\t\t\t\tif (child.get_type().name() != \"GtkColumnListView\") {",
-          "\t\t\t\t   ",
-          "\t\t\t\t\tchild = child.get_next_sibling();",
-          "\t\t\t\t\tcontinue;",
-          "\t\t\t\t}",
-          "\t\t\t\t// should be columnlistview",
-          "\t\t\t\tchild = child.get_first_child(); ",
-          "\t\t\t ",
-          "\t\t\t ",
-          "\t\t\t\t",
-          "\t\t\t\treading_header = false;",
-          "\t\t\t\tcontinue;",
-          "\t\t    }",
-          "\t\t    ",
-          "\t\t  ",
-          "    \t    ",
-          "\t\t    line_no++;",
-          "\t\t\tif (line_no == row) {",
-          "\t\t\t\t//GLib.debug(\"Returning widget %s\", child.get_type().name());",
-          "\t\t\t    return (Gtk.Widget)child;",
-          "\t\t    }",
-          "\t        child = child.get_next_sibling(); ",
-          "    \t}",
-          "\t\tGLib.debug(\"Failed to find row (max = %d)\", line_no);",
-          "        return null;",
+         "| Gtk.Widget? getRowWidgetAt" : [
+          "(double x,  double  y, out string pos) {",
           "",
+          "\tpos = \"\";",
+          "\tvar w = this.el.pick(x, y, Gtk.PickFlags.DEFAULT);",
+          "\t//GLib.debug(\"got widget %s\", w == null ? \"nothing\" : w.get_type().name());",
+          "\tif (w == null) {",
+          "\t\treturn null;",
+          "\t}",
+          "\t",
+          "\tvar row= w.get_ancestor(GLib.Type.from_name(\"GtkColumnViewRowWidget\"));",
+          "\tif (row == null) {",
+          "\t\treturn null;",
+          "\t}",
+          "\t",
+          "\t//GLib.debug(\"got colview %s\", row == null ? \"nothing\" : row.get_type().name());",
+          "\t ",
+          " ",
+          "\t",
+          "\t//GLib.debug(\"row number is %d\", rn);",
+          "\t//GLib.debug(\"click %d, %d\", (int)x, (int)y);",
+          "\t// above or belw",
+          "\tGraphene.Rect  bounds;",
+          "\trow.compute_bounds(this.el, out bounds);",
+          "\t//GLib.debug(\"click x=%d, y=%d, w=%d, h=%d\", ",
+          "\t//\t(int)bounds.get_x(), (int)bounds.get_y(),",
+          "\t//\t(int)bounds.get_width(), (int)bounds.get_height()",
+          "\t//\t);",
+          "\tvar ypos = y - bounds.get_y();",
+          "\t//GLib.debug(\"rel ypos = %d\", (int)ypos);\t",
+          "\tvar rpos = 100.0 * (ypos / bounds.get_height());",
+          "\t//GLib.debug(\"rel pos = %d %%\", (int)rpos);",
+          "\tpos = \"over\";",
+          "\t",
+          "\tif (rpos > 80) {",
+          "\t\tpos = \"below\";",
+          "\t} else if (rpos < 20) {",
+          "\t\tpos = \"above\";",
+          "\t} ",
+          "\treturn row;",
           " }"
          ],
          "| int getRowAt" : [
           "\tthis.selected_row  = null;",
           "\tif (new_row > -1) {",
           "\t\tthis.el.scroll_to(new_row,null,Gtk.ListScrollFlags.NONE, null);",
-          "\t\tvar row = this.getWidgetAtRow(new_row);",
+          "\t\tvar row = sym.get_data<Gtk.Widget>(\"widget\");",
           "\t\tif (row != null) {",
           "\t\t\tGLib.debug(\" Add selected row\");",
           " \t\t\t",
index 9d501d7..afde2d5 100644 (file)
@@ -1800,54 +1800,45 @@ public class Editor : Object
                }
 
                // user defined functions
-               public Gtk.Widget? getWidgetAtRow (uint row) {
-               /*
-                       
-               from            https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
-                       var colview = gesture.widget;
-                       var line_no = check_list_widget(colview, x,y);
-                        if (line_no > -1) {
-                               var item = colview.model.get_item(line_no);
-                                
-                       }
-                       */
-                               //GLib.debug("Get Widget At Row %d", (int)row);
-                       var  child = this.el.get_first_child(); 
-                       var line_no = -1; 
-                       var reading_header = true;
-                        
-                       while (child != null) {
-                                       //GLib.debug("Got %s", child.get_type().name());
-                          
-                          if (reading_header) {
-                                               
-               
-                                               if (child.get_type().name() != "GtkColumnListView") {
-                                                  
-                                                       child = child.get_next_sibling();
-                                                       continue;
-                                               }
-                                               // should be columnlistview
-                                               child = child.get_first_child(); 
-                                        
-                                        
-                                               
-                                               reading_header = false;
-                                               continue;
-                                   }
-                                   
-                                 
-                           
-                                   line_no++;
-                                       if (line_no == row) {
-                                               //GLib.debug("Returning widget %s", child.get_type().name());
-                                           return (Gtk.Widget)child;
-                                   }
-                               child = child.get_next_sibling(); 
-                       }
-                               GLib.debug("Failed to find row (max = %d)", line_no);
-                       return null;
+               public Gtk.Widget? getRowWidgetAt (double x,  double  y, out string pos) {
                
+                       pos = "";
+                       var w = this.el.pick(x, y, Gtk.PickFlags.DEFAULT);
+                       //GLib.debug("got widget %s", w == null ? "nothing" : w.get_type().name());
+                       if (w == null) {
+                               return null;
+                       }
+                       
+                       var row= w.get_ancestor(GLib.Type.from_name("GtkColumnViewRowWidget"));
+                       if (row == null) {
+                               return null;
+                       }
+                       
+                       //GLib.debug("got colview %s", row == null ? "nothing" : row.get_type().name());
+                        
+                
+                       
+                       //GLib.debug("row number is %d", rn);
+                       //GLib.debug("click %d, %d", (int)x, (int)y);
+                       // above or belw
+                       Graphene.Rect  bounds;
+                       row.compute_bounds(this.el, out bounds);
+                       //GLib.debug("click x=%d, y=%d, w=%d, h=%d", 
+                       //      (int)bounds.get_x(), (int)bounds.get_y(),
+                       //      (int)bounds.get_width(), (int)bounds.get_height()
+                       //      );
+                       var ypos = y - bounds.get_y();
+                       //GLib.debug("rel ypos = %d", (int)ypos);       
+                       var rpos = 100.0 * (ypos / bounds.get_height());
+                       //GLib.debug("rel pos = %d %%", (int)rpos);
+                       pos = "over";
+                       
+                       if (rpos > 80) {
+                               pos = "below";
+                       } else if (rpos < 20) {
+                               pos = "above";
+                       } 
+                       return row;
                 }
                public void show (Gee.ArrayList<Lsp.DocumentSymbol> syms) {
                        _this.navigationwindow.el.show();
@@ -1928,7 +1919,7 @@ public class Editor : Object
                        this.selected_row  = null;
                        if (new_row > -1) {
                                this.el.scroll_to(new_row,null,Gtk.ListScrollFlags.NONE, null);
-                               var row = this.getWidgetAtRow(new_row);
+                               var row = sym.get_data<Gtk.Widget>("widget");
                                if (row != null) {
                                        GLib.debug(" Add selected row");
                                        
@@ -2028,7 +2019,12 @@ public class Editor : Object
                                var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
                                var sym = (Lsp.DocumentSymbol) lr.get_item();
                                
-                               GLib.debug("got %d children for %s" , (int)sym.children.get_n_items(), sym.name);
+                               sym.set_data<Gtk.Widget>("widget", expand.get_parent());
+                               expand.get_parent().get_parent().set_data<Lsp.DocumentSymbol>("symbol", sym);
+                               
+                               GLib.debug("save sym on %s", expand.get_parent().get_parent().get_type().name());
+                               
+                               //GLib.debug("got %d children for %s" , (int)sym.children.get_n_items(), sym.name);
                            
                            expand.set_hide_expander( sym.children.get_n_items()  < 1);
                                expand.set_list_row(lr);
@@ -2077,28 +2073,6 @@ public class Editor : Object
                }
 
                // user defined functions
-               public int getRowFromSymbolx (Lsp.DocumentSymbol sym) {
-               
-                       for (var i=0;i < this.el.get_n_items(); i++) {
-                               var tr = (Gtk.TreeListRow)this.el.get_item(i);
-                          
-                               if (sym.equals( (Lsp.DocumentSymbol)tr.get_item())) {
-                                       return i;
-                               }
-                       }
-                       return -1;
-               }
-               public Lsp.DocumentSymbol? getSymbollAtOLD (uint row) {
-               
-                  var tr = (Gtk.TreeListRow)this.el.get_item(row);
-                  
-                  var a = tr.get_item();;   
-                  GLib.debug("get_item (2) = %s", a.get_type().name());
-                       
-                  
-                  return (Lsp.DocumentSymbol)tr.get_item();
-                        
-               }
        }
        public class Xcls_navigationsort : Object
        {
@@ -2309,13 +2283,15 @@ public class Editor : Object
                        //listeners
                        this.el.pressed.connect( (n_press, x, y) => {
                                string pos;
-                               var row = _this.navigation.getRowAt(x,y, out pos );
-                           if (row < 0) {
+                               var row = _this.navigation.getRowWidgetAt(x,y, out pos );
+                       
+                           if (row == null) {
                                    GLib.debug("no row selected items");
                                    return;
                            }
+                               GLib.debug("got click on %s", row.get_type().name());    
                            //Lsp.DocumentSymbol
-                           var sym =   _this.navigationsort.getSymbolAt(row);
+                           var sym =  row.get_data<Lsp.DocumentSymbol>("symbol");
                            if (sym == null) {
                                return;
                                }
@@ -2333,6 +2309,12 @@ public class Editor : Object
                                */
                             GLib.debug("goto line %d",   (int)sym.range.start.line); 
                            _this.scroll_to_line((int)sym.range.start.line);
+                           Gtk.TextIter iter;
+                           _this.buffer.el.get_iter_at_line_offset(out iter, 
+                               (int)sym.range.start.line,
+                               (int)sym.range.start.character
+                               );
+                           _this.buffer.el.place_cursor(iter);
                                
                        });
                }