sieukrem / jn-npp-plugin

Plugin for Notepad++ allowing you to automate some tasks using JavaScript
https://github.com/sieukrem/jn-npp-plugin/wiki
110 stars 24 forks source link

Tree view example #106

Open Jzhenli opened 3 years ago

Jzhenli commented 3 years ago

Hi, would u add a Tree view example for the jn-npp-plugin? it's similar to the function list.

image

trdm commented 3 years ago
var gHelpWindow = null;
//var strDoc = '<html><frameset rows = "50%, 50%" border = "6"> <frame src = "T:\\Web\\fr_left.htm"> <frame src = "T:\\Web\\rf_000000.htm" name = "price"></frameset>';
// done
function openHelp() {
    var rv = '';
    var strDoc = '';
    if(gHelpWindow) {
        return;
    }
    var option = {      
        name:'Документация',        
        docking:'right', 
        onclose:function(){
                gHelpWindow = '';
            }
        };  
    //debugger;
    // не хляют для MSIE '++' в пути. дурить начинает. пришлось перенести.
    //vPath = Editor.nppDir+'\\help\\'; 
    vPath = 'T:\\NppHelp\\help\\';  
    gHelpWindow = Editor.createDockable(option);
    //gHelpWindow.slient = true;
    var d = gHelpWindow.document;
    gHelpDocum = d;
    strDoc = '<html><head></head><frameset rows = "50%, 50%" border = "6">';
    strDoc +='<frame id = "frame_t" src = "'+vPath+'dtree.html">    <frame id = "frame_b" src = "'+vPath+'b_frame.html" name = "docs">';
    strDoc +='</frameset><noframes>ваш браузер не поддерживает фреймы</noframes>';

    d.write(strDoc);
    d.createComment();
    // Теперь надо заставить IE навигировать на нужную страницу в нижнем фрейме.
    //el.src = 'T:\\NppHelp\\help\\html\\Automatition\\HTML\\ObjectFSO_1.html';
    d.close();
    return rv;
}

var myHelpOpenCommand = {
    text: "Справка \tCtrl+F1", 
    ctrl: true,
    shift: false,
    alt: false,
    key: 0x70, // "F1"
    cmd: openHelp   
};

Найди дерево на js (dtree.js / dtree.css ( https://github.com/trdm/jn-npp-scripts/tree/master/Bin )) ии построй на их основе html страницы и юзай. dtree.zip

Jzhenli commented 3 years ago

@trdm thanks for your reply, but seems your example missed some html files, and can not run correct. Would u share these files for demo?

trdm commented 3 years ago

Остальные файлы погибли вместе с винчестером. тебе нужно будет самому их генерировать. вот пример: https://coderanch.com/t/116549/languages/dtree

Jzhenli commented 3 years ago

@trdm I know the dtree API, but not sure how to integrate it into the dockable, I try the following code, it displayed nothing at the dockable.

mytest.zip

I find you have implemented it already in your gif picture, it's really cool. Would u help to review my code and point out the problem ? thanks.

image

Jzhenli commented 3 years ago

@sieukrem @trdm Can you help to check how to integrate the dtree lib into the jn-npp-plugin, I have tried but cannot get the right method.

trdm commented 3 years ago

@sieukrem @trdm Can you help to check how to integrate the dtree lib into the jn-npp-plugin, I have tried but cannot get the right method.

да не нужно, у jn-npp-plugin уже есть все что надо. А код посмотрю потом.

Jzhenli commented 3 years ago

@trdm I have a html written with dtree as follows, image

I'm newer to js, and don't know how to displayed it in the JN dockable?

trdm commented 3 years ago

Screenshot_202

mytest.zip z_dtree_exam.js - кидаешь в %Notepad++\plugins\jN\jN\includes\% А в нем в function dtree_exam() настраиваешь путь к своим файлам. У меня так: vPath = 'E:\Projects\www\jNpp\mytest\dtree\'; только есть геммогой. Когда выполнена команда dtree_exam(), то появляется окно, но его еще надо обновить... Screenshot_203

trdm commented 3 years ago

А как заставить docable сразу навигировать на локальный файл (без фреймов) я еще не разобрался. :(

Jzhenli commented 3 years ago

@trdm great, thanks for your help, now it works, the key is to refresh the dockable manually, then it will display the tree.

I have a little improve it by add the following line, then it will auto refresh the page.

image

Now I have new question for the tree, when the tree node is clicked, how to jump to the special line in the text file as follows. Not sure if it's possible to implement it?

image

here is the code for your reference. mytest.zip

trdm commented 3 years ago

Самому интересно, как пересылать события IDialog в IEditor...

Jzhenli commented 3 years ago

seems the Notepad++ function list dockable can jump to the line by clicked the tree node.

image

sieukrem commented 3 years ago

Here is the reference how to jump to a location in file

Jzhenli commented 3 years ago

@sieukrem the reference you give is for table, but we use the 3rd lib dtree, and integrate the html file into the dockable, at present I have not find a solution to get the event from it. @trdm do you have any suggestion?

trdm commented 3 years ago

Просто надо изучить вопрос. не хочу играть в угадайку.

Jzhenli commented 3 years ago

@trdm how to call the jn-npp-plugin api in the frameset src dtree html file? or get the dree clicked event from the frameset src html? seems it's impossible.

Jzhenli commented 3 years ago

@sieukrem does jn-npp-plugin dockable support addeventlistener function? now I have a iframe src in the dockable, but cannot get the click event from the iframe, do u have any suggestion?

sieukrem commented 3 years ago

The dockable window hosts an html document. The document object is accessible as in jN javascript environment as in the document's javascript environment. Use this fact to inject communication functions.

var myFunctions = {
     onNodeClick: function(node){alert(node)}
}
var myDockable = Editor.createDockable({
  name:"Some Tree",
  docking:"right"
});
myDockable.document.write("<html><body onClick='NodeFunctions.onNodeClick(123)'>click me</body></html>");
myDockable.document.close();

// object injection only after document.close() call
myDockable.document.NodeFunctions = myFunctions;

The usage of frames creates additional indirection and makes the handling difficult. What if you try to use dtree directly in the dockable's document?

Jzhenli commented 3 years ago

@sieukrem this is my test code

testcode.zip

I use the frame in the dockable to implement the treeview with dtree lib, and want to postMessage from the frame to the dockable for the node clicked event, but cannot get this message the in dockable.

Besides, as you mentioned above, if not use the 3rd lib dtree, I'm not sure how to implement a powerful treeview in the dockable.

sieukrem commented 3 years ago

I don't know what you mean with powerful, but I prepared following example satisfying needs (tree representation, navigation to a line ) gathered from discussion

var w = Editor.createDockable({
    onbeforeclose:function(){
        return true;
    },
    onclose:function(){
    },
    name: "tree", 
    docking: 'bottom'
    });
var d = w.document;

d.write('<!DOCTYPE html><html>\
    <head><style>\
        body, html {\
          padding:0; margin:0; overflow:auto; font-family: verdana; font-size:11px\
        }\
        li {  \
            cursor: pointer; \
        }\
        li > span:hover{\
            background:#eee;\
        }\
        li > span {  \
            overflow: hidden; height:1.3em; display: block; float:left;\
        }\
        li{clear:both}\
        li > i {  \
            overflow: hidden; height:1.3em; width:18px; float:left; display:block;\
            background-position: center;  background-repeat: no-repeat; background-position-x: left;\
            background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAAx0lEQVR4nJ2SMYoCQRBF38gcQDzHXkDdZEEW1lyPYDSpockaeoPNN9kNBQWTSdTbjEhjN3R30W2wzMDoLA5+KCh+Ufxfn0oA5odzpAVWw25ClhdRQmxVWV7EVDtBubpA7+sNgNMsr/HaCalxwsWHRgu3vHFCqu29QolbXlshNVZQLjD4fb9bePkeVf1xssNYoaOtR/nHISkf0daXlgI/4201nG4+AGqccuHPUlNK/97wVEqmIaXP/rpRwVghAegs9q1eIyxfkyuea6Zqsnbd9gAAAABJRU5ErkJggg==")\
        }\
        ul {                                        \
          list-style-type: none; \
          margin-left:12px; \
        } \
        li > ul {                                        \
          margin-left:18px;                          \
        } \
        li > ul {\
          display: none !important;\
        }\
        li.open > i{\
            background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAAk0lEQVR4nLWQMQoCMRBFX5YcwMIjeAvFE21raWXpgSwXRHtbwSO4IMEEZjIkFmKr2cKB383jfb4D2JwflYbbL2eOfhirldqUfhirj2oEbRIQ1fBJjWcuTUBSw0eZYBDDJzGCFubrxdfn+/FGEqOLkgn5tyHkSpT8qVS4HK7fCS3vSv9fKU1YKYnhALrtqYkou5V7Ad34jw8khWGgAAAAAElFTkSuQmCC");\
        }\
        li.open > ul {\
          display: block !important;\
        }\
    </style></head>\
    <body id="tree-root" onclick="TreeView.onClick(event)"></body>\
</html>');

d.close();

var nodes = [
    {label:"Beverages", children:[
        { label:"Water", data:"my data 1", line: 10 },
        { label:"Tea", children:[
            { label:"Black Tea" },
            { label:"Green Tea", children:[
                { label:"Sencha" , data: "my data 2"},
                { label:"Gyokuro" }
            ]}
        ]}
    ]}
];

d.TreeView = {
    // called on click, provides original element
    onDidClickElement:function(el){
        alert("Clicked "+el.label+" data "+el.data);
        if (el.line)
            currentView.line = el.line;
    },

    onClick:function(event){
        var nodeDomEl = (event.target||event.srcElement).parentElement;
        var nodeEl = this.map[nodeDomEl.id];

        if(!!nodeEl)
            this.onDidClickElement(nodeEl);

        this.toggle(nodeDomEl, "open");
    },
    toggle:function(el, cl){
        if (cl === el.className){ 
            el.className = "" ;
        } else {
            el.className = cl;
        } 
    },

    addChildren:function(parentDomEl, els){
        if (!els || els.length == 0)
            return;

        var doc = parentDomEl.ownerDocument;
        var ulDomEl = doc.createElement("ul");

        for(var i=0; i<els.length; i++){
            var li = doc.createElement("li");
            var id = "n"+(this.id++);
            li.setAttribute("id", id);

            var el = els[i];
            this.map[id] = el;

            var item = this.TreeDataProvider.getTreeItem(el);

            var label = doc.createElement("span");
            label.innerText = item.label;

            var elChildren = this.TreeDataProvider.getChildren(el);
            if(elChildren && elChildren.length > 0){
                var expander = doc.createElement("i");
                li.appendChild(expander);
            }

            li.appendChild(label);

            this.addChildren(li, elChildren);

            ulDomEl.appendChild(li);
        }
        parentDomEl.appendChild(ulDomEl);
    },
    map:{},
    id:0

};

d.TreeView.TreeDataProvider = {
    // iterates through the tree elements
    getChildren: function(el){
        if (!el)
            return nodes;

        return el.children;
    },
    // transforms the element data to the tree item representation
    getTreeItem: function(el){
        return { label:el.label };
    }
}
d.TreeView.addChildren(d.getElementById("tree-root"), d.TreeView.TreeDataProvider.getChildren(null));

delete d;       

When you click on collapsed elements they will expand, and if you click on water it will jump to the given line in the node data.

Jzhenli commented 3 years ago

@sieukrem thanks for your example, it's good, but meanwhile it miss feature such as open to the node, when we clicked the text line, we expect it can open to node in the tree view.

sieukrem commented 3 years ago

Good point! :D I would appreciate to see a PR extending existing dialog.js for the tree functionality with bidirectional eventing from DataProvider to tree view and from tree view to Npp scripts.

Jzhenli commented 3 years ago

Great if these features can be implemented in the dialog.js, I'm looking forward to it. Unfortunately I'm newer to JS and cannot help too much on this PR.

Jzhenli commented 3 years ago

@sieukrem base on your example above, how to jump to the tree node automatically when clicked the text line in the current view?