From 8b23ebeeff94b223f4f990562c6e53325e596de1 Mon Sep 17 00:00:00 2001 From: DanyLE Date: Tue, 24 May 2022 15:39:58 +0200 Subject: [PATCH] Loading animation is now based on the current context (global or application context) --- d.ts/antos.d.ts | 32 ++++++++++++++++ src/core/BaseApplication.ts | 55 ++++++++++++++++++++++++++++ src/core/core.ts | 6 +-- src/core/gui.ts | 3 ++ src/core/pm.ts | 18 +++++++++ src/core/tags/AppDockTag.ts | 1 + src/core/tags/SystemPanelTag.ts | 8 +++- src/core/tags/WindowTag.ts | 12 +++++- src/themes/system/afx-app-window.css | 15 ++++++++ src/themes/system/afx-sys-panel.css | 2 +- 10 files changed, 145 insertions(+), 7 deletions(-) diff --git a/d.ts/antos.d.ts b/d.ts/antos.d.ts index 5ea55e3..6367a43 100644 --- a/d.ts/antos.d.ts +++ b/d.ts/antos.d.ts @@ -2255,6 +2255,20 @@ declare namespace OS { * @memberof BaseApplication */ appmenu: GUI.tag.MenuTag; + /** + * Loading animation check timeout + * + * @memberof BaseApplication + */ + private _loading_toh; + /** + * Store pending loading task + * + * @private + * @type {number[]} + * @memberof BaseApplication + */ + private _pending_task; /** *Creates an instance of BaseApplication. * @param {string} name application name @@ -2446,6 +2460,14 @@ declare namespace OS { * @memberof BaseApplication */ protected cleanup(e: BaseEvent): void; + /** + * Check if the loading tasks ended, + * if it the case, stop the animation + * + * @private + * @memberof BaseApplication + */ + private animation_check; } } } @@ -10329,6 +10351,10 @@ declare namespace OS { /** * All running processes is stored in this variables */ + /** + * Current active process ID + */ + var pidactive: number; var processes: GenericObject; /** * Create a new process of application or service @@ -10365,5 +10391,11 @@ declare namespace OS { * @returns {void} */ function killAll(app: string, force: boolean): void; + /** + * Get the current active application + * @export + * @returns {BaseModel} + */ + function getActiveApp(): BaseModel; } } diff --git a/src/core/BaseApplication.ts b/src/core/BaseApplication.ts index 4d89195..7f2266a 100644 --- a/src/core/BaseApplication.ts +++ b/src/core/BaseApplication.ts @@ -70,6 +70,21 @@ namespace OS { */ appmenu: GUI.tag.MenuTag; + /** + * Loading animation check timeout + * + * @memberof BaseApplication + */ + private _loading_toh: any; + /** + * Store pending loading task + * + * @private + * @type {number[]} + * @memberof BaseApplication + */ + private _pending_task: number[]; + /** *Creates an instance of BaseApplication. * @param {string} name application name @@ -83,6 +98,8 @@ namespace OS { } this.setting = setting.applications[this.name]; this.keycomb = {}; + this._loading_toh = undefined; + this._pending_task = []; } /** @@ -104,6 +121,7 @@ namespace OS { this.sysdock.selectedApp = this; this.appmenu.pid = this.pid; this.appmenu.items = this.baseMenu() || []; + OS.PM.pidactive = this.pid; this.appmenu.onmenuselect = ( d: GUI.tag.MenuEventData ): void => { @@ -136,6 +154,26 @@ namespace OS { this.applySetting(m.message as string); } }); + this.subscribe("loading", (o: API.AnnouncementDataType) => { + if(o.u_data != this.pid) + { + return; + } + this._pending_task.push(o.id); + this.trigger("loading", undefined); + }); + + this.subscribe("loaded", (o: API.AnnouncementDataType) => { + const i = this._pending_task.indexOf(o.id); + if (i >= 0) { + this._pending_task.splice(i, 1); + } + if (this._pending_task.length === 0) { + // set time out + if(!this._loading_toh) + this._loading_toh = setTimeout(() => this.animation_check(),1000); + } + }); this.updateLocale(this.systemsetting.system.locale); return this.loadScheme(); } @@ -446,6 +484,23 @@ namespace OS { * @memberof BaseApplication */ protected cleanup(e: BaseEvent): void {} + + /** + * Check if the loading tasks ended, + * if it the case, stop the animation + * + * @private + * @memberof BaseApplication + */ + private animation_check(): void { + if(this._pending_task.length === 0) + { + this.trigger("loaded", undefined); + } + if(this._loading_toh) + clearTimeout(this._loading_toh); + this._loading_toh = undefined; + } } BaseApplication.type = ModelType.Application; diff --git a/src/core/core.ts b/src/core/core.ts index 923f8be..39f27c6 100644 --- a/src/core/core.ts +++ b/src/core/core.ts @@ -1275,11 +1275,11 @@ namespace OS { * @param {string} p message string */ export function loading(q: number, p: string): void { - const data:API.AnnouncementDataType = {} as API.AnnouncementDataType; + const data:API.AnnouncementDataType = {} as API.AnnouncementDataType; data.id = q; data.message = p; - data.name = "OS"; - data.u_data = true; + data.name = p; + data.u_data = PM.pidactive; announcer.trigger("loading", data); } diff --git a/src/core/gui.ts b/src/core/gui.ts index 162c057..d01c308 100644 --- a/src/core/gui.ts +++ b/src/core/gui.ts @@ -533,7 +533,9 @@ namespace OS { */ export function launch(app: string, args: AppArgumentsType[]): Promise { return new Promise(async (resolve, reject) => { + const pidactive = PM.pidactive; try { + PM.pidactive = 0; if (!application[app]) { // first load it await loadApp(app); @@ -565,6 +567,7 @@ namespace OS { __("Unable to launch: {0}", app), e ); + PM.pidactive = pidactive; return reject(__e(e)); } diff --git a/src/core/pm.ts b/src/core/pm.ts index 4580bb2..1cf96b1 100644 --- a/src/core/pm.ts +++ b/src/core/pm.ts @@ -24,6 +24,10 @@ namespace OS { /** * All running processes is stored in this variables */ + /** + * Current active process ID + */ + export var pidactive: number = 0; export var processes: GenericObject = {}; /** * Create a new process of application or service @@ -159,5 +163,19 @@ namespace OS { p.quit(force); } } + + /** + * Get the current active application + * @export + * @returns {BaseModel} + */ + export function getActiveApp():BaseModel + { + if(PM.pidactive === 0) + { + return undefined; + } + return PM.appByPid(PM.pidactive); + } } } diff --git a/src/core/tags/AppDockTag.ts b/src/core/tags/AppDockTag.ts index 6c174a3..8131a10 100644 --- a/src/core/tags/AppDockTag.ts +++ b/src/core/tags/AppDockTag.ts @@ -162,6 +162,7 @@ namespace OS { } this._selectedItem = el; if (!el) { + PM.pidactive = 0; return; } $(el.domel).addClass("selected"); diff --git a/src/core/tags/SystemPanelTag.ts b/src/core/tags/SystemPanelTag.ts index 1b2e274..a3caff3 100644 --- a/src/core/tags/SystemPanelTag.ts +++ b/src/core/tags/SystemPanelTag.ts @@ -539,14 +539,18 @@ namespace OS { announcer.observable.on("app-pinned", (_) => { this.RefreshPinnedApp(); }); - announcer.observable.on("loading", (o: API.AnnouncementDataType) => { + announcer.observable.on("loading", (o: API.AnnouncementDataType) => { + if(o.u_data != 0) + { + return; + } this._pending_task.push(o.id); if(!$(this.refs.panel).hasClass("loading")) $(this.refs.panel).addClass("loading"); $(GUI.workspace).css("cursor", "wait"); }); - announcer.observable.on("loaded", (o: API.AnnouncementDataType) => { + announcer.observable.on("loaded", (o: API.AnnouncementDataType) => { const i = this._pending_task.indexOf(o.id); if (i >= 0) { this._pending_task.splice(i, 1); diff --git a/src/core/tags/WindowTag.ts b/src/core/tags/WindowTag.ts index f5a939e..411f0f8 100644 --- a/src/core/tags/WindowTag.ts +++ b/src/core/tags/WindowTag.ts @@ -71,7 +71,7 @@ namespace OS { * @memberof WindowTag */ private _desktop_pos: GenericObject; - + /** * Creates an instance of WindowTag. * @memberof WindowTag @@ -331,6 +331,15 @@ namespace OS { }); } }); + this.observable.on("loaded", ()=>{ + $(this.refs.panel).removeClass("loading"); + $(this).css("cursor", "auto"); + }); + this.observable.on("loading", ()=>{ + if(!$(this.refs.panel).hasClass("loading")) + $(this.refs.panel).addClass("loading"); + $(this).css("cursor", "wait"); + }); this.enable_dragging(); this.enable_resize(); this.setsize({ @@ -524,6 +533,7 @@ namespace OS { children: [ { el: "ul", + ref: 'panel', class: "afx-window-top", children: [ { diff --git a/src/themes/system/afx-app-window.css b/src/themes/system/afx-app-window.css index 7e51703..16b24b8 100644 --- a/src/themes/system/afx-app-window.css +++ b/src/themes/system/afx-app-window.css @@ -15,6 +15,21 @@ afx-app-window ul.afx-window-top{ width: 100%; padding:0; } + +afx-app-window ul.loading::before{ + background-color: orangered; + content: ""; + position: absolute; + height: 2px; + width: 0%; +} + +afx-app-window ul.loading::before { + right: 0; + top:0; + animation: sys-loading 1s linear infinite; +} + afx-app-window ul.afx-window-top li{ list-style: none; } diff --git a/src/themes/system/afx-sys-panel.css b/src/themes/system/afx-sys-panel.css index 6d46d35..2178dbd 100644 --- a/src/themes/system/afx-sys-panel.css +++ b/src/themes/system/afx-sys-panel.css @@ -52,7 +52,7 @@ afx-sys-panel > div.loading::before { 100% { right: auto; left: 100%; - width: 12.5%; + width: 0%; } }