mirror of
https://github.com/lxsang/antos-frontend.git
synced 2024-11-08 14:08:22 +01:00
Add features:
- Improvement application list in market place - Allow triplet keyboard shortcut in GUI - CodePad allows setting shortcut in CommandPalette commands - CodePad should have recent menu entry that remember top n file opened - Improve File application grid view - Label text should be selectable
This commit is contained in:
parent
94a0c097a8
commit
de5878c349
@ -82,12 +82,7 @@ namespace OS {
|
||||
setting.applications[this.name] = {};
|
||||
}
|
||||
this.setting = setting.applications[this.name];
|
||||
this.keycomb = {
|
||||
ALT: {},
|
||||
CTRL: {},
|
||||
SHIFT: {},
|
||||
META: {},
|
||||
};
|
||||
this.keycomb = {};
|
||||
this.subscribe("appregistry", (m) => {
|
||||
if (m.name === this.name) {
|
||||
this.applySetting(m.data.m);
|
||||
@ -199,14 +194,29 @@ namespace OS {
|
||||
k: string,
|
||||
f: (e: JQuery.KeyboardEventBase) => void
|
||||
): void {
|
||||
const arr = k.split("-");
|
||||
if (arr.length !== 2) {
|
||||
const arr = k.toUpperCase().split("-");
|
||||
const c = arr.pop();
|
||||
let fnk = "";
|
||||
if (arr.includes("META")) {
|
||||
fnk += "META";
|
||||
}
|
||||
if (arr.includes("CTRL")) {
|
||||
fnk += "CTRL";
|
||||
}
|
||||
if (arr.includes("ALT")) {
|
||||
fnk += "ALT";
|
||||
}
|
||||
if (arr.includes("SHIFT")) {
|
||||
fnk += "SHIFT";
|
||||
}
|
||||
|
||||
if ( fnk == "") {
|
||||
return;
|
||||
}
|
||||
const fnk = arr[0].toUpperCase();
|
||||
const c = arr[1].toUpperCase();
|
||||
fnk = `fn_${fnk.hash()}`;
|
||||
|
||||
if (!this.keycomb[fnk]) {
|
||||
return;
|
||||
this.keycomb[fnk] = {};
|
||||
}
|
||||
this.keycomb[fnk][c] = f;
|
||||
}
|
||||
@ -246,7 +256,7 @@ namespace OS {
|
||||
* @returns {boolean} return whether the shortcut is executed
|
||||
* @memberof BaseApplication
|
||||
*/
|
||||
shortcut(fnk: string, c: string, e: JQuery.KeyDownEvent): boolean {
|
||||
shortcut(fnk: string, c: string, e: JQuery.KeyUpEvent): boolean {
|
||||
if (!this.keycomb[fnk]) {
|
||||
return true;
|
||||
}
|
||||
|
101
src/core/gui.ts
101
src/core/gui.ts
@ -34,47 +34,16 @@ namespace OS {
|
||||
*/
|
||||
export interface ShortcutType {
|
||||
/**
|
||||
* Placeholder for all shortcut callbacks attached to `ALT` key, eg.
|
||||
* Placeholder for all shortcut callbacks, example:
|
||||
* ```typescript
|
||||
* ALT.c = function() {..}
|
||||
* fn_193462204.c = function() {..}
|
||||
* // this function will be called when the hotkey `ALT-C` is triggered
|
||||
* // fn_${"ALT".hash()} is fn_193462204
|
||||
* ```
|
||||
*
|
||||
* @memberof ShortcutType
|
||||
*/
|
||||
ALT: GenericObject<(e: JQuery.MouseDownEvent) => void>;
|
||||
|
||||
/**
|
||||
* Placeholder for all shortcut callbacks attached to `CTRL` key, eg.
|
||||
* ```typescript
|
||||
* CTRL.c = function() {..}
|
||||
* // this function will be called when the hotkey `CTRL-C` is triggered
|
||||
* ```
|
||||
*
|
||||
* @memberof ShortcutType
|
||||
*/
|
||||
CTRL: GenericObject<(e: JQuery.MouseDownEvent) => void>;
|
||||
|
||||
/**
|
||||
* Placeholder for all shortcut callbacks attached to `SHIFT` key, eg.
|
||||
* ```typescript
|
||||
* SHIFT.c = function() {..}
|
||||
* // this function will be called when the hotkey `SHIFT-C` is triggered
|
||||
* ```
|
||||
*
|
||||
* @memberof ShortcutType
|
||||
*/
|
||||
SHIFT: GenericObject<(e: JQuery.MouseDownEvent) => void>;
|
||||
/**
|
||||
* Placeholder for all shortcut callbacks attached to `META` key, eg.
|
||||
* ```typescript
|
||||
* META[" "] = function() {..}
|
||||
* // this function will be called when the hotkey `META-[space]` is triggered
|
||||
* ```
|
||||
*
|
||||
* @memberof ShortcutType
|
||||
*/
|
||||
META: GenericObject<(e: JQuery.MouseDownEvent) => void>;
|
||||
[propName: string]: GenericObject<(e: JQuery.KeyUpEvent) => void>;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -129,12 +98,7 @@ namespace OS {
|
||||
/**
|
||||
* Placeholder for system shortcuts
|
||||
*/
|
||||
var shortcut: ShortcutType = {
|
||||
ALT: {},
|
||||
CTRL: {},
|
||||
SHIFT: {},
|
||||
META: {},
|
||||
};
|
||||
var shortcut: ShortcutType = {};
|
||||
|
||||
/**
|
||||
* Convert an application html scheme to
|
||||
@ -764,17 +728,32 @@ namespace OS {
|
||||
*/
|
||||
export function bindKey(
|
||||
k: string,
|
||||
f: (e: JQuery.MouseDownEvent) => void,
|
||||
f: (e: JQuery.KeyUpEvent) => void,
|
||||
force: boolean = true
|
||||
): void {
|
||||
const arr = k.split("-");
|
||||
if (arr.length !== 2) {
|
||||
const arr = k.toUpperCase().split("-");
|
||||
const c = arr.pop();
|
||||
let fnk = "";
|
||||
if (arr.includes("META")) {
|
||||
fnk += "META";
|
||||
}
|
||||
if (arr.includes("CTRL")) {
|
||||
fnk += "CTRL";
|
||||
}
|
||||
if (arr.includes("ALT")) {
|
||||
fnk += "ALT";
|
||||
}
|
||||
if (arr.includes("SHIFT")) {
|
||||
fnk += "SHIFT";
|
||||
}
|
||||
|
||||
if ( fnk == "") {
|
||||
return;
|
||||
}
|
||||
const fnk = arr[0].toUpperCase();
|
||||
const c = arr[1].toUpperCase();
|
||||
fnk = `fn_${fnk.hash()}`;
|
||||
|
||||
if (!shortcut[fnk]) {
|
||||
return;
|
||||
shortcut[fnk] = {};
|
||||
}
|
||||
if (shortcut[fnk][c] && !force) return;
|
||||
shortcut[fnk][c] = f;
|
||||
@ -907,7 +886,7 @@ namespace OS {
|
||||
$("#wrapper").append(scheme);
|
||||
|
||||
announcer.observable.one("sysdockloaded", () => {
|
||||
$(window).bind("keydown", function (event) {
|
||||
$(window).on("keyup", function (event) {
|
||||
const dock = $("#sysdock")[0] as tag.AppDockTag;
|
||||
if (!dock) {
|
||||
return;
|
||||
@ -915,20 +894,24 @@ namespace OS {
|
||||
const app = dock.selectedApp;
|
||||
//return true unless app
|
||||
const c = String.fromCharCode(event.which).toUpperCase();
|
||||
let fnk = undefined;
|
||||
if (event.ctrlKey) {
|
||||
fnk = "CTRL";
|
||||
} else if (event.metaKey) {
|
||||
fnk = "META";
|
||||
} else if (event.shiftKey) {
|
||||
fnk = "SHIFT";
|
||||
} else if (event.altKey) {
|
||||
fnk = "ALT";
|
||||
let fnk = "";
|
||||
if (event.metaKey) {
|
||||
fnk += "META";
|
||||
}
|
||||
|
||||
if (!fnk) {
|
||||
if (event.ctrlKey) {
|
||||
fnk += "CTRL";
|
||||
}
|
||||
if (event.altKey) {
|
||||
fnk += "ALT";
|
||||
}
|
||||
if (event.shiftKey) {
|
||||
fnk += "SHIFT";
|
||||
}
|
||||
|
||||
if ( fnk == "") {
|
||||
return;
|
||||
}
|
||||
fnk = `fn_${fnk.hash()}`;
|
||||
const r = app ? app.shortcut(fnk, c, event) : true;
|
||||
if (!r) {
|
||||
return event.preventDefault();
|
||||
|
@ -224,8 +224,9 @@ namespace OS {
|
||||
const bt = ($(e.target).closest(
|
||||
"afx-button"
|
||||
)[0] as any) as ButtonTag;
|
||||
const app = bt.data;
|
||||
const app = bt.data as application.BaseApplication;
|
||||
m.items = [
|
||||
{ text: "__(New window)", dataid: "new" },
|
||||
{ text: "__(Show)", dataid: "show" },
|
||||
{ text: "__(Hide)", dataid: "hide" },
|
||||
{ text: "__(Close)", dataid: "quit" },
|
||||
@ -235,6 +236,17 @@ namespace OS {
|
||||
if (app[item.dataid]) {
|
||||
return app[item.dataid]();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (item.dataid) {
|
||||
case "new":
|
||||
GUI.launch(app.name, []);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
return m.show(e);
|
||||
};
|
||||
|
@ -6,19 +6,23 @@
|
||||
"actions" : [
|
||||
{
|
||||
"text": "__(New Project)",
|
||||
"name": "create"
|
||||
"name": "create",
|
||||
"shortcut": "CTRL-ALT-N"
|
||||
},
|
||||
{
|
||||
"text": "__(New project from current folder)",
|
||||
"name": "init"
|
||||
"name": "init",
|
||||
"shortcut": "CTRL-ALT-C"
|
||||
},
|
||||
{
|
||||
"text": "__(Build and Run)",
|
||||
"name": "buildnrun"
|
||||
"name": "buildnrun",
|
||||
"shortcut": "CTRL-ALT-B"
|
||||
},
|
||||
{
|
||||
"text": "__(Build release)",
|
||||
"name": "release"
|
||||
"name": "release",
|
||||
"shortcut": "CTRL-ALT-R"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -285,6 +285,7 @@ namespace OS {
|
||||
});
|
||||
let file = "Untitled".asFileHandle() as CodePadFileHandle;
|
||||
if (this.args && this.args.length > 0) {
|
||||
this.addRecent(this.args[0].path);
|
||||
if (this.args[0].type === "dir") {
|
||||
this.currdir = this.args[0].path.asFileHandle() as CodePadFileHandle;
|
||||
} else {
|
||||
@ -311,6 +312,7 @@ namespace OS {
|
||||
if (e.data.type === "dir") {
|
||||
return;
|
||||
}
|
||||
this.addRecent(e.data.path);
|
||||
return this.eum.active.openFile(
|
||||
e.data.path.asFileHandle() as CodePadFileHandle
|
||||
);
|
||||
@ -359,7 +361,7 @@ namespace OS {
|
||||
|
||||
this.bindKey("ALT-N", () => this.menuAction("new"));
|
||||
this.bindKey("ALT-O", () => this.menuAction("open"));
|
||||
this.bindKey("ALT-F", () => this.menuAction("opendir"));
|
||||
this.bindKey("CTRL-ALT-F", () => this.menuAction("opendir"));
|
||||
this.bindKey("CTRL-S", () => this.menuAction("save"));
|
||||
this.bindKey("ALT-W", () => this.menuAction("saveas"));
|
||||
|
||||
@ -432,7 +434,7 @@ namespace OS {
|
||||
this.langstat.text = stat.langmode.text;
|
||||
this.filestat.text = stat.file
|
||||
let win = this.scheme as GUI.tag.WindowTag;
|
||||
if(win.apptitle != stat.file)
|
||||
if (win.apptitle != stat.file)
|
||||
win.apptitle = stat.file;
|
||||
}
|
||||
|
||||
@ -595,7 +597,7 @@ namespace OS {
|
||||
* @return {*} {Promise<void>}
|
||||
* @memberof CodePad
|
||||
*/
|
||||
private loadExtensionMetaFromFile(path: string| API.VFS.BaseFileHandle): Promise<void> {
|
||||
private loadExtensionMetaFromFile(path: string | API.VFS.BaseFileHandle): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
path
|
||||
.asFileHandle()
|
||||
@ -613,7 +615,13 @@ namespace OS {
|
||||
);
|
||||
this.extensions[ext.name].name = ext.name;
|
||||
for (let v of Array.from(ext.actions)) {
|
||||
const action = v as any;
|
||||
this.extensions[ext.name].addAction(v);
|
||||
if (action.shortcut) {
|
||||
this.bindKey(action.shortcut, (e) => {
|
||||
return this.loadAndRunExtensionAction(action);
|
||||
})
|
||||
}
|
||||
}
|
||||
this.spotlight.addAction(
|
||||
this.extensions[ext.name]
|
||||
@ -649,9 +657,9 @@ namespace OS {
|
||||
.then(() => {
|
||||
// try to load local extension
|
||||
this.loadExtensionMetaFromFile("home://.codepad/extensions.json")
|
||||
.catch((e)=>{
|
||||
// ignore any error
|
||||
});
|
||||
.catch((e) => {
|
||||
// ignore any error
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
return this.error(
|
||||
@ -711,7 +719,7 @@ namespace OS {
|
||||
*
|
||||
* @type {{ name: any, ext: any, rootpath?:string }}
|
||||
*/
|
||||
parent: { name: any, ext: any, rootpath?:string };
|
||||
parent: { name: any, ext: any, rootpath?: string };
|
||||
|
||||
/**
|
||||
* Action name
|
||||
@ -726,7 +734,7 @@ namespace OS {
|
||||
if (!CodePad.extensions[name]) {
|
||||
//load the extension
|
||||
let path = `${this.meta().path}/${name}.js`;
|
||||
if(data.parent.rootpath)
|
||||
if (data.parent.rootpath)
|
||||
path = `${data.parent.rootpath}/${name}.js`;
|
||||
this._api
|
||||
.requires(path, true)
|
||||
@ -750,15 +758,41 @@ namespace OS {
|
||||
* @memberof CodePad
|
||||
*/
|
||||
private fileMenu(): GUI.BasicItemType {
|
||||
const recent = this.setting.recent.map((i: string) => {
|
||||
return { text: i };
|
||||
});
|
||||
return {
|
||||
text: __("File"),
|
||||
nodes: [
|
||||
{ text: __("New"), dataid: "new", shortcut: "A-N" },
|
||||
{
|
||||
text: __("Open Recent"),
|
||||
dataid: "recent",
|
||||
nodes: recent,
|
||||
onchildselect: (
|
||||
e: GUI.TagEventType<GUI.tag.MenuEventData>,
|
||||
r: CodePad
|
||||
) => {
|
||||
const handle = e.data.item.data.text.asFileHandle();
|
||||
handle.onready().then((meta: any) => {
|
||||
if (!meta) {
|
||||
return;
|
||||
}
|
||||
if (meta.type == "dir") {
|
||||
this.currdir = handle;
|
||||
this.toggleSideBar();
|
||||
}
|
||||
else {
|
||||
this.eum.active.openFile(handle);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
{ text: __("Open"), dataid: "open", shortcut: "A-O" },
|
||||
{
|
||||
text: __("Open Folder"),
|
||||
dataid: "opendir",
|
||||
shortcut: "A-F",
|
||||
shortcut: "C-A-F",
|
||||
},
|
||||
{ text: __("Save"), dataid: "save", shortcut: "C-S" },
|
||||
{
|
||||
@ -906,8 +940,22 @@ namespace OS {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add a file to recent files setting
|
||||
*
|
||||
* @private
|
||||
* @param {string} file
|
||||
* @memberof CodePad
|
||||
*/
|
||||
private addRecent(file: string): void {
|
||||
if (!this.setting.recent)
|
||||
this.setting.recent = [];
|
||||
if (this.setting.recent.includes(file)) {
|
||||
return;
|
||||
}
|
||||
this.setting.recent.push(file);
|
||||
this.setting.recent.slice(0, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu action definition
|
||||
@ -934,9 +982,10 @@ namespace OS {
|
||||
(v) => v !== "dir"
|
||||
),
|
||||
})
|
||||
.then((f: API.FileInfoType) =>
|
||||
me.eum.active.openFile(f.file.path.asFileHandle())
|
||||
);
|
||||
.then((f: API.FileInfoType) => {
|
||||
this.addRecent(f.file.path);
|
||||
me.eum.active.openFile(f.file.path.asFileHandle());
|
||||
});
|
||||
case "opendir":
|
||||
return me
|
||||
.openDialog("FileDialog", {
|
||||
@ -944,6 +993,7 @@ namespace OS {
|
||||
mimes: ["dir"],
|
||||
})
|
||||
.then(function (f: API.FileInfoType) {
|
||||
me.addRecent(f.file.path);
|
||||
me.currdir = f.file.path.asFileHandle();
|
||||
return me.toggleSideBar();
|
||||
});
|
||||
@ -1057,7 +1107,7 @@ namespace OS {
|
||||
*/
|
||||
class CMDMenu {
|
||||
text: string | FormattedString;
|
||||
private shortcut: string;
|
||||
shortcut: string;
|
||||
nodes: GenericObject<any>[];
|
||||
parent: CMDMenu;
|
||||
rootpath: string;
|
||||
@ -1075,6 +1125,9 @@ namespace OS {
|
||||
*/
|
||||
constructor(text: string | FormattedString, shortcut?: string) {
|
||||
this.text = text;
|
||||
if (shortcut) {
|
||||
this.text += `(${shortcut})`;
|
||||
}
|
||||
this.shortcut = shortcut;
|
||||
this.nodes = [];
|
||||
this.parent = undefined;
|
||||
@ -1091,6 +1144,9 @@ namespace OS {
|
||||
*/
|
||||
addAction(v: ActionType): CMDMenu {
|
||||
v.parent = this;
|
||||
if (v.shortcut) {
|
||||
v.text = `${v.text.__()} (${v.shortcut})`;
|
||||
}
|
||||
this.nodes.push(v);
|
||||
return this;
|
||||
}
|
||||
@ -1140,7 +1196,7 @@ namespace OS {
|
||||
}
|
||||
|
||||
CMDMenu.fromMenu = function (mn): CMDMenu {
|
||||
const m = new CMDMenu(mn.text, mn.shortcut);
|
||||
const m = new CMDMenu(mn.text, undefined);
|
||||
m.onchildselect(mn.onchildselect);
|
||||
for (let it of Array.from(mn.nodes)) {
|
||||
let v = it as ActionType;
|
||||
|
@ -32,6 +32,11 @@ afx-app-window[data-id ='files-app-window'] afx-vbox[data-id = "nav-bar"]{
|
||||
afx-app-window[data-id ='files-app-window'] afx-grid-view afx-grid-row.grid_row_header div{
|
||||
border-top:1px solid #A6A6A6;
|
||||
}
|
||||
|
||||
afx-app-window[data-id ='files-app-window'] afx-grid-view afx-grid-row afx-label span {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
afx-app-window[data-id ='files-app-window'] button{
|
||||
height: 23px;
|
||||
border-radius: 0;
|
||||
|
@ -96,6 +96,9 @@ namespace OS {
|
||||
this.bindKey("CTRL-R", () => {
|
||||
return this.menuOptionsHandle("repos");
|
||||
});
|
||||
this.bindKey("CTRL-I", () => {
|
||||
return this.menuOptionsHandle("install");
|
||||
});
|
||||
|
||||
$(this.searchbox).keyup((e) => this.search(e));
|
||||
|
||||
|
@ -5,4 +5,5 @@ afx-label i.label-text{
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
margin-left: 3px;
|
||||
user-select:text;
|
||||
}
|
Loading…
Reference in New Issue
Block a user