Add input tag and update all base dialogs to support mobile devices

This commit is contained in:
DanyLE 2022-12-09 18:20:31 +01:00 committed by Dany LE
parent 1a6ece4e7c
commit 2e887851c5
18 changed files with 725 additions and 315 deletions

View File

@ -42,7 +42,8 @@ tags = dist/core/tags/tag.js \
dist/core/tags/SystemPanelTag.js \ dist/core/tags/SystemPanelTag.js \
dist/core/tags/DesktopTag.js \ dist/core/tags/DesktopTag.js \
dist/core/tags/StackMenuTag.js \ dist/core/tags/StackMenuTag.js \
dist/core/tags/StackPanelTag.js dist/core/tags/StackPanelTag.js \
dist/core/tags/InputTag.js
javascripts= dist/core/core.js \ javascripts= dist/core/core.js \
dist/core/settings.js \ dist/core/settings.js \

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

@ -4723,6 +4723,153 @@ declare namespace OS {
} }
} }
} }
/// <reference types="jquery" />
declare namespace OS {
namespace GUI {
namespace tag {
/**
* This tag define a basic text input and its behavior
*
* @export
* @class InputTag
* @extends {AFXTag}
*/
class InputTag extends AFXTag {
/**
*Creates an instance of InputTag.
* @memberof InputTag
*/
constructor();
/**
* Set the path to the header icon, the path should be
* a VFS file path
*
* @memberof InputTag
*/
set icon(v: string);
/**
* Set the icon class to the header
*
* @memberof InputTag
*/
set iconclass(v: string);
/**
* Alias to header setter/getter
*
* @memberof InputTag
*/
set text(v: string | FormattedString);
get text(): string | FormattedString;
/**
* Setter: Set the text of the button
*
* Getter: Get the current button test
*
* @memberof InputTag
*/
set label(v: string | FormattedString);
get label(): string | FormattedString;
/**
* Setter: Enable or disable the input
*
* Getter: Get the `enable` property of the input
*
* @memberof InputTag
*/
set disable(v: boolean);
get disable(): boolean;
/**
* Setter: set verbosity of the input
*
* Getter: Get the current input verbosity
*
* @memberof InputTag
*/
set verbose(v: boolean);
get verbose(): boolean;
/**
* JQuery style generic event handling on the input element
*
* @param {string} enname: JQuery event name
* @param {JQuery.TypeEventHandler<HTMLInputElement | HTMLTextAreaElement, unknown, any, any, string>} handle: JQuery handle
* @memberof InputTag
*/
on(ename: string, handle: JQuery.TypeEventHandler<HTMLInputElement | HTMLTextAreaElement, unknown, any, any, string>): void;
/**
* Manually trigger an event
*
* @param {string} evt: JQuery event name
* @memberof InputTag
*/
trigger(evt: string): void;
/**
* Mount the tag
*
* @protected
* @memberof InputTag
*/
protected mount(): void;
/**
* Get the current active input element
*
* @memberof InputTag
*/
get input(): HTMLInputElement | HTMLTextAreaElement;
/**
* Get/set the current active input value
*
* @memberof InputTag
*/
get value(): string;
set value(v: string);
/**
* Get/set input type
* This only affects the inline input element
*
* @memberof InputTag
*/
get type(): string;
set type(v: string);
/**
* Get/set input name
*
* @memberof InputTag
*/
get name(): string;
set name(v: string);
/**
* Init the tag before mounting
*
* @protected
* @memberof InputTag
*/
protected init(): void;
/**
* Re-calibrate the button, do nothing in this tag
*
* @protected
* @memberof InputTag
*/
protected calibrate(): void;
/**
* Update the current tag, do nothing in this tag
*
* @param {*} [d]
* @memberof InputTag
*/
reload(d?: any): void;
/**
* Button layout definition
*
* @protected
* @returns {TagLayoutType[]}
* @memberof InputTag
*/
protected layout(): TagLayoutType[];
}
}
}
}
declare namespace OS { declare namespace OS {
namespace GUI { namespace GUI {
namespace tag { namespace tag {
@ -5248,6 +5395,18 @@ declare namespace OS {
* @memberof LabelTag * @memberof LabelTag
*/ */
set icon(v: string); set icon(v: string);
/**
* set horizontal aligment of the label content
*
* @param {string} v shall be "left, right, or center"
*/
set halign(v: string);
/**
* set horizontal aligment of the label content
*
* @param {string} v shall be "top, bottom, or center"
*/
set valign(v: string);
/** /**
* Set the CSS class of the label icon * Set the CSS class of the label icon
* *
@ -6425,6 +6584,7 @@ declare namespace OS {
* @memberof TileLayoutTag * @memberof TileLayoutTag
*/ */
constructor(); constructor();
private _padding;
/** /**
* Do nothing * Do nothing
* *
@ -6464,6 +6624,19 @@ declare namespace OS {
*/ */
set dir(v: "row" | "column"); set dir(v: "row" | "column");
get dir(): "row" | "column"; get dir(): "row" | "column";
/**
* Setter:
*
* SET content padding
*
* Getter:
*
* Get content padding
*
* @memberof TileLayoutTag
*/
set padding(v: number);
get padding(): number;
/** /**
* Mount the element * Mount the element
* *

View File

@ -372,23 +372,15 @@ namespace OS {
*/ */
main(): void { main(): void {
super.main(); super.main();
const $input = $(this.find("txtInput")); const input = this.find("txtInput") as GUI.tag.InputTag;
if (this.data && this.data.label) { if(this.data)
(this.find( {
"lbl" input.set(this.data);
) as tag.LabelTag).text = this.data.label;
}
if (this.data && this.data.value) {
$input.val(this.data.value);
}
if (this.data && this.data.type) {
($input[0] as HTMLInputElement).type = this.data.type
} }
(this.find("btnOk") as tag.ButtonTag).onbtclick = (_e) => { (this.find("btnOk") as tag.ButtonTag).onbtclick = (_e) => {
if (this.handle) { if (this.handle) {
this.handle($input.val()); this.handle(input.value);
} }
return this.quit(); return this.quit();
}; };
@ -399,40 +391,30 @@ namespace OS {
return this.quit(); return this.quit();
}; };
$input.on("keyup", (e) => { input.on("keyup", (e) => {
if (e.which !== 13) { if (e.which !== 13) {
return; return;
} }
if (this.handle) { if (this.handle) {
this.handle($input.val()); this.handle(input.value);
} }
return this.quit(); return this.quit();
}); });
$input.trigger("focus"); input.trigger("focus");
} }
} }
/** /**
* Scheme definition of the Prompt dialog * Scheme definition of the Prompt dialog
*/ */
PromptDialog.scheme = `\ PromptDialog.scheme = `\
<afx-app-window width='200' height='150' apptitle = "Prompt"> <afx-app-window width='250' height='200' apptitle = "Prompt">
<afx-vbox> <afx-vbox padding = "10">
<afx-hbox> <afx-input data-id= "txtInput"></afx-input>
<div data-width = "10" ></div> <div data-height="35" style="text-align: right;">
<afx-vbox> <afx-button data-id = "btnOk" text = "__(Ok)"></afx-button>
<div data-height="10" ></div> <afx-button data-id = "btnCancel" text = "__(Cancel)"></afx-button>
<afx-label data-id = "lbl" ></afx-label> </div>
<input type = "text" data-id= "txtInput" ></input>
<div data-height="10" ></div>
<afx-hbox data-height="30">
<div ></div>
<afx-button data-id = "btnOk" text = "__(Ok)" data-width = "40" ></afx-button>
<afx-button data-id = "btnCancel" text = "__(Cancel)" data-width = "50" ></afx-button>
</afx-hbox>
</afx-vbox>
<div data-width = "10" ></div>
</afx-hbox>
</afx-vbox> </afx-vbox>
</afx-app-window>\ </afx-app-window>\
`; `;
@ -464,15 +446,11 @@ namespace OS {
*/ */
main(): void { main(): void {
super.main(); super.main();
const $input = $(this.find("txtInput")); const input = this.find("txtInput") as tag.InputTag;
if (this.data && this.data.value) { if(this.data)
$input.val(this.data.value); input.set(this.data);
}
if (this.data && this.data.disable) {
$input.prop('disabled', true);
}
(this.find("btn-Ok") as tag.ButtonTag).onbtclick = (_e) => { (this.find("btn-Ok") as tag.ButtonTag).onbtclick = (_e) => {
const value = $input.val(); const value = input.value;
if (!value || value === "") { if (!value || value === "") {
return; return;
} }
@ -488,7 +466,7 @@ namespace OS {
return this.quit(); return this.quit();
}; };
$input.focus(); input.trigger("focus");
} }
} }
/** /**
@ -496,21 +474,12 @@ namespace OS {
*/ */
TextDialog.scheme = `\ TextDialog.scheme = `\
<afx-app-window data-id = "TextDialog" width='400' height='300'> <afx-app-window data-id = "TextDialog" width='400' height='300'>
<afx-vbox> <afx-vbox padding="10">
<afx-hbox> <afx-input data-id= "txtInput" verbose="true"></afx-input>
<div data-width = "10" ></div> <div data-height="40" style="text-align:right;padding-top:5px;">
<afx-vbox> <afx-button data-id = "btn-Ok" text = "__(Ok)" ></afx-button>
<div data-height="10" ></div> <afx-button data-id = "btnCancel" text = "__(Cancel)" ></afx-button>
<textarea data-id= "txtInput" ></textarea> </div>
<div data-height="10" ></div>
<afx-hbox data-height="30">
<div ></div>
<afx-button data-id = "btn-Ok" text = "__(Ok)" data-width = "40" ></afx-button>
<afx-button data-id = "btnCancel" text = "__(Cancel)" data-width = "50" ></afx-button>
</afx-hbox>
</afx-vbox>
<div data-width = "10" ></div>
</afx-hbox>
</afx-vbox> </afx-vbox>
</afx-app-window>\ </afx-app-window>\
`; `;
@ -575,23 +544,13 @@ namespace OS {
* Scheme definition * Scheme definition
*/ */
CalendarDialog.scheme = `\ CalendarDialog.scheme = `\
<afx-app-window width='300' height='250' apptitle = "Calendar" > <afx-app-window width='350' height='380' apptitle = "Calendar" >
<afx-vbox> <afx-vbox padding="10">
<afx-hbox>
<div data-width = "10" ></div>
<afx-vbox>
<div data-height="10" ></div>
<afx-calendar-view data-id = "cal" ></afx-calendar-view> <afx-calendar-view data-id = "cal" ></afx-calendar-view>
<div data-height="10" ></div> <div data-height="35" style = 'text-align: right;'>
<afx-hbox data-height="30">
<div ></div>
<afx-button data-id = "btnOk" text = "__(Ok)" data-width = "40" ></afx-button> <afx-button data-id = "btnOk" text = "__(Ok)" data-width = "40" ></afx-button>
<afx-button data-id = "btnCancel" text = "__(Cancel)" data-width = "50" ></afx-button> <afx-button data-id = "btnCancel" text = "__(Cancel)" data-width = "50" ></afx-button>
</afx-hbox> </div>
<div data-height="10" ></div>
</afx-vbox>
<div data-width = "10" ></div>
</afx-hbox>
</afx-vbox> </afx-vbox>
</afx-app-window>\ </afx-app-window>\
`; `;
@ -654,23 +613,13 @@ namespace OS {
* Scheme definition * Scheme definition
*/ */
ColorPickerDialog.scheme = `\ ColorPickerDialog.scheme = `\
<afx-app-window width='320' height='250' apptitle = "Color picker" > <afx-app-window width='320' height='300' apptitle = "Color picker" >
<afx-vbox> <afx-vbox padding = "10">
<afx-hbox>
<div data-width = "10" ></div>
<afx-vbox>
<div data-height="10" ></div>
<afx-color-picker data-id = "cpicker" ></afx-color-picker> <afx-color-picker data-id = "cpicker" ></afx-color-picker>
<div data-height="10" ></div> <div data-height="35" style = "text-align: right;">
<afx-hbox data-height="30"> <afx-button data-id = "btnOk" text = "__(Ok)" ></afx-button>
<div ></div> <afx-button data-id = "btnCancel" text = "__(Cancel)" ></afx-button>
<afx-button data-id = "btnOk" text = "__(Ok)" data-width = "40" ></afx-button> </div>
<afx-button data-id = "btnCancel" text = "__(Cancel)" data-width = "50" ></afx-button>
</afx-hbox>
<div data-height="10" ></div>
</afx-vbox>
<div data-width = "10" ></div>
</afx-hbox>
</afx-vbox> </afx-vbox>
</afx-app-window>\ </afx-app-window>\
`; `;
@ -734,22 +683,12 @@ namespace OS {
* Scheme definition * Scheme definition
*/ */
InfoDialog.scheme = `\ InfoDialog.scheme = `\
<afx-app-window width='250' height='300' apptitle = "Info" > <afx-app-window width='300' height='350' apptitle = "Info" >
<afx-vbox> <afx-vbox padding = "10">
<afx-hbox>
<div data-width = "10" ></div>
<afx-vbox>
<div data-height="10" ></div>
<afx-grid-view data-id = "grid" ></afx-grid-view> <afx-grid-view data-id = "grid" ></afx-grid-view>
<div data-height="10" ></div> <div data-height="35" style="text-align: right;">
<afx-hbox data-height="30"> <afx-button data-id = "btnCancel" text = "__(Cancel)"></afx-button>
<div ></div> </div>
<afx-button data-id = "btnCancel" text = "__(Cancel)" data-width = "50" ></afx-button>
</afx-hbox>
<div data-height="10" ></div>
</afx-vbox>
<div data-width = "10" ></div>
</afx-hbox>
</afx-vbox> </afx-vbox>
</afx-app-window>\ </afx-app-window>\
`; `;
@ -815,22 +754,13 @@ namespace OS {
* Scheme definition * Scheme definition
*/ */
YesNoDialog.scheme = `\ YesNoDialog.scheme = `\
<afx-app-window width='200' height='150' apptitle = "Prompt"> <afx-app-window width='250' height='200' apptitle = "Warning">
<afx-vbox> <afx-vbox padding = "10">
<afx-hbox> <afx-label data-id = "lbl" valign="top" ></afx-label>
<div data-width = "10" ></div> <div data-height="35" style = "text-align: right;">
<afx-vbox> <afx-button data-id = "btnYes" text = "__(Yes)" ></afx-button>
<div data-height="10" ></div> <afx-button data-id = "btnNo" text = "__(No)"></afx-button>
<afx-label data-id = "lbl" ></afx-label> </div>
<div data-height="10" ></div>
<afx-hbox data-height="30">
<div ></div>
<afx-button data-id = "btnYes" text = "__(Yes)" data-width = "40" ></afx-button>
<afx-button data-id = "btnNo" text = "__(No)" data-width = "40" ></afx-button>
</afx-hbox>
</afx-vbox>
<div data-width = "10" ></div>
</afx-hbox>
</afx-vbox> </afx-vbox>
</afx-app-window>\ </afx-app-window>\
`; `;
@ -901,22 +831,13 @@ namespace OS {
* Scheme definition * Scheme definition
*/ */
SelectionDialog.scheme = `\ SelectionDialog.scheme = `\
<afx-app-window width='250' height='300' apptitle = "Selection"> <afx-app-window width='350' height='300' apptitle = "Selection">
<afx-vbox> <afx-vbox padding = "10">
<afx-hbox>
<div data-width = "10" ></div>
<afx-vbox>
<div data-height="10" ></div>
<afx-list-view data-id = "list" ></afx-list-view> <afx-list-view data-id = "list" ></afx-list-view>
<div data-height="10" ></div> <div data-height="35" style = "text-align: right;">
<afx-hbox data-height="30"> <afx-button data-id = "btnOk" text = "__(Ok)" ></afx-button>
<div ></div> <afx-button data-id = "btnCancel" text = "__(Cancel)"></afx-button>
<afx-button data-id = "btnOk" text = "__(Ok)" data-width = "40" ></afx-button> </div>
<afx-button data-id = "btnCancel" text = "__(Cancel)" data-width = "50" ></afx-button>
</afx-hbox>
</afx-vbox>
<div data-width = "10" ></div>
</afx-hbox>
</afx-vbox> </afx-vbox>
</afx-app-window>\ </afx-app-window>\
`; `;
@ -960,18 +881,11 @@ namespace OS {
iconclass: mt.iconclass, iconclass: mt.iconclass,
text: `${mt.name}(v${mt.version})`, text: `${mt.name}(v${mt.version})`,
}); });
$(this.find("mydesc")).html(mt.description); $(this.find("mydesc")).html(`${mt.description} <br/> ${mt.info.author} (${mt.info.email})`);
// grid data for author info // grid data for author info
if (!mt.info) { if (!mt.info) {
return; return;
} }
const rows = [
[{ text: __("Author") }, { text: mt.info.author }],
[{ text: __("Email") }, { text: mt.info.email }]
];
const grid = this.find("mygrid") as tag.GridViewTag;
grid.header = [{ text: "", width: 100 }, { text: "" }];
grid.rows = rows;
`pkg://${mt.pkgname?mt.pkgname:mt.app}/README.md` `pkg://${mt.pkgname?mt.pkgname:mt.app}/README.md`
.asFileHandle() .asFileHandle()
.read() .read()
@ -995,25 +909,19 @@ namespace OS {
* Scheme definition * Scheme definition
*/ */
AboutDialog.scheme = `\ AboutDialog.scheme = `\
<afx-app-window data-id = 'about-window' width='450' height='400'> <afx-app-window data-id = 'about-window' width='550' height='450'>
<afx-vbox> <afx-vbox padding = "5">
<div style="text-align:center; margin-top:10px;" data-height="50"> <div style="text-align:center; margin-top:10px;" data-height="50">
<h3 style = "margin:0;padding:0;"> <h3 style = "margin:0;padding:0;">
<afx-label data-id = 'mylabel' style="display: inline-block;"></afx-label> <afx-label data-id = 'mylabel' style="display: inline-block;"></afx-label>
</h3> </h3>
<i><p style = "margin:0; padding:0" data-id = 'mydesc'></p></i> <i><p style = "margin:0; padding:0" data-id = 'mydesc'></p></i>
</div> </div>
<afx-hbox data-height="60">
<div data-width="10"></div>
<afx-grid-view data-id = 'mygrid'></afx-grid-view>
</afx-hbox>
<div data-id="read-me" style="overflow-x: hidden; overflow-y: auto;"></div> <div data-id="read-me" style="overflow-x: hidden; overflow-y: auto;"></div>
<div data-height="10"></div> <div data-height="10"></div>
<afx-hbox data-height="30"> <div data-height="35" style = "text-align: right;">
<div ></div> <afx-button data-id = "btnCancel" text = "__(Cancel)" ></afx-button>
<afx-button data-id = "btnCancel" text = "__(Cancel)" data-width = "60" ></afx-button> </div>
</afx-hbox>
<div data-height = "10"></div>
</afx-vbox> </afx-vbox>
</afx-app-window>\ </afx-app-window>\
`; `;
@ -1076,7 +984,7 @@ namespace OS {
super.main(); super.main();
const fileview = this.find("fileview") as tag.FileViewTag; const fileview = this.find("fileview") as tag.FileViewTag;
const location = this.find("location") as tag.ListViewTag; const location = this.find("location") as tag.ListViewTag;
const filename = this.find("filename") as HTMLInputElement; const filename = this.find("filename") as tag.InputTag;
fileview.fetch = (path: string) => fileview.fetch = (path: string) =>
new Promise(function (resolve, reject) { new Promise(function (resolve, reject) {
if (!path) { if (!path) {
@ -1133,7 +1041,7 @@ namespace OS {
} }
fileview.onfileselect = function (e) { fileview.onfileselect = function (e) {
if (e.data.type === "file") { if (e.data.type === "file") {
return $(filename).val(e.data.filename); return filename.value = e.data.filename;
} }
}; };
(this.find("btnOk") as tag.ButtonTag).onbtclick = (_e) => { (this.find("btnOk") as tag.ButtonTag).onbtclick = (_e) => {
@ -1180,7 +1088,7 @@ namespace OS {
} }
} }
const name = $(filename).val(); const name = filename.value;
if (this.handle) { if (this.handle) {
this.handle({ file: f, name }); this.handle({ file: f, name });
} }
@ -1194,9 +1102,13 @@ namespace OS {
}; };
if (this.data && this.data.file) { if (this.data && this.data.file) {
$(filename) $(filename).show();
.css("display", "block") filename.value = (this.data.file.basename || "Untitled");
.val(this.data.file.basename || "Untitled"); this.trigger("resize");
}
else
{
$(filename).hide();
this.trigger("resize"); this.trigger("resize");
} }
if (this.data && this.data.hidden) { if (this.data && this.data.hidden) {
@ -1222,18 +1134,15 @@ namespace OS {
* Scheme definition * Scheme definition
*/ */
FileDialog.scheme = `\ FileDialog.scheme = `\
<afx-app-window width='400' height='300'> <afx-app-window width='400' height='450'>
<afx-vbox> <afx-vbox>
<afx-list-view data-id = "location" dropdown = "true" data-height = "40"></afx-list-view> <afx-list-view data-id = "location" dropdown = "true" data-height = "35"></afx-list-view>
<afx-file-view data-id = "fileview" view="tree" status = "false"></afx-file-view> <afx-file-view data-id = "fileview" view="tree" status = "false"></afx-file-view>
<input data-height = '26' type = "text" data-id = "filename" style="margin-left:5px; margin-right:5px;display:none;" ></input> <afx-input data-height = '52' label = "__(Target file/folder)" type = "text" data-id = "filename" ></afx-input>
<afx-hbox data-height = '30'> <div style=' text-align:right;' data-height="35">
<div style=' text-align:right;'>
<afx-button data-id = "btnOk" text = "__(Ok)"></afx-button> <afx-button data-id = "btnOk" text = "__(Ok)"></afx-button>
<afx-button data-id = "bt-cancel" text = "__(Cancel)"></afx-button> <afx-button data-id = "bt-cancel" text = "__(Cancel)"></afx-button>
</div> </div>
<div data-width="5"></div>
</afx-hbox>
</afx-vbox> </afx-vbox>
</afx-app-window>\ </afx-app-window>\
`; `;
@ -1316,17 +1225,15 @@ namespace OS {
* @memberof MultiInputDialog * @memberof MultiInputDialog
*/ */
init(): void { init(): void {
let height = 60; let height = 85;
let html = ""; let html = "";
if (this.data && this.data.model) { if (this.data && this.data.model) {
const model = this.data.model; const model = this.data.model;
for (const key in model) { for (const key in model) {
html += `\ html += `\
<afx-label data-height="25" text="{0}" ></afx-label> <afx-input data-height="52" text="{0}" type="text" name = {1} ></afx-input>
<input data-height="25" type="text" name="{1}" ></input>
<div data-height="10" ></div>
`.format(model[key], key); `.format(model[key], key);
height += 60; height += 52;
} }
} }
this.markup = MultiInputDialog.scheme.format(height, html); this.markup = MultiInputDialog.scheme.format(height, html);
@ -1369,20 +1276,13 @@ namespace OS {
*/ */
MultiInputDialog.scheme = `\ MultiInputDialog.scheme = `\
<afx-app-window width='350' height='{0}'> <afx-app-window width='350' height='{0}'>
<afx-hbox> <afx-vbox padding = "5">
<div data-width="10" ></div>
<afx-vbox>
<div data-height="5" ></div>
{1} {1}
<afx-hbox data-height="30"> <div data-height="35" style = "text-align: right;">
<div ></div> <afx-button data-id = "btnOk" text = "__(Ok)"></afx-button>
<afx-button data-id = "btnOk" text = "__(Ok)" data-width = "40" ></afx-button> <afx-button data-id = "btnCancel" text = "__(Cancel)"></afx-button>
<afx-button data-id = "btnCancel" text = "__(Cancel)" data-width = "50" ></afx-button> </div>
</afx-hbox>
<div data-height="5" ></div>
</afx-vbox> </afx-vbox>
<div data-width="10" ></div>
</afx-hbox>
</afx-app-window>`; </afx-app-window>`;
@ -1468,28 +1368,22 @@ namespace OS {
*/ */
private addField(key: string, value: string, removable: boolean): void { private addField(key: string, value: string, removable: boolean): void {
const div = $("<div>") const div = $("<div>")
.css("width", "100%")
.css("display", "flex") .css("display", "flex")
.css("flex-direction", "row") .css("flex-direction", "row")
.appendTo(this.container); .appendTo(this.container);
$("<input>") $("<input>")
.attr("type", "text") .attr("type", "text")
.css("width", "120px") .css("flex", "1")
.css("height", "23px")
.val(key) .val(key)
.appendTo(div); .appendTo(div);
$("<input>") $("<input>")
.attr("type", "text") .attr("type", "text")
.css("width", "200px") .css("flex", "1")
.css("height", "23px")
.val(value) .val(value)
.appendTo(div); .appendTo(div);
if (removable) { if (removable) {
const btn = $("<afx-button>"); const btn = $("<afx-button>");
btn[0].uify(undefined); btn[0].uify(undefined);
$("button", btn)
.css("width", "23px")
.css("height", "23px");
(btn[0] as tag.ButtonTag).iconclass = "fa fa-minus"; (btn[0] as tag.ButtonTag).iconclass = "fa fa-minus";
btn btn
.on("click", () => { .on("click", () => {
@ -1497,12 +1391,13 @@ namespace OS {
}) })
.appendTo(div); .appendTo(div);
} }
else { else
{
$("<div>") $("<div>")
.css("width", "23px") .css("width", "40px")
.css("height", "35px")
.appendTo(div); .appendTo(div);
} }
} }
} }
@ -1511,23 +1406,18 @@ namespace OS {
* Scheme definition * Scheme definition
*/ */
KeyValueDialog.scheme = `\ KeyValueDialog.scheme = `\
<afx-app-window width='350' height='300'> <afx-app-window width='400' height='350'>
<afx-hbox> <afx-vbox padding = "10">
<div data-width="10" ></div>
<afx-vbox>
<div data-height="5" ></div>
<afx-label text="__(Enter key-value data)" data-height="30"></afx-label> <afx-label text="__(Enter key-value data)" data-height="30"></afx-label>
<div data-id="container"></div> <div data-id="container"></div>
<afx-hbox data-height="30"> <afx-hbox data-height="35">
<afx-button data-id = "btnAdd" iconclass="fa fa-plus" data-width = "30" ></afx-button> <afx-button data-id = "btnAdd" iconclass="fa fa-plus" data-width = "35" ></afx-button>
<div ></div> <div style = "text-align: right;">
<afx-button data-id = "btnOk" text = "__(Ok)" data-width = "40" ></afx-button> <afx-button data-id = "btnOk" text = "__(Ok)"></afx-button>
<afx-button data-id = "btnCancel" text = "__(Cancel)" data-width = "50" ></afx-button> <afx-button data-id = "btnCancel" text = "__(Cancel)"></afx-button>
</div>
</afx-hbox> </afx-hbox>
<div data-height="5" ></div>
</afx-vbox> </afx-vbox>
<div data-width="10" ></div>
</afx-hbox>
</afx-app-window>`; </afx-app-window>`;
} }
} }

View File

@ -113,8 +113,10 @@ namespace OS {
* @memberof CalendarTag * @memberof CalendarTag
*/ */
protected mount(): void { protected mount(): void {
$(this.refs.prev).on("click",(e) => this.prevmonth()); (this.refs.prev as ButtonTag).iconclass = "fa fa-angle-left";
$(this.refs.next).on("click",(e) => this.nextmonth()); (this.refs.next as ButtonTag).iconclass = "fa fa-angle-right";
(this.refs.prev as ButtonTag).onbtclick = (e) => this.prevmonth();
(this.refs.next as ButtonTag).onbtclick = (e) => this.nextmonth();
const grid = this.refs.grid as GridViewTag; const grid = this.refs.grid as GridViewTag;
grid.header = [ grid.header = [
{ text: "__(Sun)" }, { text: "__(Sun)" },
@ -319,9 +321,9 @@ namespace OS {
el: "div", el: "div",
ref: "ctrl", ref: "ctrl",
children: [ children: [
{ el: "i", class: "prevmonth", ref: "prev" }, { el: "afx-button", class: "prevmonth", ref: "prev" },
{ el: "afx-label", ref: "mlbl" }, { el: "afx-label", ref: "mlbl" },
{ el: "i", class: "nextmonth", ref: "next" }, { el: "afx-button", class: "nextmonth", ref: "next" },
], ],
}, },
{ el: "afx-grid-view", ref: "grid" }, { el: "afx-grid-view", ref: "grid" },

View File

@ -1217,7 +1217,6 @@ namespace OS {
.css("top", top + "px") .css("top", top + "px")
.css("left", left + "px"); .css("left", left + "px");
}; };
return this.calibrate(); return this.calibrate();
} }

265
src/core/tags/InputTag.ts Normal file
View File

@ -0,0 +1,265 @@
namespace OS {
export namespace GUI {
export namespace tag {
/**
* This tag define a basic text input and its behavior
*
* @export
* @class InputTag
* @extends {AFXTag}
*/
export class InputTag extends AFXTag {
/**
*Creates an instance of InputTag.
* @memberof InputTag
*/
constructor() {
super();
}
/**
* Set the path to the header icon, the path should be
* a VFS file path
*
* @memberof InputTag
*/
set icon(v: string) {
$(this).attr("icon", v);
(this.refs.label as LabelTag).icon = v;
}
/**
* Set the icon class to the header
*
* @memberof InputTag
*/
set iconclass(v: string) {
$(this).attr("iconclass", v);
(this.refs.label as LabelTag).iconclass = v;
}
/**
* Alias to header setter/getter
*
* @memberof InputTag
*/
set text(v: string | FormattedString) {
this.label = v;
}
get text(): string | FormattedString {
return this.label;
}
/**
* Setter: Set the text of the button
*
* Getter: Get the current button test
*
* @memberof InputTag
*/
set label(v: string | FormattedString) {
(this.refs.label as LabelTag).text = v;
}
get label(): string | FormattedString {
return (this.refs.label as LabelTag).text;
}
/**
* Setter: Enable or disable the input
*
* Getter: Get the `enable` property of the input
*
* @memberof InputTag
*/
set disable(v: boolean) {
$(this.refs.area).prop("disabled", v);
$(this.refs.input).prop("disabled", v);
}
get disable(): boolean {
return !$(this.input).prop("disabled");
}
/**
* Setter: set verbosity of the input
*
* Getter: Get the current input verbosity
*
* @memberof InputTag
*/
set verbose(v: boolean) {
this.attsw(v, "verbose");
this.calibrate();
}
get verbose(): boolean {
return this.hasattr("verbose");
}
/**
* JQuery style generic event handling on the input element
*
* @param {string} enname: JQuery event name
* @param {JQuery.TypeEventHandler<HTMLInputElement | HTMLTextAreaElement, unknown, any, any, string>} handle: JQuery handle
* @memberof InputTag
*/
on(ename: string, handle:JQuery.TypeEventHandler<HTMLInputElement | HTMLTextAreaElement, unknown, any, any, string> ): void
{
$(this.input).on(ename, handle);
}
/**
* Manually trigger an event
*
* @param {string} evt: JQuery event name
* @memberof InputTag
*/
trigger(evt: string)
{
$(this.input).trigger(evt);
}
/**
* Mount the tag
*
* @protected
* @memberof InputTag
*/
protected mount() {
// Do nothing
}
/**
* Get the current active input element
*
* @memberof InputTag
*/
get input(): HTMLInputElement | HTMLTextAreaElement
{
if(this.verbose)
{
return this.refs.area as HTMLTextAreaElement;
}
return this.refs.input as HTMLInputElement;
}
/**
* Get/set the current active input value
*
* @memberof InputTag
*/
get value(): string{
return this.input.value;
}
set value(v: string)
{
this.input.value = v;
}
/**
* Get/set input type
* This only affects the inline input element
*
* @memberof InputTag
*/
get type(): string{
if(this.verbose) return undefined;
return (this.input as HTMLInputElement).type;
}
set type(v: string)
{
if(!this.verbose)
{
(this.input as HTMLInputElement).type = v;
}
}
/**
* Get/set input name
*
* @memberof InputTag
*/
get name(): string{
return (this.input as HTMLInputElement).name;
}
set name(v: string)
{
(this.input as HTMLInputElement).name = v;
}
/**
* Init the tag before mounting
*
* @protected
* @memberof InputTag
*/
protected init(): void {
this.disable = false;
this.verbose = false;
this.type = "text";
}
/**
* Re-calibrate the button, do nothing in this tag
*
* @protected
* @memberof InputTag
*/
protected calibrate(): void
{
$(this.refs.area)
.css("width", "100%");
$(this.refs.input)
.css("width", "100%");
if(this.verbose)
{
$(this.refs.area).show();
$(this.refs.input).hide();
(this.refs.input as HTMLInputElement).value = "";
}
else
{
$(this.refs.area).hide();
$(this.refs.input).show();
(this.refs.area as HTMLTextAreaElement).value = "";
}
}
/**
* Update the current tag, do nothing in this tag
*
* @param {*} [d]
* @memberof InputTag
*/
reload(d?: any): void {}
/**
* Button layout definition
*
* @protected
* @returns {TagLayoutType[]}
* @memberof InputTag
*/
protected layout(): TagLayoutType[] {
return [
{
el: "afx-label",
ref: "label"
},
{
el: "input",
ref:"input"
},
{
el: "textarea",
ref: "area"
},
{
el: "div"
}
];
}
}
define("afx-input", InputTag);
}
}
}

View File

@ -94,6 +94,49 @@ namespace OS {
$(this.refs.i).hide(); $(this.refs.i).hide();
} }
} }
/**
* set horizontal aligment of the label content
*
* @param {string} v shall be "left, right, or center"
*/
set halign(v: string)
{
let align = "center";
switch(v)
{
case "left":
align = "flex-start";
break;
case "right":
align = "flex-end";
break;
default:
break;
}
$(this.refs.container).css("justify-content", align);
}
/**
* set horizontal aligment of the label content
*
* @param {string} v shall be "top, bottom, or center"
*/
set valign(v: string)
{
let align = "center";
switch(v)
{
case "top":
align = "flex-start";
break;
case "bottom":
align = "flex-end";
break;
default:
break;
}
$(this.refs.container).css("align-items", align);
}
/** /**
* Set the CSS class of the label icon * Set the CSS class of the label icon

View File

@ -23,13 +23,17 @@ namespace OS {
super(); super();
} }
private _padding: number;
/** /**
* Do nothing * Do nothing
* *
* @protected * @protected
* @memberof TileLayoutTag * @memberof TileLayoutTag
*/ */
protected init(): void {} protected init(): void {
this.padding = 0;
}
/** /**
* Do nothing * Do nothing
* *
@ -84,6 +88,26 @@ namespace OS {
get dir(): "row" | "column" { get dir(): "row" | "column" {
return $(this).attr("dir") as any; return $(this).attr("dir") as any;
} }
/**
* Setter:
*
* SET content padding
*
* Getter:
*
* Get content padding
*
* @memberof TileLayoutTag
*/
set padding(v: number)
{
$(this).attr("padding", v);
this._padding = v;
}
get padding(): number
{
return this._padding;
}
/** /**
* Mount the element * Mount the element
@ -95,9 +119,7 @@ namespace OS {
protected mount(): void { protected mount(): void {
$(this).css("display", "block"); $(this).css("display", "block");
$(this.refs.yield) $(this.refs.yield)
.css("display", "flex") .css("display", "flex");
.css("width", "100%")
.css("height", "100%");
this.observable.on("resize", (e) => this.calibrate()); this.observable.on("resize", (e) => this.calibrate());
return this.calibrate(); return this.calibrate();
} }
@ -109,6 +131,10 @@ namespace OS {
* @memberof TileLayoutTag * @memberof TileLayoutTag
*/ */
calibrate(): void { calibrate(): void {
$(this.refs.yield)
.css("padding", this.padding)
.css("width", `${$(this).width() - this.padding*2}px`)
.css("height", `${$(this).height() - this.padding*2}px`);
if (this.dir === "row") { if (this.dir === "row") {
return this.hcalibrate(); return this.hcalibrate();
} }
@ -128,7 +154,7 @@ namespace OS {
private hcalibrate(): void { private hcalibrate(): void {
const auto_width = []; const auto_width = [];
let ocwidth = 0; let ocwidth = 0;
const avaiWidth = $(this).width(); const avaiWidth = $(this).width() - this.padding * 2;
$(this.refs.yield) $(this.refs.yield)
.children() .children()
.each(function (e) { .each(function (e) {
@ -171,7 +197,7 @@ namespace OS {
private vcalibrate(): void { private vcalibrate(): void {
const auto_height = []; const auto_height = [];
let ocheight = 0; let ocheight = 0;
const avaiheight = $(this).height(); const avaiheight = $(this).innerHeight() - this.padding * 2;
$(this.refs.yield) $(this.refs.yield)
.children() .children()
.each(function (e) { .each(function (e) {

View File

@ -601,7 +601,7 @@ namespace OS {
const dep = this.checkDependencies(pkgname); const dep = this.checkDependencies(pkgname);
if (dep.notfound.size != 0) { if (dep.notfound.size != 0) {
this.openDialog("TextDialog", { this.openDialog("TextDialog", {
disable: true, disable: false,
title: __("Unresolved dependencies"), title: __("Unresolved dependencies"),
value: __( value: __(
"Unable to install: The package `{0}` depends on these packages, but they are not found:\n{1}", "Unable to install: The package `{0}` depends on these packages, but they are not found:\n{1}",

View File

@ -1,44 +1,11 @@
afx-calendar-view div{ afx-calendar-view div{
text-align: center; text-align: center;
} }
afx-calendar-view > div {
afx-calendar-view > div afx-label i{
font-weight: bold; font-weight: bold;
} }
afx-calendar-view i.prevmonth, afx-calendar-view i.nextmonth{
display: inline-block;
width: 16px;
height: 16px;
cursor: pointer;
}
afx-calendar-view i.prevmonth{
margin-right: 20px;
}
afx-calendar-view i.nextmonth{
margin-left: 20px;
}
afx-calendar-view i.prevmonth:before{
content: "\f104";
font-family: "FontAwesome";
font-size: 16px;
font-style: normal;
/*position:absolute;
top:25%;
right:5px;*/
}
afx-calendar-view i.nextmonth:before{
content: "\f105";
font-family: "FontAwesome";
font-size: 16px;
font-style: normal;
margin-left: 20px;
/*position:absolute;
top:25%;
right:5px;*/
}
afx-calendar-view afx-grid-view afx-grid-row.afx-grid-row-selected afx-grid-cell afx-calendar-view afx-grid-view afx-grid-row.afx-grid-row-selected afx-grid-cell
{ {

View File

@ -0,0 +1,20 @@
afx-input afx-label
{
font-size: 13px;
color: #bb86fc;
background-color: #464646;
}
afx-input input,
afx-input textarea
{
border-radius: 0;
border: 0;
border-bottom: 1px solid #262626;
background-color: #464646;
}
afx-input input:focus,
afx-input textarea:focus
{
border-bottom: 1px solid #bb86fc;
}

View File

@ -1,5 +1,4 @@
html,body{ html,body{
font-family: "Ubuntu";
color: white; color: white;
} }
#desktop > div > ul afx-list-item { #desktop > div > ul afx-list-item {
@ -44,14 +43,11 @@ html,body{
input { input {
outline: none; outline: none;
padding: 2px; padding: 2px;
height:23px;
border: 1px solid #262626; border: 1px solid #262626;
background-color:#464646; background-color:#464646;
color: white; color: white;
border-radius: 3px; border-radius: 3px;
box-sizing: border-box; box-sizing: border-box;
font-family: "Ubuntu";
font-size: 13px;
} }
textarea { textarea {

View File

@ -1,49 +1,11 @@
afx-calendar-view div{ afx-calendar-view div{
text-align: center; text-align: center;
} }
afx-calendar-view > div {
afx-calendar-view > div afx-label i{
font-weight: bold; font-weight: bold;
} }
afx-calendar-view i.prevmonth, afx-calendar-view i.nextmonth{
display: inline-block;
width: 16px;
height: 16px;
cursor: pointer;
}
afx-calendar-view i.prevmonth{
margin-right: 20px;
}
afx-calendar-view i.nextmonth{
margin-left: 20px;
}
afx-calendar-view i.prevmonth:before{
content: "\f104";
font-family: "FontAwesome";
font-size: 16px;
font-style: normal;
/*position:absolute;
top:25%;
right:5px;*/
}
afx-calendar-view i.nextmonth:before{
content: "\f105";
font-family: "FontAwesome";
font-size: 16px;
font-style: normal;
margin-left: 20px;
/*position:absolute;
top:25%;
right:5px;*/
}
/*
afx-calendar-view afx-grid-view afx-grid-row.selected{
background-color: white;
color:#414339;
}*/
afx-calendar-view afx-grid-view afx-grid-row.afx-grid-row-selected afx-grid-cell afx-calendar-view afx-grid-view afx-grid-row.afx-grid-row-selected afx-grid-cell
{ {
background-color: transparent; background-color: transparent;

View File

@ -0,0 +1,20 @@
afx-input afx-label
{
font-size: 13px;
color: #116cd6;
background-color: #f6f6f6;
}
afx-input input,
afx-input textarea
{
border-radius: 0;
border: 0;
border-bottom: 1px solid #a6a6a6;
background-color: #f6f6f6;
}
afx-input input:focus,
afx-input textarea:focus
{
border-bottom: 1px solid #116cd6;
}

View File

@ -1,5 +1,4 @@
html,body{ html,body{
font-family: "Ubuntu";
color:#414339; color:#414339;
} }
@ -45,14 +44,11 @@ html,body{
input { input {
outline: none; outline: none;
padding: 2px; padding: 2px;
height:23px;
border: 1px solid #a6a6a6; border: 1px solid #a6a6a6;
background-color: #f6F6F6; background-color: #f6F6F6;
color: #414339; color: #414339;
border-radius: 5px; border-radius: 5px;
box-sizing: border-box; box-sizing: border-box;
font-family: "Ubuntu";
font-size: 13px;
} }
textarea { textarea {
color: #414339; color: #414339;

View File

@ -6,5 +6,15 @@ afx-calendar-view afx-grid-view .grid_row_header afx-grid-cell{
border-right: 0; border-right: 0;
} }
afx-calendar-view afx-label { afx-calendar-view afx-label {
display: inline-block; flex-direction: row;
justify-content: center;
}
afx-calendar-view > div {
display: flex;
flex-direction: row;
}
afx-calendar-view > div > afx-label
{
flex:1;
} }

View File

@ -0,0 +1,29 @@
afx-input {
display: flex;
flex-direction: column;
}
afx-input textarea
{
flex: 1;
padding-left: 5px;
padding-right: 5px;
}
afx-input > div
{
flex: 1;
}
afx-input[verbose] > div {
flex: none;
height: 0;
}
afx-input input{
height: 30px;
padding-left: 5px;
padding-right: 5px;
}
afx-input afx-label
{
padding-left: 3px;
padding-top: 5px;
}

View File

@ -6,6 +6,7 @@ html,body{
overflow: hidden; overflow: hidden;
touch-action: none; touch-action: none;
font-size: 14px; font-size: 14px;
font-family: "Ubuntu";
} }
#desktop > div > ul afx-list-item { #desktop > div > ul afx-list-item {
width: 70px; width: 70px;
@ -73,6 +74,16 @@ body
#systooltip { #systooltip {
z-index: 1000000; z-index: 1000000;
} }
input {
font-size: 14px;
height: 35px;
font-family: "Ubuntu";
}
textarea {
font-family: "Ubuntu";
font-size: 14px;
}
#login_form{ #login_form{
width:300px; width:300px;