hotkeys refactor & files up, down, right, left

This commit is contained in:
Van 2014-09-15 16:06:49 +08:00
parent e814ee39d7
commit db0c3992d0
4 changed files with 201 additions and 110 deletions

View File

@ -266,6 +266,12 @@ var editors = {
"Ctrl-E": "deleteLine", "Ctrl-E": "deleteLine",
"Ctrl-D": "doNothing", // 取消默认的 deleteLine "Ctrl-D": "doNothing", // 取消默认的 deleteLine
"Ctrl-B": "jumpToDecl", "Ctrl-B": "jumpToDecl",
"Ctrl-S": function () {
wide.saveFile();
},
"Alt-Shift-F": function () {
wide.fmt();
},
"Alt-F7": "findUsages" "Alt-F7": "findUsages"
} }
}); });

165
static/js/hotkeys.js Normal file
View File

@ -0,0 +1,165 @@
var hotkeys = {
defaultKeyMap: {
// Ctrl+1 焦点切换到文件树
goFileTree: {
ctrlKey: true,
altKey: false,
shiftKey: false,
which: 49
},
// Ctrl+4 焦点切换到输出窗口
goOutPut: {
ctrlKey: true,
altKey: false,
shiftKey: false,
which: 52
},
// F6 构建并运行
buildRun: {
ctrlKey: false,
altKey: false,
shiftKey: false,
which: 117
}
},
_bindFileTree: function() {
// TODO: 滚动处理
$("#files").keydown(function(event) {
switch (event.which) {
case 13: // 回车
if (!wide.curNode) {
return false;
}
if (wide.curNode.iconSkin === "ico-ztree-dir ") { // 选中节点是目录
// 不做任何处理
return false;
}
// 模拟点击:打开文件
tree._onClick(wide.curNode);
break;
case 38: // 上
var node = {};
if (!wide.curNode) { // 没有选中节点时,默认选中第一个
node = tree.fileTree.getNodeByTId("files_1");
} else {
if (wide.curNode && wide.curNode.isFirstNode && wide.curNode.level === 0) {
// 当前节点为顶部第一个节点
return false;
}
node = wide.curNode.getPreNode();
if (wide.curNode.isFirstNode && wide.curNode.getParentNode()) {
// 当前节点为第一个节点且有父亲
node = wide.curNode.getParentNode();
}
var preNode = wide.curNode.getPreNode();
if (preNode && preNode.iconSkin === "ico-ztree-dir "
&& preNode.open) {
// 当前节点的上一个节点是目录且打开时
node = preNode.children[preNode.children.length - 1];
}
}
wide.curNode = node;
tree.fileTree.selectNode(node);
$("#files").focus();
break;
case 40: // 下
var node = {};
if (!wide.curNode) { // 没有选中节点时,默认选中第一个
node = tree.fileTree.getNodeByTId("files_1");
} else {
if (wide.curNode && wide.curNode.isLastNode && !wide.curNode.open
&& wide.curNode.getParentNode().isLastNode) {
// 当前节点为最底部的节点
return false;
}
node = wide.curNode.getNextNode();
if (wide.curNode.iconSkin === "ico-ztree-dir " && wide.curNode.open) {
// 当前节点是目录且打开时
node = wide.curNode.children[0];
}
if (wide.curNode.isLastNode && wide.curNode.level !== 0
&& wide.curNode.getParentNode().getNextNode()) {
// 当前节点为最后一个节点,但其父节点还有下一个节点
node = wide.curNode.getParentNode().getNextNode();
}
}
wide.curNode = node;
tree.fileTree.selectNode(node);
$("#files").focus();
break;
case 37: // 左
if (!wide.curNode) {
wide.curNode = tree.fileTree.getNodeByTId("files_1");
tree.fileTree.selectNode(wide.curNode);
$("#files").focus();
return false;
}
if (wide.curNode.iconSkin !== "ico-ztree-dir " || !wide.curNode.open) {
return false;
}
tree.fileTree.expandNode(wide.curNode, false, false, true);
$("#files").focus();
break;
case 39: // 右
if (!wide.curNode) {
wide.curNode = tree.fileTree.getNodeByTId("files_1");
tree.fileTree.selectNode(wide.curNode);
$("#files").focus();
return false;
}
if (wide.curNode.iconSkin !== "ico-ztree-dir " || wide.curNode.open) {
return false;
}
tree.fileTree.expandNode(wide.curNode, true, false, true);
$("#files").focus();
break;
}
});
},
init: function() {
this._bindFileTree();
var hotKeys = this.defaultKeyMap;
$(document).keydown(function(event) {
if (event.ctrlKey === hotKeys.goFileTree.ctrlKey
&& event.which === hotKeys.goFileTree.which) { // Ctrl+1 焦点切换到文件树
// 有些元素需设置 tabindex 为 -1 时才可以 focus
$("#files").focus();
event.preventDefault();
return;
}
if (event.ctrlKey === hotKeys.goOutPut.ctrlKey
&& event.which === hotKeys.goOutPut.which) { // Ctrl+4 焦点切换到输出窗口
$("#output").focus();
event.preventDefault();
return;
}
if (event.which === hotKeys.buildRun.which) { // F6 构建并运行
wide.run();
event.preventDefault();
return;
}
});
}
};

View File

@ -1,9 +1,9 @@
var outputWS = new WebSocket(config.channel.output + '/output/ws'); var outputWS = new WebSocket(config.channel.output + '/output/ws');
outputWS.onopen = function () { outputWS.onopen = function() {
console.log('[output onopen] connected'); console.log('[output onopen] connected');
}; };
outputWS.onmessage = function (e) { outputWS.onmessage = function(e) {
console.log('[output onmessage]' + e.data); console.log('[output onmessage]' + e.data);
var data = JSON.parse(e.data); var data = JSON.parse(e.data);
@ -43,37 +43,37 @@ outputWS.onmessage = function (e) {
url: '/run', url: '/run',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
beforeSend: function (data) { beforeSend: function(data) {
$('#output').text(''); $('#output').text('');
}, },
success: function (data) { success: function(data) {
} }
}); });
} }
} }
}; };
outputWS.onclose = function (e) { outputWS.onclose = function(e) {
console.log('[output onclose] disconnected (' + e.code + ')'); console.log('[output onclose] disconnected (' + e.code + ')');
delete outputWS; delete outputWS;
}; };
outputWS.onerror = function (e) { outputWS.onerror = function(e) {
console.log('[output onerror] ' + e); console.log('[output onerror] ' + e);
}; };
var wide = { var wide = {
curNode: undefined, curNode: undefined,
curEditor: undefined, curEditor: undefined,
_initLayout: function () { _initLayout: function() {
var mainH = $(window).height() - $(".menu").height() - $(".footer").height() - 2; var mainH = $(window).height() - $(".menu").height() - $(".footer").height() - 2;
$(".content, .ztree").height(mainH); $(".content, .ztree").height(mainH);
$(".edit-panel").height(mainH - $(".output").height()); $(".edit-panel").height(mainH - $(".output").height());
}, },
init: function () { init: function() {
this._initLayout(); this._initLayout();
$("body").bind("mousedown", function (event) { $("body").bind("mousedown", function(event) {
if (!(event.target.id === "dirRMenu" || $(event.target).closest("#dirRMenu").length > 0)) { if (!(event.target.id === "dirRMenu" || $(event.target).closest("#dirRMenu").length > 0)) {
$("#dirRMenu").hide(); $("#dirRMenu").hide();
} }
@ -89,9 +89,8 @@ var wide = {
} }
}); });
this._bindKey();
}, },
saveFile: function () { saveFile: function() {
var request = { var request = {
file: $(".edit-header .current span:eq(0)").attr("title"), file: $(".edit-header .current span:eq(0)").attr("title"),
code: wide.curEditor.getValue() code: wide.curEditor.getValue()
@ -101,23 +100,23 @@ var wide = {
url: '/file/save', url: '/file/save',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function(data) {
} }
}); });
}, },
saveAllFiles: function () { saveAllFiles: function() {
// TODO: save all files // TODO: save all files
}, },
closeFile: function () { closeFile: function() {
// TODO: close file // TODO: close file
}, },
closeAllFiles: function () { closeAllFiles: function() {
// TODO: close all files // TODO: close all files
}, },
exit: function () { exit: function() {
// TODO: exit // TODO: exit
}, },
run: function () { run: function() {
var request = { var request = {
file: $(".edit-header .current span:eq(0)").attr("title"), file: $(".edit-header .current span:eq(0)").attr("title"),
code: wide.curEditor.getValue() code: wide.curEditor.getValue()
@ -128,14 +127,14 @@ var wide = {
url: '/build', url: '/build',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
beforeSend: function (data) { beforeSend: function(data) {
$('#output').text(''); $('#output').text('');
}, },
success: function (data) { success: function(data) {
} }
}); });
}, },
goget: function () { goget: function() {
var request = { var request = {
file: $(".edit-header .current span:eq(0)").attr("title") file: $(".edit-header .current span:eq(0)").attr("title")
}; };
@ -145,14 +144,14 @@ var wide = {
url: '/go/get', url: '/go/get',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
beforeSend: function (data) { beforeSend: function(data) {
$('#output').text(''); $('#output').text('');
}, },
success: function (data) { success: function(data) {
} }
}); });
}, },
goinstall: function () { goinstall: function() {
var request = { var request = {
file: $(".edit-header .current span:eq(0)").attr("title"), file: $(".edit-header .current span:eq(0)").attr("title"),
code: wide.curEditor.getValue() code: wide.curEditor.getValue()
@ -163,14 +162,14 @@ var wide = {
url: '/go/install', url: '/go/install',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
beforeSend: function (data) { beforeSend: function(data) {
$('#output').text(''); $('#output').text('');
}, },
success: function (data) { success: function(data) {
} }
}); });
}, },
fmt: function () { fmt: function() {
var path = $(".edit-header .current span:eq(0)").attr("title"); var path = $(".edit-header .current span:eq(0)").attr("title");
var mode = wide.curNode.mode; var mode = wide.curNode.mode;
@ -188,7 +187,7 @@ var wide = {
url: '/go/fmt', url: '/go/fmt',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function(data) {
if (data.succ) { if (data.succ) {
wide.curEditor.setValue(data.code); wide.curEditor.setValue(data.code);
} }
@ -202,7 +201,7 @@ var wide = {
url: '/html/fmt', url: '/html/fmt',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function(data) {
if (data.succ) { if (data.succ) {
wide.curEditor.setValue(data.code); wide.curEditor.setValue(data.code);
} }
@ -226,92 +225,12 @@ var wide = {
// TODO: XML/JSON 格式化处理 // TODO: XML/JSON 格式化处理
break; break;
} }
},
_bindKey: function () {
$("#files").keydown(function (event) {
switch (event.which) {
case 13: // 回车
if (!wide.curNode) {
return false;
}
if (wide.curNode.iconSkin === "ico-ztree-dir ") { // 选中节点是目录
// 不做任何处理
return false;
}
// 模拟点击:打开文件
tree._onClick(wide.curNode);
break;
case 38: // 上
if (!wide.curNode) {
return false;
}
tree.fileTree.selectNode(wide.curNode.getPreNode());
wide.curNode = wide.curNode.getPreNode();
$("#files").focus();
break;
case 40: // 下
if (!wide.curNode) {
return false;
}
// TODO: 处理滚动条,递归获取下一个
tree.fileTree.selectNode(wide.curNode.getNextNode());
wide.curNode = wide.curNode.getNextNode();
$("#files").focus();
break;
}
});
$(document).keydown(function (event) {
if (event.ctrlKey && event.which === 49) { // Ctrl+1 焦点切换到文件树
// 有些元素需设置 tabindex 为 -1 时才可以 focus
$("#files").focus();
event.preventDefault();
return;
}
if (event.ctrlKey && event.which === 52) { // Ctrl+4 焦点切换到输出窗口
$("#output").focus();
event.preventDefault();
return;
}
if (event.ctrlKey && event.which === 83) { // Ctrl+S 保存当前编辑器文件
wide.saveFile();
event.preventDefault();
return;
}
if (event.altKey && event.shiftKey && event.which === 70) { // Alt+Shift+F 格式化当前编辑器文件
if (!wide.curNode) {
return false;
}
wide.fmt();
event.preventDefault();
return;
}
if (event.which === 117) { // F6 构建并运行
wide.run();
event.preventDefault();
return;
}
});
} }
}; };
$(document).ready(function () { $(document).ready(function() {
wide.init(); wide.init();
tree.init(); tree.init();
menu.init(); menu.init();
hotkeys.init();
}); });

View File

@ -199,5 +199,6 @@
<script type="text/javascript" src="{{.Wide.StaticServer}}/static/js/tree.js?{{.Wide.StaticResourceVersion}}"></script> <script type="text/javascript" src="{{.Wide.StaticServer}}/static/js/tree.js?{{.Wide.StaticResourceVersion}}"></script>
<script type="text/javascript" src="{{.Wide.StaticServer}}/static/js/wide.js?{{.Wide.StaticResourceVersion}}"></script> <script type="text/javascript" src="{{.Wide.StaticServer}}/static/js/wide.js?{{.Wide.StaticResourceVersion}}"></script>
<script type="text/javascript" src="{{.Wide.StaticServer}}/static/js/menu.js?{{.Wide.StaticResourceVersion}}"></script> <script type="text/javascript" src="{{.Wide.StaticServer}}/static/js/menu.js?{{.Wide.StaticResourceVersion}}"></script>
<script type="text/javascript" src="{{.Wide.StaticServer}}/static/js/hotkeys.js?{{.Wide.StaticResourceVersion}}"></script>
</body> </body>
</html> </html>