parent
130d4deb0a
commit
b92fc0dabc
7 changed files with 3808 additions and 2 deletions
@ -0,0 +1,48 @@ |
||||
#!/usr/bin/env python3 |
||||
# -*- coding: utf-8 -*- |
||||
|
||||
# Copyright (C) 2018 Andy Stewart |
||||
# |
||||
# Author: Andy Stewart <lazycat.manatee@gmail.com> |
||||
# Maintainer: Andy Stewart <lazycat.manatee@gmail.com> |
||||
# |
||||
# This program is free software: you can redistribute it and/or modify |
||||
# it under the terms of the GNU General Public License as published by |
||||
# the Free Software Foundation, either version 3 of the License, or |
||||
# any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
||||
from PyQt5.QtCore import QUrl |
||||
from PyQt5.QtGui import QColor |
||||
from core.browser import BrowserBuffer |
||||
import os |
||||
|
||||
class AppBuffer(BrowserBuffer): |
||||
def __init__(self, buffer_id, url, config_dir, arguments, emacs_var_dict): |
||||
BrowserBuffer.__init__(self, buffer_id, url, config_dir, arguments, emacs_var_dict, False, QColor(255, 255, 255, 255)) |
||||
|
||||
self.url = "file://" + (os.path.join(os.path.dirname(__file__), "index.html")) |
||||
self.buffer_widget.setUrl(QUrl(self.url)) |
||||
|
||||
def add_sub_node(self): |
||||
self.buffer_widget.eval_js("add_node();") |
||||
|
||||
def remove_node(self): |
||||
self.buffer_widget.eval_js("remove_node();") |
||||
|
||||
def update_node_topic(self): |
||||
self.send_input_message("Update topic: ", "update_node_topic") |
||||
|
||||
def handle_update_node_topic(self, topic): |
||||
self.buffer_widget.eval_js("update_node_topic('{}');".format(topic)) |
||||
|
||||
def handle_input_message(self, result_type, result_content): |
||||
if result_type == "update_node_topic": |
||||
self.handle_update_node_topic(str(result_content)) |
||||
@ -0,0 +1,75 @@ |
||||
<!doctype html> |
||||
<html> |
||||
<head> |
||||
<meta charset="utf-8"> |
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
||||
<link type="text/css" rel="stylesheet" href="jsmind.css" /> |
||||
|
||||
<script type="text/javascript" src="jsmind.js"></script> |
||||
<script type="text/javascript" src="jsmind.draggable.js"></script> |
||||
<script type="text/javascript" src="jsmind.screenshot.js"></script> |
||||
<style type="text/css"> |
||||
html, body { |
||||
width: 100%; |
||||
height: 100%; |
||||
margin: 0; |
||||
padding: 0; |
||||
} |
||||
|
||||
#jsmind_container{ |
||||
width: 100%; |
||||
height: 100%; |
||||
} |
||||
</style> |
||||
</head> |
||||
<body> |
||||
<div id="jsmind_container"></div> |
||||
|
||||
<script type="text/javascript"> |
||||
var _jm = null; |
||||
function open_empty(){ |
||||
var options = { |
||||
container:'jsmind_container', |
||||
theme:'greensea', |
||||
editable:true |
||||
} |
||||
_jm = jsMind.show(options); |
||||
} |
||||
|
||||
open_empty(); |
||||
|
||||
function add_node(){ |
||||
var selected_node = _jm.get_selected_node(); // as parent of new node |
||||
if(!selected_node) { |
||||
_jm.move_node(selected_id,'_first_'); |
||||
} |
||||
|
||||
var nodeid = jsMind.util.uuid.newid(); |
||||
var node = _jm.add_node(selected_node, nodeid, 'Topic'); |
||||
} |
||||
|
||||
function get_selected_nodeid(){ |
||||
var selected_node = _jm.get_selected_node(); |
||||
if(!!selected_node){ |
||||
return selected_node.id; |
||||
}else{ |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
function remove_node(){ |
||||
var selected_id = get_selected_nodeid(); |
||||
if(selected_id) { |
||||
_jm.remove_node(selected_id); |
||||
} |
||||
} |
||||
|
||||
function update_node_topic(topic) { |
||||
var selected_id = get_selected_nodeid(); |
||||
if (selected_id) { |
||||
_jm.update_node(selected_id, topic); |
||||
} |
||||
} |
||||
</script> |
||||
</body> |
||||
</html> |
||||
@ -0,0 +1,48 @@ |
||||
/* |
||||
* Released under BSD License |
||||
* Copyright (c) 2014-2015 hizzgdev@163.com |
||||
* |
||||
* Project Home: |
||||
* https://github.com/hizzgdev/jsmind/ |
||||
*/ |
||||
|
||||
/* important section */ |
||||
.jsmind-inner{position:relative;overflow:auto;width:100%;height:100%;}/*box-shadow:0 0 2px #000;*/ |
||||
.jsmind-inner{ |
||||
moz-user-select:-moz-none; |
||||
-moz-user-select:none; |
||||
-o-user-select:none; |
||||
-khtml-user-select:none; |
||||
-webkit-user-select:none; |
||||
-ms-user-select:none; |
||||
user-select:none; |
||||
} |
||||
|
||||
/* z-index:1 */ |
||||
canvas{position:absolute;z-index:1;} |
||||
|
||||
/* z-index:2 */ |
||||
jmnodes{position:absolute;z-index:2;background-color:rgba(0,0,0,0);}/*background color is necessary*/ |
||||
jmnode{position:absolute;cursor:default;max-width:400px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;} |
||||
jmexpander{position:absolute;width:11px;height:11px;display:block;overflow:hidden;line-height:12px;font-size:12px;text-align:center;border-radius:6px;border-width:1px;border-style:solid;cursor:pointer;} |
||||
|
||||
/* default theme */ |
||||
jmnode{padding:10px;background-color:#fff;color:#333;border-radius:5px;box-shadow:1px 1px 1px #666;font:16px/1.125 Verdana,Arial,Helvetica,sans-serif;} |
||||
jmnode:hover{box-shadow:2px 2px 8px #000;background-color:#ebebeb;color:#333;} |
||||
jmnode.selected{background-color:#11f;color:#fff;box-shadow:2px 2px 8px #000;} |
||||
jmnode.root{font-size:24px;} |
||||
jmexpander{border-color:gray;} |
||||
jmexpander:hover{border-color:#000;} |
||||
|
||||
@media screen and (max-device-width: 1024px) { |
||||
jmnode{padding:5px;border-radius:3px;font-size:14px;} |
||||
jmnode.root{font-size:21px;} |
||||
} |
||||
|
||||
/* greensea theme */ |
||||
jmnodes.theme-greensea jmnode{background-color:#1abc9c;color:#fff;} |
||||
jmnodes.theme-greensea jmnode:hover{background-color:#16a085;} |
||||
jmnodes.theme-greensea jmnode.selected{background-color:#11f;color:#fff;} |
||||
jmnodes.theme-greensea jmnode.root{} |
||||
jmnodes.theme-greensea jmexpander{} |
||||
jmnodes.theme-greensea jmexpander:hover{} |
||||
@ -0,0 +1,349 @@ |
||||
/* |
||||
* Released under BSD License |
||||
* Copyright (c) 2014-2015 hizzgdev@163.com |
||||
*
|
||||
* Project Home: |
||||
* https://github.com/hizzgdev/jsmind/
|
||||
*/ |
||||
|
||||
(function($w){ |
||||
'use strict'; |
||||
var $d = $w.document; |
||||
var __name__ = 'jsMind'; |
||||
var jsMind = $w[__name__]; |
||||
if(!jsMind){return;} |
||||
if(typeof jsMind.draggable != 'undefined'){return;} |
||||
|
||||
var jdom = jsMind.util.dom; |
||||
var jcanvas = jsMind.util.canvas; |
||||
|
||||
var clear_selection = 'getSelection' in $w ? function(){ |
||||
$w.getSelection().removeAllRanges(); |
||||
} : function(){ |
||||
$d.selection.empty(); |
||||
}; |
||||
|
||||
var options = { |
||||
line_width : 5, |
||||
lookup_delay : 500, |
||||
lookup_interval : 80 |
||||
}; |
||||
|
||||
jsMind.draggable = function(jm){ |
||||
this.jm = jm; |
||||
this.e_canvas = null; |
||||
this.canvas_ctx = null; |
||||
this.shadow = null; |
||||
this.shadow_w = 0; |
||||
this.shadow_h = 0; |
||||
this.active_node = null; |
||||
this.target_node = null; |
||||
this.target_direct = null; |
||||
this.client_w = 0; |
||||
this.client_h = 0; |
||||
this.offset_x = 0; |
||||
this.offset_y = 0; |
||||
this.hlookup_delay = 0; |
||||
this.hlookup_timer = 0; |
||||
this.capture = false; |
||||
this.moved = false; |
||||
}; |
||||
|
||||
jsMind.draggable.prototype = { |
||||
init:function(){ |
||||
this._create_canvas(); |
||||
this._create_shadow(); |
||||
this._event_bind(); |
||||
}, |
||||
|
||||
resize:function(){ |
||||
this.jm.view.e_nodes.appendChild(this.shadow); |
||||
this.e_canvas.width=this.jm.view.size.w; |
||||
this.e_canvas.height=this.jm.view.size.h; |
||||
}, |
||||
|
||||
_create_canvas:function(){ |
||||
var c = $d.createElement('canvas'); |
||||
this.jm.view.e_panel.appendChild(c); |
||||
var ctx = c.getContext('2d'); |
||||
this.e_canvas = c; |
||||
this.canvas_ctx = ctx; |
||||
}, |
||||
|
||||
_create_shadow:function(){ |
||||
var s = $d.createElement('jmnode'); |
||||
s.style.visibility = 'hidden'; |
||||
s.style.zIndex = '3'; |
||||
s.style.cursor = 'move'; |
||||
s.style.opacity= '0.7'; |
||||
this.shadow = s; |
||||
}, |
||||
|
||||
reset_shadow:function(el){ |
||||
var s = this.shadow.style; |
||||
this.shadow.innerHTML = el.innerHTML; |
||||
s.left = el.style.left; |
||||
s.top = el.style.top; |
||||
s.width = el.style.width; |
||||
s.height = el.style.height; |
||||
s.backgroundImage = el.style.backgroundImage; |
||||
s.backgroundSize = el.style.backgroundSize; |
||||
s.transform = el.style.transform; |
||||
this.shadow_w = this.shadow.clientWidth; |
||||
this.shadow_h = this.shadow.clientHeight; |
||||
|
||||
}, |
||||
|
||||
show_shadow:function(){ |
||||
if(!this.moved){ |
||||
this.shadow.style.visibility = 'visible'; |
||||
} |
||||
}, |
||||
|
||||
hide_shadow:function(){ |
||||
this.shadow.style.visibility = 'hidden'; |
||||
}, |
||||
|
||||
clear_lines:function(){ |
||||
jcanvas.clear(this.canvas_ctx, 0, 0, this.jm.view.size.w, this.jm.view.size.h); |
||||
}, |
||||
|
||||
_magnet_shadow:function(node){ |
||||
if(!!node){ |
||||
this.canvas_ctx.lineWidth = options.line_width; |
||||
this.canvas_ctx.strokeStyle = 'rgba(0,0,0,0.3)'; |
||||
this.canvas_ctx.lineCap = 'round'; |
||||
this.clear_lines(); |
||||
jcanvas.lineto(this.canvas_ctx, |
||||
node.sp.x, |
||||
node.sp.y, |
||||
node.np.x, |
||||
node.np.y); |
||||
} |
||||
}, |
||||
|
||||
_lookup_close_node:function(){ |
||||
var root = this.jm.get_root(); |
||||
var root_location = root.get_location(); |
||||
var root_size = root.get_size(); |
||||
var root_x = root_location.x + root_size.w/2; |
||||
|
||||
var sw = this.shadow_w; |
||||
var sh = this.shadow_h; |
||||
var sx = this.shadow.offsetLeft; |
||||
var sy = this.shadow.offsetTop; |
||||
|
||||
var ns,nl; |
||||
|
||||
var direct = (sx + sw/2)>=root_x ? |
||||
jsMind.direction.right : jsMind.direction.left; |
||||
var nodes = this.jm.mind.nodes; |
||||
var node = null; |
||||
var min_distance = Number.MAX_VALUE; |
||||
var distance = 0; |
||||
var closest_node = null; |
||||
var closest_p = null; |
||||
var shadow_p = null; |
||||
for(var nodeid in nodes){ |
||||
var np,sp; |
||||
node = nodes[nodeid]; |
||||
if(node.isroot || node.direction == direct){ |
||||
if(node.id == this.active_node.id){ |
||||
continue; |
||||
} |
||||
ns = node.get_size(); |
||||
nl = node.get_location(); |
||||
if(direct == jsMind.direction.right){ |
||||
if(sx-nl.x-ns.w<=0){continue;} |
||||
distance = Math.abs(sx-nl.x-ns.w) + Math.abs(sy+sh/2-nl.y-ns.h/2); |
||||
np = {x:nl.x+ns.w-options.line_width,y:nl.y+ns.h/2}; |
||||
sp = {x:sx+options.line_width,y:sy+sh/2}; |
||||
}else{ |
||||
if(nl.x-sx-sw<=0){continue;} |
||||
distance = Math.abs(sx+sw-nl.x) + Math.abs(sy+sh/2-nl.y-ns.h/2); |
||||
np = {x:nl.x+options.line_width,y:nl.y+ns.h/2}; |
||||
sp = {x:sx+sw-options.line_width,y:sy+sh/2}; |
||||
} |
||||
if(distance < min_distance){ |
||||
closest_node = node; |
||||
closest_p = np; |
||||
shadow_p = sp; |
||||
min_distance = distance; |
||||
} |
||||
} |
||||
} |
||||
var result_node = null; |
||||
if(!!closest_node){ |
||||
result_node = { |
||||
node:closest_node, |
||||
direction:direct, |
||||
sp:shadow_p, |
||||
np:closest_p |
||||
}; |
||||
} |
||||
return result_node; |
||||
}, |
||||
|
||||
lookup_close_node:function(){ |
||||
var node_data = this._lookup_close_node(); |
||||
if(!!node_data){ |
||||
this._magnet_shadow(node_data); |
||||
this.target_node = node_data.node; |
||||
this.target_direct = node_data.direction; |
||||
} |
||||
}, |
||||
|
||||
_event_bind:function(){ |
||||
var jd = this; |
||||
var container = this.jm.view.container; |
||||
jdom.add_event(container,'mousedown',function(e){ |
||||
var evt = e || event; |
||||
jd.dragstart.call(jd,evt); |
||||
}); |
||||
jdom.add_event(container,'mousemove',function(e){ |
||||
var evt = e || event; |
||||
jd.drag.call(jd,evt); |
||||
}); |
||||
jdom.add_event(container,'mouseup',function(e){ |
||||
var evt = e || event; |
||||
jd.dragend.call(jd,evt); |
||||
}); |
||||
jdom.add_event(container,'touchstart',function(e){ |
||||
var evt = e || event; |
||||
jd.dragstart.call(jd,evt); |
||||
}); |
||||
jdom.add_event(container,'touchmove',function(e){ |
||||
var evt = e || event; |
||||
jd.drag.call(jd,evt); |
||||
}); |
||||
jdom.add_event(container,'touchend',function(e){ |
||||
var evt = e || event; |
||||
jd.dragend.call(jd,evt); |
||||
}); |
||||
}, |
||||
|
||||
dragstart:function(e){ |
||||
if(!this.jm.get_editable()){return;} |
||||
if(this.capture){return;} |
||||
this.active_node = null; |
||||
|
||||
var jview = this.jm.view; |
||||
var el = e.target || event.srcElement; |
||||
if(el.tagName.toLowerCase() != 'jmnode'){return;} |
||||
var nodeid = jview.get_binded_nodeid(el); |
||||
if(!!nodeid){ |
||||
var node = this.jm.get_node(nodeid); |
||||
if(!node.isroot){ |
||||
this.reset_shadow(el); |
||||
this.active_node = node; |
||||
this.offset_x = (e.clientX || e.touches[0].clientX) - el.offsetLeft; |
||||
this.offset_y = (e.clientY || e.touches[0].clientY) - el.offsetTop; |
||||
this.client_hw = Math.floor(el.clientWidth/2); |
||||
this.client_hh = Math.floor(el.clientHeight/2); |
||||
if(this.hlookup_delay != 0){ |
||||
$w.clearTimeout(this.hlookup_delay); |
||||
} |
||||
if(this.hlookup_timer != 0){ |
||||
$w.clearInterval(this.hlookup_timer); |
||||
} |
||||
var jd = this; |
||||
this.hlookup_delay = $w.setTimeout(function(){ |
||||
jd.hlookup_delay = 0; |
||||
jd.hlookup_timer = $w.setInterval(function(){ |
||||
jd.lookup_close_node.call(jd); |
||||
},options.lookup_interval); |
||||
},options.lookup_delay); |
||||
this.capture = true; |
||||
} |
||||
} |
||||
}, |
||||
|
||||
drag:function(e){ |
||||
if(!this.jm.get_editable()){return;} |
||||
if(this.capture){ |
||||
e.preventDefault(); |
||||
this.show_shadow(); |
||||
this.moved = true; |
||||
clear_selection(); |
||||
var px = (e.clientX || e.touches[0].clientX) - this.offset_x; |
||||
var py = (e.clientY || e.touches[0].clientY) - this.offset_y; |
||||
var cx = px + this.client_hw; |
||||
var cy = py + this.client_hh; |
||||
this.shadow.style.left = px + 'px'; |
||||
this.shadow.style.top = py + 'px'; |
||||
clear_selection(); |
||||
} |
||||
}, |
||||
|
||||
dragend:function(e){ |
||||
if(!this.jm.get_editable()){return;} |
||||
if(this.capture){ |
||||
if(this.hlookup_delay != 0){ |
||||
$w.clearTimeout(this.hlookup_delay); |
||||
this.hlookup_delay = 0; |
||||
this.clear_lines(); |
||||
} |
||||
if(this.hlookup_timer != 0){ |
||||
$w.clearInterval(this.hlookup_timer); |
||||
this.hlookup_timer = 0; |
||||
this.clear_lines(); |
||||
} |
||||
if(this.moved){ |
||||
var src_node = this.active_node; |
||||
var target_node = this.target_node; |
||||
var target_direct = this.target_direct; |
||||
this.move_node(src_node,target_node,target_direct); |
||||
} |
||||
this.hide_shadow(); |
||||
} |
||||
this.moved = false; |
||||
this.capture = false; |
||||
}, |
||||
|
||||
move_node:function(src_node,target_node,target_direct){ |
||||
var shadow_h = this.shadow.offsetTop; |
||||
if(!!target_node && !!src_node && !jsMind.node.inherited(src_node, target_node)){ |
||||
// lookup before_node
|
||||
var sibling_nodes = target_node.children; |
||||
var sc = sibling_nodes.length; |
||||
var node = null; |
||||
var delta_y = Number.MAX_VALUE; |
||||
var node_before = null; |
||||
var beforeid = '_last_'; |
||||
while(sc--){ |
||||
node = sibling_nodes[sc]; |
||||
if(node.direction == target_direct && node.id != src_node.id){ |
||||
var dy = node.get_location().y - shadow_h; |
||||
if(dy > 0 && dy < delta_y){ |
||||
delta_y = dy; |
||||
node_before = node; |
||||
beforeid = '_first_'; |
||||
} |
||||
} |
||||
} |
||||
if(!!node_before){beforeid = node_before.id;} |
||||
this.jm.move_node(src_node.id, beforeid, target_node.id, target_direct); |
||||
} |
||||
this.active_node = null; |
||||
this.target_node = null; |
||||
this.target_direct = null; |
||||
}, |
||||
|
||||
jm_event_handle:function(type,data){ |
||||
if(type === jsMind.event_type.resize){ |
||||
this.resize(); |
||||
} |
||||
} |
||||
}; |
||||
|
||||
var draggable_plugin = new jsMind.plugin('draggable',function(jm){ |
||||
var jd = new jsMind.draggable(jm); |
||||
jd.init(); |
||||
jm.add_event_listener(function(type,data){ |
||||
jd.jm_event_handle.call(jd,type,data); |
||||
}); |
||||
}); |
||||
|
||||
jsMind.register_plugin(draggable_plugin); |
||||
|
||||
})(window); |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,349 @@ |
||||
/* |
||||
* Released under BSD License |
||||
* Copyright (c) 2014-2015 hizzgdev@163.com |
||||
*
|
||||
* Project Home: |
||||
* https://github.com/hizzgdev/jsmind/
|
||||
*/ |
||||
|
||||
(function($w){ |
||||
'use strict'; |
||||
|
||||
var __name__ = 'jsMind'; |
||||
var jsMind = $w[__name__]; |
||||
if(!jsMind){return;} |
||||
if(typeof jsMind.screenshot != 'undefined'){return;} |
||||
|
||||
var $d = $w.document; |
||||
var $c = function(tag){return $d.createElement(tag);}; |
||||
|
||||
var css = function(cstyle,property_name){ |
||||
return cstyle.getPropertyValue(property_name); |
||||
}; |
||||
var is_visible = function(cstyle){ |
||||
var visibility = css(cstyle,'visibility'); |
||||
var display = css(cstyle,'display'); |
||||
return (visibility !== 'hidden' && display !== 'none'); |
||||
}; |
||||
var jcanvas = jsMind.util.canvas; |
||||
jcanvas.rect = function (ctx,x,y,w,h,r) { |
||||
if (w < 2 * r) r = w / 2; |
||||
if (h < 2 * r) r = h / 2; |
||||
ctx.moveTo(x+r, y); |
||||
ctx.arcTo(x+w, y, x+w, y+h, r); |
||||
ctx.arcTo(x+w, y+h, x, y+h, r); |
||||
ctx.arcTo(x, y+h, x, y, r); |
||||
ctx.arcTo(x, y, x+w, y, r); |
||||
}; |
||||
|
||||
jcanvas.text_multiline = function(ctx,text,x,y,w,h,lineheight){ |
||||
var line = ''; |
||||
var text_len = text.length; |
||||
var chars = text.split(''); |
||||
var test_line = null; |
||||
ctx.textAlign = 'left'; |
||||
ctx.textBaseline = 'top'; |
||||
for(var i=0;i<text_len;i++){ |
||||
test_line = line + chars[i]; |
||||
if(ctx.measureText(test_line).width > w && i>0){ |
||||
ctx.fillText(line,x,y); |
||||
line = chars[i]; |
||||
y += lineheight; |
||||
}else{ |
||||
line = test_line; |
||||
} |
||||
} |
||||
ctx.fillText(line,x,y); |
||||
}; |
||||
|
||||
jcanvas.text_ellipsis = function(ctx,text,x,y,w,h){ |
||||
var center_y = y+h/2; |
||||
var text = jcanvas.fittingString(ctx,text,w); |
||||
ctx.textAlign = 'left'; |
||||
ctx.textBaseline = 'middle'; |
||||
ctx.fillText(text,x,center_y,w); |
||||
}; |
||||
|
||||
jcanvas.fittingString = function(ctx,text,max_width) { |
||||
var width = ctx.measureText(text).width; |
||||
var ellipsis = '…' |
||||
var ellipsis_width = ctx.measureText(ellipsis).width; |
||||
if (width<=max_width || width<=ellipsis_width) { |
||||
return text; |
||||
} else { |
||||
var len = text.length; |
||||
while (width>=max_width-ellipsis_width && len-->0) { |
||||
text = text.substring(0, len); |
||||
width = ctx.measureText(text).width; |
||||
} |
||||
return text+ellipsis; |
||||
} |
||||
}; |
||||
|
||||
jcanvas.image = function(ctx,backgroundUrl,x,y,w,h,r,rotation,callback){ |
||||
var img = new Image(); |
||||
img.onload = function () { |
||||
ctx.save(); |
||||
ctx.translate(x,y); |
||||
ctx.save(); |
||||
ctx.beginPath(); |
||||
jcanvas.rect(ctx,0,0,w,h,r); |
||||
ctx.closePath(); |
||||
ctx.clip(); |
||||
ctx.translate(w/2,h/2); |
||||
ctx.rotate(rotation*Math.PI/180); |
||||
ctx.drawImage(img,-w/2,-h/2); |
||||
ctx.restore(); |
||||
ctx.restore(); |
||||
callback(); |
||||
} |
||||
img.src = backgroundUrl; |
||||
}; |
||||
|
||||
jsMind.screenshot = function(jm){ |
||||
this.jm = jm; |
||||
this.canvas_elem = null; |
||||
this.canvas_ctx = null; |
||||
this._inited = false; |
||||
}; |
||||
|
||||
jsMind.screenshot.prototype = { |
||||
init:function(){ |
||||
if(this._inited){return;} |
||||
console.log('init'); |
||||
var c = $c('canvas'); |
||||
var ctx = c.getContext('2d'); |
||||
|
||||
this.canvas_elem = c; |
||||
this.canvas_ctx = ctx; |
||||
this.jm.view.e_panel.appendChild(c); |
||||
this._inited = true; |
||||
this.resize(); |
||||
}, |
||||
|
||||
shoot:function(callback){ |
||||
this.init(); |
||||
this._watermark(); |
||||
var jms = this; |
||||
this._draw(function(){ |
||||
if(!!callback){ |
||||
callback(jms); |
||||
} |
||||
jms.clean(); |
||||
}); |
||||
}, |
||||
|
||||
shootDownload: function(){ |
||||
this.shoot(function(jms){ |
||||
jms._download(); |
||||
}); |
||||
}, |
||||
|
||||
shootAsDataURL: function(callback){ |
||||
this.shoot(function(jms){ |
||||
callback(jms.canvas_elem.toDataURL()); |
||||
}); |
||||
}, |
||||
|
||||
resize:function(){ |
||||
if(this._inited){ |
||||
this.canvas_elem.width=this.jm.view.size.w; |
||||
this.canvas_elem.height=this.jm.view.size.h; |
||||
} |
||||
}, |
||||
|
||||
clean:function(){ |
||||
var c = this.canvas_elem; |
||||
this.canvas_ctx.clearRect(0,0,c.width,c.height); |
||||
}, |
||||
|
||||
_draw:function(callback){ |
||||
var ctx = this.canvas_ctx; |
||||
ctx.textAlign = 'left'; |
||||
ctx.textBaseline = 'top'; |
||||
this._draw_lines(); |
||||
this._draw_nodes(callback); |
||||
}, |
||||
|
||||
_watermark:function(){ |
||||
var c = this.canvas_elem; |
||||
var ctx = this.canvas_ctx; |
||||
ctx.textAlign='right'; |
||||
ctx.textBaseline='bottom'; |
||||
ctx.fillStyle='#000'; |
||||
ctx.font='11px Verdana,Arial,Helvetica,sans-serif'; |
||||
ctx.fillText('hizzgdev.github.io/jsmind',c.width-5.5,c.height-2.5); |
||||
ctx.textAlign='left'; |
||||
ctx.fillText($w.location,5.5,c.height-2.5); |
||||
}, |
||||
|
||||
_draw_lines:function(){ |
||||
this.jm.view.show_lines(this.canvas_ctx); |
||||
}, |
||||
|
||||
_draw_nodes:function(callback){ |
||||
var nodes = this.jm.mind.nodes; |
||||
var node; |
||||
for(var nodeid in nodes){ |
||||
node = nodes[nodeid]; |
||||
this._draw_node(node); |
||||
} |
||||
|
||||
function check_nodes_ready() { |
||||
console.log('check_node_ready'+new Date()); |
||||
var allOk = true; |
||||
for(var nodeid in nodes){ |
||||
node = nodes[nodeid]; |
||||
allOk = allOk & node.ready; |
||||
} |
||||
|
||||
if(!allOk) { |
||||
$w.setTimeout(check_nodes_ready, 200); |
||||
} else { |
||||
$w.setTimeout(callback, 200); |
||||
} |
||||
} |
||||
check_nodes_ready(); |
||||
}, |
||||
|
||||
_draw_node:function(node){ |
||||
var ctx = this.canvas_ctx; |
||||
var view_data = node._data.view; |
||||
var node_element = view_data.element; |
||||
var ncs = getComputedStyle(node_element); |
||||
if(!is_visible(ncs)){ |
||||
node.ready = true; |
||||
return; |
||||
} |
||||
|
||||
var bgcolor = css(ncs,'background-color'); |
||||
var round_radius = parseInt(css(ncs,'border-top-left-radius')); |
||||
var color = css(ncs,'color'); |
||||
var padding_left = parseInt(css(ncs,'padding-left')); |
||||
var padding_right = parseInt(css(ncs,'padding-right')); |
||||
var padding_top = parseInt(css(ncs,'padding-top')); |
||||
var padding_bottom = parseInt(css(ncs,'padding-bottom')); |
||||
var text_overflow = css(ncs,'text-overflow'); |
||||
var font = css(ncs,'font-style')+' '+ |
||||
css(ncs,'font-variant')+' '+ |
||||
css(ncs,'font-weight')+' '+ |
||||
css(ncs,'font-size')+'/'+css(ncs,'line-height')+' '+ |
||||
css(ncs,'font-family'); |
||||
|
||||
var rb = {x:view_data.abs_x, |
||||
y:view_data.abs_y, |
||||
w:view_data.width+1, |
||||
h:view_data.height+1}; |
||||
var tb = {x:rb.x+padding_left, |
||||
y:rb.y+padding_top, |
||||
w:rb.w-padding_left-padding_right, |
||||
h:rb.h-padding_top-padding_bottom}; |
||||
|
||||
ctx.font=font; |
||||
ctx.fillStyle = bgcolor; |
||||
ctx.beginPath(); |
||||
jcanvas.rect(ctx, rb.x, rb.y, rb.w, rb.h, round_radius); |
||||
ctx.closePath(); |
||||
ctx.fill(); |
||||
|
||||
ctx.fillStyle = color; |
||||
if ('background-image' in node.data) { |
||||
var backgroundUrl = css(ncs,'background-image').slice(5, -2); |
||||
node.ready = false; |
||||
var rotation = 0; |
||||
if ('background-rotation' in node.data) { |
||||
rotation = node.data['background-rotation']; |
||||
} |
||||
jcanvas.image(ctx, backgroundUrl, rb.x, rb.y, rb.w, rb.h, round_radius, rotation, |
||||
function() { |
||||
node.ready = true; |
||||
}); |
||||
} |
||||
if (!!node.topic) { |
||||
if(text_overflow === 'ellipsis'){ |
||||
jcanvas.text_ellipsis(ctx, node.topic, tb.x, tb.y, tb.w, tb.h); |
||||
}else{ |
||||
var line_height = parseInt(css(ncs,'line-height')); |
||||
jcanvas.text_multiline(ctx, node.topic, tb.x, tb.y, tb.w, tb.h,line_height); |
||||
} |
||||
} |
||||
if(!!view_data.expander){ |
||||
this._draw_expander(view_data.expander); |
||||
} |
||||
if (!('background-image' in node.data)) { |
||||
node.ready = true; |
||||
} |
||||
}, |
||||
|
||||
_draw_expander:function(expander){ |
||||
var ctx = this.canvas_ctx; |
||||
var ncs = getComputedStyle(expander); |
||||
if(!is_visible(ncs)){ return; } |
||||
|
||||
var style_left = css(ncs,'left'); |
||||
var style_top = css(ncs,'top'); |
||||
var font = css(ncs,'font'); |
||||
var left = parseInt(style_left); |
||||
var top = parseInt(style_top); |
||||
var is_plus = expander.innerHTML === '+'; |
||||
|
||||
ctx.lineWidth = 1; |
||||
|
||||
ctx.beginPath(); |
||||
ctx.arc(left+7,top+7,5,0,Math.PI*2,true); |
||||
ctx.moveTo(left+10,top+7); |
||||
ctx.lineTo(left+4,top+7); |
||||
if(is_plus){ |
||||
ctx.moveTo(left+7,top+4); |
||||
ctx.lineTo(left+7,top+10); |
||||
} |
||||
ctx.closePath(); |
||||
ctx.stroke(); |
||||
}, |
||||
|
||||
_download:function(){ |
||||
var c = this.canvas_elem; |
||||
var name = this.jm.mind.name+'.png'; |
||||
|
||||
if (navigator.msSaveBlob && (!!c.msToBlob)) { |
||||
var blob = c.msToBlob(); |
||||
navigator.msSaveBlob(blob,name); |
||||
} else { |
||||
var bloburl = this.canvas_elem.toDataURL(); |
||||
var anchor = $c('a'); |
||||
if ('download' in anchor) { |
||||
anchor.style.visibility = 'hidden'; |
||||
anchor.href = bloburl; |
||||
anchor.download = name; |
||||
$d.body.appendChild(anchor); |
||||
var evt = $d.createEvent('MouseEvents'); |
||||
evt.initEvent('click', true, true); |
||||
anchor.dispatchEvent(evt); |
||||
$d.body.removeChild(anchor); |
||||
} else { |
||||
location.href = bloburl; |
||||
} |
||||
} |
||||
}, |
||||
|
||||
jm_event_handle:function(type,data){ |
||||
if(type === jsMind.event_type.resize){ |
||||
this.resize(); |
||||
} |
||||
} |
||||
}; |
||||
|
||||
var screenshot_plugin = new jsMind.plugin('screenshot',function(jm){ |
||||
var jss = new jsMind.screenshot(jm); |
||||
jm.screenshot = jss; |
||||
jm.shoot = function(){ |
||||
jss.shoot(); |
||||
}; |
||||
jm.add_event_listener(function(type,data){ |
||||
jss.jm_event_handle.call(jss,type,data); |
||||
}); |
||||
}); |
||||
|
||||
jsMind.register_plugin(screenshot_plugin); |
||||
|
||||
})(window); |
||||
Loading…
Reference in new issue