From 3c25d8b52ec384dc5b1f666fbb756a81d093c89f Mon Sep 17 00:00:00 2001 From: DanyLE Date: Thu, 15 Dec 2022 17:01:16 +0100 Subject: [PATCH] Support pinned app in dock + remove old pinned apps UI --- d.ts/antos.d.ts | 48 ++++-- src/core/gui.ts | 5 +- src/core/tags/AppDockTag.ts | 205 ++++++++++++++++------- src/core/tags/StackMenuTag.ts | 30 +++- src/core/tags/SystemPanelTag.ts | 54 +----- src/themes/antos_dark/afx-dock.css | 9 +- src/themes/antos_dark/afx-sys-panel.css | 15 +- src/themes/antos_light/afx-dock.css | 9 +- src/themes/antos_light/afx-sys-panel.css | 16 +- src/themes/system/afx-sys-panel.css | 11 +- 10 files changed, 250 insertions(+), 152 deletions(-) diff --git a/d.ts/antos.d.ts b/d.ts/antos.d.ts index 78369f8..5c66358 100644 --- a/d.ts/antos.d.ts +++ b/d.ts/antos.d.ts @@ -4761,9 +4761,9 @@ declare namespace OS { set text(v: string | FormattedString); get text(): string | FormattedString; /** - * Setter: Set the text of the button + * Setter: Set the text of the label * - * Getter: Get the current button test + * Getter: Get the current label test * * @memberof InputTag */ @@ -4845,7 +4845,7 @@ declare namespace OS { */ protected init(): void; /** - * Re-calibrate the button, do nothing in this tag + * Re-calibrate, do nothing in this tag * * @protected * @memberof InputTag @@ -4859,7 +4859,7 @@ declare namespace OS { */ reload(d?: any): void; /** - * Button layout definition + * Input layout definition * * @protected * @returns {TagLayoutType[]} @@ -6401,13 +6401,6 @@ declare namespace OS { * @memberof SystemPanelTag */ calibrate(): void; - /** - * Refresh the pinned applications menu - * - * @private - * @memberof SystemPanelTag - */ - private RefreshPinnedApp; /** * Check if the loading tasks ended, * if it the case, stop the animation @@ -8025,6 +8018,13 @@ declare namespace OS { * @memberof StackMenuTag */ set onmenuselect(v: TagEventCallback); + /** + * Hide the current menu. This function is called + * only if the current menu is context menu + * + * @memberof StackMenuTag + */ + hide(): void; /** * Show the current menu. This function is called * only if the current menu is a context menu @@ -8560,7 +8560,7 @@ declare namespace OS { * @type {application.BaseApplication} * @memberof AppDockItemType */ - app: application.BaseApplication; + app?: application.BaseApplication; /** * Reference to the DOM element of * the owner dock item @@ -8667,6 +8667,17 @@ declare namespace OS { * @memberof AppDockTag */ get selectedItem(): AppDockItemType; + /** + * Add a button to the dock + * + * @private + * @param {string} [name] associated application name + * @param {AppDockItemType} [item] dock item + * @param {boolean} [pinned] the button is pinned to the dock ? + * @memberof AppDockTag + */ + private add_button; + private update_button; /** * When a new application process is created, this function * will be called to add new application entry to the dock. @@ -8677,6 +8688,12 @@ declare namespace OS { * @memberof AppDockTag */ addapp(item: AppDockItemType): void; + /** + * Handle the application selection action + * + * @private + * @memberof AppDockTag + */ private handleAppSelect; /** * Delete and application entry from the dock. @@ -8694,6 +8711,13 @@ declare namespace OS { * @memberof AppDockTag */ protected mount(): void; + /** + * refresh the pinned application list + * + * @private + * @memberof AppDockTag + */ + private refresh_pinned_app; } } } diff --git a/src/core/gui.ts b/src/core/gui.ts index cfc24e3..44d19be 100644 --- a/src/core/gui.ts +++ b/src/core/gui.ts @@ -644,10 +644,7 @@ namespace OS { const data = { icon: null, iconclass: meta.iconclass || "", - app, - onbtclick() { - return app.toggle(); - }, + app }; // TODO: this path is not good, need to create a blob of it if (meta.icon) { diff --git a/src/core/tags/AppDockTag.ts b/src/core/tags/AppDockTag.ts index 662e87e..af0ade2 100644 --- a/src/core/tags/AppDockTag.ts +++ b/src/core/tags/AppDockTag.ts @@ -15,7 +15,7 @@ namespace OS { * @type {application.BaseApplication} * @memberof AppDockItemType */ - app: application.BaseApplication; + app?: application.BaseApplication; /** * Reference to the DOM element of @@ -94,9 +94,6 @@ namespace OS { break; } } - if (i !== -1) { - $(this.items[i].domel).attr("tooltip", `ct:${app.title()}`); - } } /** @@ -186,6 +183,62 @@ namespace OS { return this._selectedItem; } + /** + * Add a button to the dock + * + * @private + * @param {string} [name] associated application name + * @param {AppDockItemType} [item] dock item + * @param {boolean} [pinned] the button is pinned to the dock ? + * @memberof AppDockTag + */ + private add_button(name:string, item: AppDockItemType, pinned: boolean = false): void + { + const collection = $(this).children().filter((i, e) => { + return (e as ButtonTag).data.name == name; + }); + if(collection.length > 0) + { + (collection[0] as ButtonTag).data.pinned = true; + item.domel = collection[0] as ButtonTag; + return; + } + const el = $(""); + const bt = el[0] as ButtonTag; + el.appendTo(this); + el[0].uify(this.observable); + bt.set(item); + bt.data = { + name: name, + pinned: pinned + }; + item.domel = bt; + bt.onbtclick = (e) => { + e.data.stopPropagation(); + this.handleAppSelect(bt); + }; + } + + private update_button(el: ButtonTag): void + { + const collection = this.items.filter(it => it.app.name == el.data.name); + if(collection.length == 1) + { + $(el).removeClass("plural"); + } + if(collection.length == 0) + { + if(el.data.pinned) + { + $(el).removeClass(); + } + else + { + $(el).remove(); + } + } + } + /** * When a new application process is created, this function * will be called to add new application entry to the dock. @@ -200,17 +253,7 @@ namespace OS { let bt = undefined; if(collection.length == 0) { - const el = $(""); - bt = el[0] as ButtonTag; - el.appendTo(this); - el[0].uify(this.observable); - bt.set(item); - bt.data = item.app.name; - item.domel = bt; - bt.onbtclick = (e) => { - e.data.stopPropagation(); - this.handleAppSelect(bt); - }; + this.add_button(item.app.name, item); } else { @@ -222,40 +265,48 @@ namespace OS { this.selectedApp = item.app; } - private handleAppSelect(bt: ButtonTag) - { - const name = bt.data as any as string; - const collection = this.items.filter(it => it.app.name == name); - if(collection.length == 0) + /** + * Handle the application selection action + * + * @private + * @memberof AppDockTag + */ + private handleAppSelect(bt: ButtonTag) { - return; + const name = bt.data.name as string; + const collection = this.items.filter(it => it.app.name == name); + const ctxmenu = $("#contextmenu")[0] as tag.StackMenuTag; + ctxmenu.hide(); + if(collection.length == 0) + { + GUI.launch(name, []); + return; + } + if(collection.length == 1) + { + collection[0].app.trigger("focus"); + return; + } + // show the context menu containning a list of application to select + const menu_data = collection.map(e => { + return { + text: (e.app.scheme as WindowTag).apptitle, + icon: e.icon, + iconclass: e.iconclass, + app: e.app + }; + }); + const offset = $(bt).offset(); + ctxmenu.nodes = menu_data; + $(ctxmenu) + .css("left", offset.left) + .css("bottom", $(this).height()); + ctxmenu.onmenuselect = (e) => + { + e.data.item.data.app.show(); + } + ctxmenu.show(); } - if(collection.length == 1) - { - collection[0].app.trigger("focus"); - return; - } - // show the context menu containning a list of application to select - const menu_data = collection.map(e => { - return { - text: (e.app.scheme as WindowTag).apptitle, - icon: e.icon, - iconclass: e.iconclass, - app: e.app - }; - }); - const ctxmenu = $("#contextmenu")[0] as tag.StackMenuTag; - const offset = $(bt).offset(); - ctxmenu.nodes = menu_data; - $(ctxmenu) - .css("left", offset.left) - .css("bottom", $(this).height()); - ctxmenu.onmenuselect = (e) => - { - e.data.item.data.app.show(); - } - ctxmenu.show(); - } /** * Delete and application entry from the dock. @@ -278,18 +329,10 @@ namespace OS { if (i !== -1) { const appName = this.items[i].app.name; - const el = this.items[i].domel; + const el = this.items[i].domel as ButtonTag; delete this.items[i].app; this.items.splice(i, 1); - const collection = this.items.filter(it => it.app.name == appName); - if(collection.length == 1) - { - $(el).removeClass("plural"); - } - if(collection.length == 0) - { - $(el).remove(); - } + this.update_button(el); } } @@ -307,7 +350,7 @@ namespace OS { const bt = ($(e.target).closest( "afx-button" )[0] as any) as ButtonTag; - const name = bt.data as any; + const name = bt.data.name as string; const collection = this.items.filter(it => it.app.name == name); m.nodes = [ { text: "__(New window)", dataid: "new" }, @@ -317,7 +360,7 @@ namespace OS { m.onmenuselect = function (evt) { switch (evt.data.item.data.dataid) { case "new": - GUI.launch(bt.data as string, []); + GUI.launch(bt.data.name as string, []); break; case "hide": collection.forEach((el,_) => el.app.hide()); @@ -329,7 +372,11 @@ namespace OS { break; } }; - return m.show(e); + const offset = $(bt).offset(); + $(m) + .css("left", offset.left) + .css("bottom", $(this).height()); + return m.show(); }; announcer.trigger("sysdockloaded", undefined); GUI.bindKey("CTRL-ALT-2", (e) =>{ @@ -383,6 +430,44 @@ namespace OS { $(this).on("wheel", (evt)=>{ (this as any).scrollLeft += (evt.originalEvent as WheelEvent).deltaY; }); + announcer.on("app-pinned", (_) => { + this.refresh_pinned_app(); + }); + this.refresh_pinned_app(); + } + /** + * refresh the pinned application list + * + * @private + * @memberof AppDockTag + */ + private refresh_pinned_app(): void + { + if(!setting.system.startup.pinned) + return; + // unpin all application on the dock + $(this).children().each((i,e) => { + (e as ButtonTag).data.pinned = false; + }); + // pin all setting application on the dock + setting.system.startup.pinned + .filter((el) =>{ + const app = setting.system.packages[el]; + return app && app.app + }) + .forEach((name) => { + const app = setting.system.packages[name]; + const item = { + icon: app.icon, + iconclass: app.iconclass, + app: undefined + }; + this.add_button(name, item, true); + }); + // update to remove the button + $(this).children().each((i,e) => { + this.update_button(e as ButtonTag); + }); } } define("afx-apps-dock", AppDockTag); diff --git a/src/core/tags/StackMenuTag.ts b/src/core/tags/StackMenuTag.ts index 0ffd803..b96dc1c 100644 --- a/src/core/tags/StackMenuTag.ts +++ b/src/core/tags/StackMenuTag.ts @@ -482,7 +482,24 @@ namespace OS { set onmenuselect(v: TagEventCallback) { this._onmenuselect = v; } - + /** + * Hide the current menu. This function is called + * only if the current menu is context menu + * + * @memberof StackMenuTag + */ + hide(): void + { + if (!this.context) { + return; + } + $(this) + .css("bottom", "unset") + .css("top", "unset") + .css("left", "unset") + .css("right", "unset") + .hide(); + } /** * Show the current menu. This function is called * only if the current menu is a context menu @@ -505,7 +522,9 @@ namespace OS { $(this) .css("top", top + "px") - .css("left", left + "px"); + .css("left", left + "px") + .css("bottom", "unset") + .css("right", "unset"); } const dropoff = (e) => { @@ -517,12 +536,7 @@ namespace OS { { return; } - $(this) - .css("bottom", "unset") - .css("top", "unset") - .css("left", "unset") - .css("right", "unset") - .hide(); + this.hide(); $(document).off("click", dropoff); }; diff --git a/src/core/tags/SystemPanelTag.ts b/src/core/tags/SystemPanelTag.ts index f6f4748..6c3315f 100644 --- a/src/core/tags/SystemPanelTag.ts +++ b/src/core/tags/SystemPanelTag.ts @@ -206,15 +206,10 @@ namespace OS { ref: "panel", children: [ { - el: "afx-menu", + el: "afx-button", ref: "osmenu", class: "afx-panel-os-menu", }, - { - el: "afx-menu", - ref: "pinned", - class: "afx-panel-os-pinned-app", - }, { el: "afx-apps-dock", ref: "sysdock", @@ -382,34 +377,6 @@ namespace OS { }px`; } - - /** - * Refresh the pinned applications menu - * - * @private - * @memberof SystemPanelTag - */ - private RefreshPinnedApp(): void - { - if(!setting.system.startup.pinned) - return; - (this.refs.pinned as GUI.tag.MenuTag).items = - setting.system.startup.pinned - .filter((el) =>{ - const app = setting.system.packages[el]; - return app && app.app - }) - .map((name) => { - const app = setting.system.packages[name]; - return { - icon: app.icon, - iconclass: app.iconclass, - app: app.app, - tooltip: `cb:${app.name}` - }; - }); - } - /** * Check if the loading tasks ended, * if it the case, stop the animation @@ -434,7 +401,7 @@ namespace OS { * @memberof SystemPanelTag */ protected mount(): void { - (this.refs.osmenu as MenuTag).items = [this._osmenu]; + (this.refs.osmenu as ButtonTag).set(this._osmenu); this._cb = (e) => { if ( !$(e.target).closest($(this.refs.overlay)).length && @@ -468,7 +435,7 @@ namespace OS { return Ant.OS.exit(); }, }); - (this.refs.osmenu as MenuTag).onmenuselect = (e) => { + (this.refs.osmenu as ButtonTag).onbtclick = (e) => { if($(this.refs.overlay).is(":hidden")) { this.toggle(true); @@ -511,19 +478,9 @@ namespace OS { }; $(this.refs.overlay) .hide(); - (this.refs.pinned as GUI.tag.MenuTag).onmenuselect = (e) => { - const app = e.data.item.data.app; - if(!app) - return; - GUI.launch(app, []); - }; - this.refs.osmenu.contextmenuHandle = (e, m) => { } - this.refs.systray.contextmenuHandle = (e, m) => { } - this.refs.pinned.contextmenuHandle = (e, m) => { } + this.refs.osmenu.contextmenuHandle = (e, m) => { }; + this.refs.systray.contextmenuHandle = (e, m) => { }; this.refs.panel.contextmenuHandle = (e, m) => { }; - announcer.on("app-pinned", (_) => { - this.RefreshPinnedApp(); - }); announcer.on("loading", (o: API.AnnouncementDataType) => { if(o.u_data != 0) { @@ -549,7 +506,6 @@ namespace OS { announcer.on("desktopresize", (e) => { this.calibrate(); }); - this.RefreshPinnedApp(); Ant.OS.announcer.trigger("syspanelloaded", undefined); } } diff --git a/src/themes/antos_dark/afx-dock.css b/src/themes/antos_dark/afx-dock.css index d47e7e0..e02f36a 100644 --- a/src/themes/antos_dark/afx-dock.css +++ b/src/themes/antos_dark/afx-dock.css @@ -9,11 +9,18 @@ afx-apps-dock{ box-shadow: none; } +afx-apps-dock afx-button > button:hover { + background-color: #3f3e3e; +} +afx-apps-dock afx-button.plural > button:hover +{ + border-top: 3px double #646363; +} afx-apps-dock afx-button.selected > button { background-color: #464646; color: white; border: 0; - border-bottom: 3px solid #bb86fc; + border-bottom: 2px solid #bb86fc; } afx-apps-dock afx-button.plural.selected > button { border-top: 3px double #646363; diff --git a/src/themes/antos_dark/afx-sys-panel.css b/src/themes/antos_dark/afx-sys-panel.css index a0351eb..1f0b2fd 100644 --- a/src/themes/antos_dark/afx-sys-panel.css +++ b/src/themes/antos_dark/afx-sys-panel.css @@ -4,14 +4,19 @@ afx-sys-panel > div{ box-shadow: none; } -afx-sys-panel .afx-panel-os-menu li +afx-sys-panel .afx-panel-os-menu button +{ + background-color: #e7414d; + border-radius: 0; + border: 0; +} + +afx-sys-panel .afx-panel-os-menu button .label-text { font-weight: bold; - background-color: #e7414d; - border-top-right-radius: 9px; - border-bottom-right-radius: 9px; } -afx-sys-panel .afx-panel-os-menu a { + +afx-sys-panel .afx-panel-os-menu { color: white; } diff --git a/src/themes/antos_light/afx-dock.css b/src/themes/antos_light/afx-dock.css index a228a8c..d66cf27 100644 --- a/src/themes/antos_light/afx-dock.css +++ b/src/themes/antos_light/afx-dock.css @@ -8,11 +8,18 @@ afx-apps-dock{ border-right:1px solid #a6a6a6; box-shadow: none; } +afx-apps-dock afx-button > button:hover { + background-color: #cecece; +} +afx-apps-dock afx-button.plural > button:hover +{ + border-top: 3px double #a6a6a6; +} afx-apps-dock afx-button.selected > button { background-color: #2786F3; color: white; border: 0; - border-bottom: 3px solid salmon; + border-bottom: 2px solid salmon; } afx-apps-dock afx-button.plural.selected > button { diff --git a/src/themes/antos_light/afx-sys-panel.css b/src/themes/antos_light/afx-sys-panel.css index d97ad1f..7a946bb 100644 --- a/src/themes/antos_light/afx-sys-panel.css +++ b/src/themes/antos_light/afx-sys-panel.css @@ -3,15 +3,19 @@ afx-sys-panel > div{ border-top: 1px solid #9c9C9C; box-shadow:none; } +afx-sys-panel .afx-panel-os-menu button +{ + background-color: #e7414d; + border-radius: 0; + border: 0; +} -afx-sys-panel .afx-panel-os-menu li +afx-sys-panel .afx-panel-os-menu button .label-text { font-weight: bold; - background-color: #e7414d; - border-top-right-radius: 9px; - border-bottom-right-radius: 9px; } -afx-sys-panel .afx-panel-os-menu a { + +afx-sys-panel .afx-panel-os-menu { color: white; } @@ -96,7 +100,7 @@ afx-sys-panel div[data-id="searchicon"]:before{ } afx-sys-panel input{ border:0; - height: 25px; + height: 30px; color:#afafaf; font-size: 16px; background-color: transparent; diff --git a/src/themes/system/afx-sys-panel.css b/src/themes/system/afx-sys-panel.css index 563e83f..75518a6 100644 --- a/src/themes/system/afx-sys-panel.css +++ b/src/themes/system/afx-sys-panel.css @@ -15,6 +15,11 @@ afx-sys-panel > div{ height: 35px; } +afx-sys-panel afx-apps-dock +{ + flex:1; +} + afx-sys-panel afx-overlay { bottom: 35px; @@ -68,17 +73,11 @@ afx-sys-panel > div.loading::before { afx-sys-panel .afx-panel-os-menu { padding:0; margin: 0; - margin-right: 5px; } afx-sys-panel .afx-panel-os-stray{ position: relative; } - -afx-sys-panel .afx-panel-os-pinned-app afx-menu-entry{ - display: inline-block; -} - afx-sys-panel afx-menu.afx-panel-os-stray afx-menu { right: 0; position: absolute;