Support pinned app in dock + remove old pinned apps UI
All checks were successful
gitea-sync/antos/pipeline/head This commit looks good

This commit is contained in:
DanyLE 2022-12-15 17:01:16 +01:00
parent 43ef0e1321
commit 7c19269d8f
10 changed files with 250 additions and 152 deletions

48
d.ts/antos.d.ts vendored
View File

@ -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<StackMenuEventData>);
/**
* 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;
}
}
}

View File

@ -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) {

View File

@ -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 = $("<afx-button>");
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 = $("<afx-button>");
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);

View File

@ -482,7 +482,24 @@ namespace OS {
set onmenuselect(v: TagEventCallback<StackMenuEventData>) {
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);
};

View File

@ -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<number>) => {
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);
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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 {

View File

@ -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;

View File

@ -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;