diff --git a/photonui/photonui-tests.ts b/photonui/photonui-tests.ts new file mode 100644 index 000000000..3242d3a92 --- /dev/null +++ b/photonui/photonui-tests.ts @@ -0,0 +1,908 @@ +/// + +// All exemple scripts from PhotonUI documentation: + +// Accel Manager +// We add a field to test accels +var field = new photonui.TextField({ + value: "Text Field" +}); +photonui.domInsert(field, "demo"); + +// ... And a label to display things +var label = new photonui.Label({text: ""}); +photonui.domInsert(label, "demo"); + +// We create the accel +var accel = new photonui.AccelManager(); + +// "Ctrl+A" / "Command+A" accelerator that is disabled if +// a field is focused +accel.addAccel("accel1", "ctrl + a", function() { + label.text += "'Ctrl + A' accelerator\n"; +}); +accel.addAccel("accel1-mac", "command + a", function() { + label.text += "'Command + A' accelerator\n"; +}); + +// "Ctrl+R" accelerator that works even if the field is focused +accel.addAccel("accel3", "ctrl + r", function() { + label.text += "'Ctrl + R' accelerator\n"; +}, false); + +// A more complexe sequence (hold "Ctrl+X", and then press "C") +accel.addAccel("accel4", "ctrl + x > c", function() { + label.text += "'Ctrl + X > C' accelerator\n"; +}); + +// BoxLayout +var box = new photonui.BoxLayout({ + orientation: "vertical", // "vertical" or "horizontal" + spacing: 5, // spacing between widgets + children: [ + new photonui.Button(), + new photonui.Button(), + new photonui.Button() + ] +}); + +photonui.domInsert(box, "demo"); + +// Button +var btn = new photonui.Button({ + text: "My Button", + leftIcon: new photonui.FAIcon("fa-send"), + callbacks: { + click: function(widget: any, event: any) { + alert("Someone clicked on " + widget.text); + } + } +}); + +photonui.domInsert(btn, "demo"); + +// canvas +var canvas = new photonui.Canvas({ + width: 200, + height: 150 +}); + +photonui.domInsert(canvas, "demo"); + +var ctx = canvas.getContext("2d"); + +ctx.lineWidth = 3; +ctx.strokeStyle = "#DB624F"; + +ctx.beginPath(); +ctx.moveTo(10, 10); +ctx.lineTo(40, 140); +ctx.lineTo(50, 30); +ctx.lineTo(190, 100); +ctx.stroke(); + +// Checkbox +var check = new photonui.CheckBox({ + value: true +}); + +photonui.domInsert(check, "demo"); + +// Color +var color = new photonui.Color("red"); + +console.log(color.hexString); +// "#FF0000" +var color = new photonui.Color("red"); + +console.log(color.hexString); +// "#FF0000" + +console.log(color.rgbString); +// "rgb(255, 0, 0)" + +console.log(color.rgbaString); +// "rgb(255, 0, 0, 1)" + +console.log(color.getRGB()); +// Array [ 255, 0, 0 ] + +console.log(color.getRGBA()); +// Array [ 255, 0, 0, 255 ] + +console.log(color.red, color.green, color.blue); +// 255 0 0 + +console.log(color.hue, color.saturation, color.brightness); +// 0 100 100 + +color.brightness = 50; +console.log(color.hexString); +// "#7F0000" + +color.hue = 204; +console.log(color.hexString); +// #004C7F + +// ColorButton +var btn2 = new photonui.ColorButton({ + value: "#4EC8DB", + callbacks: { + "value-changed": function(widget: any, value: any) { + var header = document.getElementsByTagName("header")[0]; + header.style.backgroundColor = value; + } + } +}); + +photonui.domInsert(btn2, "demo"); + +// colorpalette +var palette = new photonui.ColorPalette({ + callbacks: { + "value-changed": function(widget: any, value: any) { + var header = document.getElementsByTagName("header")[0]; + header.style.backgroundColor = value; + } + } +}); + +photonui.domInsert(palette, "demo"); + +var palette = new photonui.ColorPalette({ + palette: [ + ["#D32F2F", "#F44336", "#E91E63", "#9C27B0", "#673AB7"], + ["#3F51B5", "#2196F3", "#03A9F4", "#00BCD4", "#009688"], + ["#4CAF50", "#8BC34A", "#CDDC39", "#FFEB3B", "#FFC107"], + ["#FF9800", "#FF5722", "#795548", "#9E9E9E", "#607D8B"] + ], + callbacks: { + "value-changed": function(widget: any, value: any) { + var header = document.getElementsByTagName("header")[0]; + header.style.backgroundColor = value; + } + } +}); + +photonui.domInsert(palette, "demo"); + +// ColorPicker +var colorPicker = new photonui.ColorPicker({ + value: "#4EC8DB", + callbacks: { + "value-changed": function(widget: any, value: any) { + var header = document.getElementsByTagName("header")[0]; + header.style.backgroundColor = value; + } + } +}); + +photonui.domInsert(colorPicker, "demo"); + +// ColorPickerDialog +var dlg = new photonui.ColorPickerDialog({ + value: "#4EC8DB", + callbacks: { + "value-changed": function(widget: any, value: any) { + var header = document.getElementsByTagName("header")[0]; + header.style.backgroundColor = value; + } + } +}); + +// Add a button to show up the dialog +var btn = new photonui.Button({ + text: "Display the dialog", + callbacks: { + click: dlg.show.bind(dlg) + } +}); + +photonui.domInsert(btn, "demo"); + +// Dialog +var pos = photonui.Helpers.getAbsolutePosition("demo"); + +new photonui.Dialog({ + title: "My Dialog", + visible: true, + x: pos.x, y: pos.y, + child: new photonui.Label("Hello, I'm a dialog"), + padding: 10, + buttons: [ + new photonui.Button() + ], + callbacks: { + "close-button-clicked": function(widget: any) { + widget.destroy(); + } + } +}); + +// FAIcon +var icon = new photonui.FAIcon({ + iconName: "fa-camera", + size: "fa-3x", // "", "fa-lg", "fa-2x", "fa-3x", "fa-4x", "fa5x" + color: "#DB624F" +}); + +photonui.domInsert(icon, "demo"); + +// FileManager +// File manager that accepts PNG, JPEG, BMP and SVG files +var fm = new photonui.FileManager({ + acceptedMimes: ["image/png", "image/jpeg"], + acceptedExts: ["bmp", "svg"], + dropZone: document, // Enable file d&d + multiselect: true, // Allow to select more than one file + callbacks: { + "file-open": function(widget: any, file: any, x: number, y: number) { + // x and y are defined only with d&d + if (x !== undefined) { + alert(file.name + " dropped at ("+x+", "+y+")"); + } + else { + alert(file.name + " opened"); + } + } + } +}); + +// Button to show the "file open" dialog +var btn = new photonui.Button({ + text: "Open", + callbacks: { + click: function(widget: any, event: any) { + fm.open(); + } + } +}); + +photonui.domInsert(btn, "demo"); + +// FluidLayout +var fl = new photonui.FluidLayout({ + children: [ + new photonui.Button(), + new photonui.Button(), + new photonui.Button(), + new photonui.Button(), + new photonui.Button(), + new photonui.Button(), + new photonui.Button() + ] +}); + +photonui.domInsert(fl, "demo"); + +// FontSelect +var select = new photonui.FontSelect({ + value: "item1", + fonts: [ + "Arial", + "Arial Black", + "Cantarell", + "Courier New", + "Impact", + "Time New Roman", + "Titillium Web", + "Verdana" + ], + callbacks: { + "value-changed": function(widget: any, value: any) { + alert("Value changed: " + value); + } + } +}); + +photonui.domInsert(select, "demo"); + +// GridLayout +var grid = new photonui.GridLayout({ + horizontalPadding: 0, + verticalPadding: 0, + horizontalSpacing: 5, + verticalSpacing: 5, + children: [ + new photonui.Button({ + text: "Widget 1", + layoutOptions: { + x: 0, y: 0, + cols: 1, rows: 1 + } + }), + new photonui.Button({ + text: "Widget 2", + layoutOptions: { + x: 1, y: 0, + cols: 1, rows: 1 + } + }), + new photonui.Button({ + text: "Widget 3", + layoutOptions: { + x: 2, y: 0, + cols: 1, rows: 2 + } + }), + new photonui.Button({ + text: "Widget 4", + layoutOptions: { + x: 0, y: 1, + cols: 2, rows: 1 + } + }) + ] +}); + +photonui.domInsert(grid, "demo"); + +// Image +var img = new photonui.Image({ + url: "../../images/favicon.png" +}); + +photonui.domInsert(img, "demo"); + +// Label +var label = new photonui.Label({ + text: "My Label", + textAlign: "left" +}); + +photonui.domInsert(label, "demo"); + +// Menu +var menu = new photonui.Menu({ + iconVisible: true, + children: [ + new photonui.MenuItem({ + text: "Menu Item 1", + icon: new photonui.FAIcon("fa-paper-plane") + }), + new photonui.MenuItem({ + text: "Menu Item 2", + icon: new photonui.FAIcon("fa-gears") + }), + new photonui.MenuItem({ + text: "Menu Item 3", + icon: new photonui.FAIcon("fa-paw") + }) + ] +}); + +photonui.domInsert(menu, "demo"); + +// MenuItem +var menu = new photonui.Menu({ + iconVisible: true, + children: [ + new photonui.MenuItem({ + text: "Menu Item 1", + icon: new photonui.FAIcon("fa-paper-plane"), + callbacks: { + click: function(widget: any, event: any) { + alert("You clicked on me!"); + } + } + }), + new photonui.MenuItem({ + text: "Menu Item 2", + icon: new photonui.FAIcon("fa-gears") + }), + new photonui.MenuItem({ + text: "Menu Item 3", + icon: new photonui.FAIcon("fa-paw") + }) + ] +}); + +photonui.domInsert(menu, "demo"); + +// Mouse Manager +var img = new photonui.Image({ + url: "../../images/favicon.png" +}); + +var mouse = new photonui.MouseManager({ + element: img, + callbacks: { + "click": function(manager: any, mstate: any) { + alert("You clicked on the image at " + + mstate.x + ", " + mstate.y); + } + } +}); + +photonui.domInsert(img, "demo"); + +// Numeric Filed +var field2 = new photonui.NumericField({ + placeholder: "placeholder", + decimalDigits: 2, + min: -10, max: 10, + step: 0.5, // When scrolling over the field + decimalSymbol: ".", // "." or "," + value: 5.5 +}); + +photonui.domInsert(field2, "demo"); + +// PopupMenu +var pos = photonui.Helpers.getAbsolutePosition("demo"); + +var popup = new photonui.PopupMenu({ + children: [ + new photonui.MenuItem({ + text: "Menu Item 1", + icon: new photonui.FAIcon("fa-paper-plane"), + callbacks: { + click: function(widget: any, event: any) { + alert("You clicked on me!"); + } + } + }), + new photonui.MenuItem({ + text: "Menu Item 2", + icon: new photonui.FAIcon("fa-gears") + }), + new photonui.MenuItem({ + text: "Menu Item 3", + icon: new photonui.FAIcon("fa-paw") + }) + ] +}); + +popup.popupXY(pos.x, pos.y); + +// PopupWindow +var pos = photonui.Helpers.getAbsolutePosition("demo"); + +var popup = new photonui.PopupWindow({ + padding: 10, + width: 200, + height: 200, + child: new photonui.Label({ + text: "Click anywhere to close" + }) +}); + +popup.popupXY(pos.x, pos.y); + +// ProgressBar +var pb = new photonui.ProgressBar({ + textVisible: true, + value: 0.42 +}); + +photonui.domInsert(pb, "demo"); + +// Select +var select2 = new photonui.Select({ + value: "item1", + children: [ + new photonui.MenuItem({value: "item1", text: "Item 1"}), + new photonui.MenuItem({value: "item2", text: "Item 2"}), + new photonui.MenuItem({value: "item3", text: "Item 3"}) + ], + callbacks: { + "value-changed": function(widget: any, value: any) { + alert("Value changed: " + value); + } + } +}); + +photonui.domInsert(select2, "demo"); + +// Separator +var separator = new photonui.Separator(); + +photonui.domInsert(separator, "demo"); + +// Slider +var box = new photonui.BoxLayout({ + children: [ + new photonui.Slider({ + fieldVisible: false, + min: 0, max: 100, + step: 5, + value: 50 + }), + new photonui.Slider({ + fieldVisible: true, + min: -100, max: 100, + step: 10, + value: -50 + }), + new photonui.Slider({ + fieldVisible: true, + min: 0, max: 1, + decimalDigits: 2, + decimalSymbol: ".", + step: 0.05, + value: 0.5 + }) + ] +}); + +photonui.domInsert(box, "demo"); + +// SpriteIcon +// Create the spritesheet +var spriteSheet = new photonui.SpriteSheet({ + name: "default", + imageUrl: "./spritesheet.png", + size: 16, + icons: { + "remove": [ 0, 0], + "add": [16, 0], + "grayHeart": [32, 0], + "redHeart": [48, 0], + "battery1": [ 0, 16], + "battery2": [16, 16], + "battery3": [32, 16], + "battery4": [48, 16] + } +}); + +// Create an icon from the spritesheet +var icon2 = new photonui.SpriteIcon("default/redHeart"); + +photonui.domInsert(icon2, "demo"); + +// SubMenuItem +var menu = new photonui.Menu({ + iconVisible: true, + children: [ + new photonui.SubMenuItem({ + text: "Submenu Item", + menuName: "submenu1", + icon: new photonui.FAIcon("fa-paw") + }), + new photonui.Menu({ + visible: true, // false to hide it by default + name: "submenu1", + iconVisible: true, + children: [ + new photonui.MenuItem({ + text: "Submenu Item 1", + icon: new photonui.FAIcon("fa-gamepad") + }), + new photonui.MenuItem({ + text: "Sumbenu Item 2", + icon: new photonui.FAIcon("fa-flask") + }) + ] + }) + ] +}); + +photonui.domInsert(menu, "demo"); + +// Switch +var sw = new photonui.Switch({ + value: true +}); + +photonui.domInsert(sw, "demo"); + +// TabItem +var tabs = new photonui.TabLayout({ + tabsPosition: "top", // "top", "bottom", "left" or "right" + children: [ + new photonui.TabItem({ + title: "Tab 1", + child: new photonui.Label("Widget inside the first tab") + }), + new photonui.TabItem({ + title: "Tab 2", + child: new photonui.Button() + }), + new photonui.TabItem({ + title: "Tab 3" + }) + ] +}); + +photonui.domInsert(tabs, "demo"); +document.getElementById("demo") + .className += " photonui-container-expand-child"; + +// TabLayout +var tabs = new photonui.TabLayout({ + tabsPosition: "top", // "top", "bottom", "left" or "right" + children: [ + new photonui.TabItem({ + title: "Tab 1", + child: new photonui.Label("Widget inside the first tab") + }), + new photonui.TabItem({ + title: "Tab 2", + child: new photonui.Button() + }), + new photonui.TabItem({ + title: "Tab 3" + }) + ] +}); + +photonui.domInsert(tabs, "demo"); +document.getElementById("demo") + .className += " photonui-container-expand-child"; + +// Text +var text = new photonui.Text({ + rawHtml: "Lorem ipsum dolor sit amet..." +}); + +photonui.domInsert(text, "demo"); + +// TextAreaField +var field3 = new photonui.TextAreaField({ + placeholder: "placeholder", + value: "This is a\nTextArea" +}); + +photonui.domInsert(field3, "demo"); + +// TextField +var field = new photonui.TextField({ + placeholder: "placeholder", + value: "Text" +}); + +photonui.domInsert(field, "demo"); + +var grid = new photonui.GridLayout({ + verticalSpacing: 5, + horizontalSpacing: 5, + children: [ + new photonui.Label({ + text: "Username:", + forInputName: "username-field", + layoutOptions: { + gridX: 0, + gridY: 0 + } + }), + new photonui.TextField({ + name: "username-field", + placeholder: "Username", + value: "Anakin", + layoutOptions: { + gridX: 1, + gridY: 0 + } + }), + new photonui.Label({ + text: "Password:", + forInputName: "password-field", + layoutOptions: { + gridX: 0, + gridY: 1 + } + }), + new photonui.TextField({ + name: "password-field", + type: "password", + placeholder: "password", + value: "D4RK51D3", + layoutOptions: { + gridX: 1, + gridY: 1 + } + }), + new photonui.Button({ + text: "Login", + leftIcon: new photonui.FAIcon("fa-sign-in"), + callbacks: { + click: function(widget: any, event: any) { + var usernameField = photonui.getWidget("username-field"); + var passwordField = photonui.getWidget("password-field"); + alert( + "Username: " + (usernameField).value + + ", Password: " + (passwordField).value + ); + } + }, + layoutOptions: { + gridX: 0, + gridY: 2, + gridWidth: 2 + } + }) + ] +}); + +photonui.domInsert(grid, "demo"); + +// ToggleButton +var toggle = new photonui.ToggleButton({ + value: false, + text: "Toggle Button" +}); + +photonui.domInsert(toggle, "demo"); + +var toggle2 = new photonui.ToggleButton({ + value: false, + text: "Value: off", + buttonColor: "red", + callbacks: { + "value-changed": function(widget: any, value: any) { + widget.text = "Value: " + ((value) ? "on" : "off"); + widget.buttonColor = (value) ? "green" : "red"; + } + } +}); + +photonui.domInsert(toggle2, "demo"); + +// Translation +var translation = new photonui.Translation(); + +translation.addCatalogs({ + "fr": { + "messages": { + "Hello World": ["Bonjour le monde"] + } + } +}); + +translation.locale = "fr"; // Change the locale to test + +var label = new photonui.Label({ + text: _("Hello World"), + text2: translation.lazyGettext("Hello World") +}); + +photonui.domInsert(label, "demo"); + +var tr = new photonui.Translation(); +tr.addCatalogs({ + "fr": { + "plural-forms": "nplurals=2; plural=(n > 1);", + "messages": { + "Hello World": ["Bonjour le monde"], + 'Browser language is "{lang}".': ["La langue du navigateur est « {lang} »."], + "Close": ["Fermer"] + } + }, + "it": { + "plural-forms": "nplurals=2; plural=(n != 1);", + "messages": { + "Hello World": ["Buongiorno il mondo"], + 'Browser language is "{lang}".': ['La lingua del browser è "{lang}".'], + "Close": ["Chiudere"] + } + } +}); +tr.locale = tr.guessUserLanguage(); // Browser language + +// Language selector +var layout = new photonui.BoxLayout({ + orientation: "vertical", + children: [ + new photonui.Label({ + text: _('Browser language is "{lang}".', { + lang: tr.guessUserLanguage() + }) + }), + new photonui.Select({ + name: "lang", + placeholder: "Choose a language...", + value: tr.locale, + children: [ + new photonui.MenuItem({value: "en", text: "English"}), + new photonui.MenuItem({value: "fr", text: "Français"}), + new photonui.MenuItem({value: "it", text: "Italiano"}), + ], + callbacks: { + "value-changed": function(widget: any, value: any) { + tr.locale = value; + } + } + }) + ] +}); +photonui.domInsert(layout, "demo"); + +// A window +var pos = photonui.Helpers.getAbsolutePosition("demo"); +var win = new photonui.Window({ + visible: true, + title: _("Hello World"), + x: pos.x, y: pos.y + 100, + width: 250, + padding: 20, + child: new photonui.Button({ + text: _("Close"), + callbacks: { + "click": function() { win.hide(); } + } + }), + callbacks: { + "close-button-clicked": function(widget: any) { widget.hide(); } + } +}); + +// Viewport +var viewport = new photonui.Viewport({ + width: 300, + height: 200, + padding: 5, + horizontalScrollbar: false, // true, false or null (= auto) + verticalScrollbar: null, // true, false or null (= auto) + child: new photonui.BoxLayout({ + children: [ + new photonui.Button(), + new photonui.Button(), + new photonui.Button(), + new photonui.Button(), + new photonui.Button(), + new photonui.Button(), + new photonui.Button(), + new photonui.Button(), + new photonui.Button(), + new photonui.Button() + ] + }) +}); + +photonui.domInsert(viewport, "demo"); + +// Window +var pos = photonui.Helpers.getAbsolutePosition("demo"); + +new photonui.Window({ + title: "My Window", + visible: true, + x: pos.x, y: pos.y, + width: 300, height: 100, + callbacks: { + "close-button-clicked": function(widget: any) { + widget.destroy(); + }, + "position-changed": function(widget: any, x: number, y: number) { + widget.title = "My Window (x: " + x + ", y: " + y + ")"; + } + } +}); + +// Get the position of the #demo area to display windows +// in the right place +var pos = photonui.Helpers.getAbsolutePosition("demo"); + +// Create a window with a button to center it (x axis) on the page +var win1 = new photonui.Window({ + title: "Window 1", + visible: true, + padding: 10, + x: pos.x + 20, y: pos.y + 50, + child: new photonui.Button({ + text: "Center Me", + callbacks: { + click: function(widget: any, event: any) { + win1.center(); + win1.y = pos.y; + } + } + }), + callbacks: { + "close-button-clicked": function(widget: any) { + widget.destroy(); + } + } +}); + +// Create a second window without "close" button +var win2 = new photonui.Window({ + title: "Window 2", + visible: true, + height: 100, + closeButtonVisible: false, + x: pos.x, y: pos.y +}); + +// Focus the first window +win1.show(); diff --git a/photonui/photonui.d.ts b/photonui/photonui.d.ts new file mode 100644 index 000000000..973b241bd --- /dev/null +++ b/photonui/photonui.d.ts @@ -0,0 +1,435 @@ +// Type definitions for PhotonUI v1.0.0 +// Project: https://github.com/wanadev/PhotonUI +// Definitions by: Florent Poujol +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +declare module photonui { + // Base + module Helpers { + function escapeHtml(string: string): void; + function uuid4(): string; + function cleanNode(node: HTMLElement): void; + function getAbsolutePosition(element: HTMLElement|string): { x: number; y: number }; + function numberToCssSize(value: number, defaultValue?: number, nullValue?: string): string; + } + + class Base { + constructor(params?: { [key: string]: any }); + destroy(): void; + registerCallback(id: string, wEvent: string, callback: Function, thisArg: any): void; + removeCallback(id: string): void; + } + + class Widget extends Base { + absolutePosition: { x: number; y: number; }; // readonly + contextMenu: PopupWindow; + contextMenuName: string; + html: HTMLElement; // readonly + layoutOptions: { [key: string]: any }; + name: string; + offsetWidth: number; // readonly + offsetHeight: number; // readonly + parent: Widget; + parentName: string; + tooltip: string; + visible: boolean; + + show(): void; + hide(): void; + unparent(): void; + addClass(className: string): void; + removeClass(className: string): void; + + static getWidget(name: string): Widget; + static domInsert(widget: Widget, element?: HTMLElement|string): void; + } + + // Methods + function domInsert(widget: Widget, element?: HTMLElement|string): void; + function getWidget(name: string): Widget; + + //Widgets + class FileManager extends Base { + acceptedExts: string[]; + acceptedMimes: string[]; + dropZone: HTMLElement; + multiselect: boolean; + + open(): void; + } + + class Translation extends Base { + locale: string; + + addCatalogs(catalogs: { [key: string]: any }): void; + guessUserLanguage(): string; + gettext(string: string, replacements?: { [key: string]: string }): string; + lazyGettext(string: string, replacements?: { [key: string]: string }): string; + enableDomScan(enable: boolean): void; + updateDomTranslation(): void; + } + + class AccelManager extends Base { + addAccel(id: string, keys: string, callback: Function, safe?: boolean): void; + removeAccel(id: string): void; + } + + class MouseManager extends Base { + constructor(params?: { [key: string]: any }); + constructor(element?: Widget|HTMLElement, params?: { [key: string]: any }); + + element: HTMLElement; + threshold: number; + + action: string; // readonly + btnLeft: boolean; // readonly + btnMiddle: boolean; // readonly + btnRight: boolean; // readonly + button: string; // readonly + pageX: number; // readonly + pageY: number; // readonly + x: number; // readonly + y: number; // readonly + deltaX: number; // readonly + deltaY: number; // readonly + } + + // ----------------------------------- + + class BaseIcon extends Widget {} + + class FAIcon extends BaseIcon { + constructor(params?: { [key: string]: any }); + constructor(name: string, params?: { [key: string]: any }); + + color: string; + iconName: string; + size: string; + } + + class SpriteIcon extends BaseIcon { + constructor(params?: { [key: string]: any }); + constructor(name: string, params?: { [key: string]: any }); + + icon: string; + iconName: string; + spriteSheetName: string; + } + + // ----------------------------------- + + class Image extends Widget { + width: number; + height: number; + url: string; + } + + class SpriteSheet extends Base { + name: string; + imageUrl: string; + size: string; + icons: { [iconName: string]: number[] }; + + addIcon(iconName: string, x: number, y: number): void; + removeIcon(iconName: string): void; + getIconPosition(iconName: string): { x: number; y: number; }; + getIconCSS(iconName: string): string; + + static getSpriteSheet(name: string): SpriteSheet; + } + + class Canvas extends Widget { + canvas: HTMLElement; + interactiveMode: HTMLElement; + width: number; + height: number; + getContext(contextId: string): any; + setContext(contextId: string): void; + supportsContext(contextId: string): boolean; + toBlod(imageFormat: string): any; // returns Blob + toBlodHD(imageFormat: string): any; // returns Blob + toDataUrl(imageFormat: string): string; + toDataUrlHD(imageFormat: string): string; + transferControlToProxy(): void; + } + + class Label extends Widget { + constructor(params?: { [key: string]: any }); + constructor(name: string, params?: { [key: string]: any }); + + forInput: Field|CheckBox; + forInputName: string; + text: string; + textAlign: string; + } + + class Text extends Widget { + rawHtml: string; + text: string; + } + + class ProgressBar extends Widget { + orientation: string; + pulsate: boolean; + textVisible: boolean; + value: number; + } + + class Separator extends Widget { + orientation: string; + } + + class Button extends Widget { + appearance: string; // normal | flat + buttonColor: string; + + leftIconName: string; + leftIcon: BaseIcon; + leftIconVisible: boolean; + + rightIconName: string; + rightIcon: BaseIcon; + rightIconVisible: boolean; + + text: string; + textVisible: boolean; + } + + class ColorButton extends Widget { + color: Color; + dialogOnly: boolean; + value: string; + } + + class CheckBox extends Widget { + value: boolean; + } + class Switch extends CheckBox {} + class ToggleButton extends CheckBox {} + + // ----------------------------------- + + class Color extends Base { + constructor(color: string); + constructor(params?: { [key: string]: any }); + + hexString: string; + rgbString: string; // readonly + rgbaString: string; // readonly + + red: number; + green: number; + blue: number; + alpha: number; + + hue: number; + saturation: number; + brightness: number; + + setRGB(red: number, green: number, blue: number): void; + getRGB(): number[]; + setRGBA(red: number, green: number, blue: number, alpha: number): void; + getRGBA(): number[]; + setHSB(hue: number, saturation: number, brightness: number): void; + } + + class ColorPalette extends Widget { + color: Color; + palette: Array; + value: string; + + static palette: Array; + } + + class ColorPicker extends Widget { + color: Color; + value: string; + } + + // ----------------------------------- + + class Field extends Widget { + placeholder: string; + value: boolean; + } + + class NumericField extends Field { + min: number; + max: number; + step: number; + decimalDigits: number; + decimalSymbol: string; + } + + class Slider extends NumericField { + fieldVisible: boolean; + } + + class TextAreaField extends Field { + cols: number; + rows: number; + } + + class TextField extends Field { + type: string; // text, password, email, search, tel, url + } + + // ----------------------------------- + + class Select extends Widget { + children: Widget[]; + childrenNames: string[]; + iconVisible: boolean; + placeholder: string; + popupWidth: number; + popupHeight: number; + popupMaxWidth: number; + popupMinWidth: number; + popupMaxHeight: number; + popupMinHeight: number; + popupOffsetWidth: number; // readonly + popupOffsetHeight: number; // readonly + popupPadding: number; + value: any; // string (maybe) + + addChild(widget: Widget, layoutOptions?: any): void; + } + + class FontSelect extends Select { + fonts: string[]; + + addFont(fontName: string): void; + } + + // ----------------------------------- + + class Container extends Widget { + child: Widget; + childName: string; + containerNode: HTMLElement; // readonly + horizontalChildExpansion: boolean; + verticalChildExpansion: boolean; + + removeChild(widget: Widget): void; + } + + class Layout extends Container { + children: Widget[]; + childrenNames: string[]; + + addChild(widget: Widget, layoutOptions?: { [key: string]: any }): void; + empty(): void; + } + + class BoxLayout extends Layout { + horizontalPadding: number; + verticalPadding: number; + orientation: string; + spacing: number; + } + + class FluidLayout extends Layout { + horizontalPadding: number; + verticalPadding: number; + } + + class GridLayout extends Layout { + horizontalPadding: number; + verticalPadding: number; + horizontalSpacing: number; + verticalSpacing: number; + } + + class Menu extends Layout { + iconVisible: boolean; + } + + class MenuItem extends Menu { + active: boolean; + icon: BaseIcon; + iconName: string; + text: string; + value: any; // string (maybe) + } + + class SubMenuItem extends MenuItem { + menu: Menu; + menuName: string; + } + + // ----------------------------------- + + class Viewport extends Container { + width: number; + minWidth: number; + maxWidth: number; + height: number; + minHeight: number; + maxHeight: number; + padding: number; + horizontalScrollbar: boolean; + verticalScrollbar: boolean; + } + + // ----------------------------------- + + class BaseWindow extends Container { + width: number; + minWidth: number; + maxWidth: number; + height: number; + minHeight: number; + maxHeight: number; + padding: number; + position: { x: number; y: number }; + x: number; + y: number; + + center(): void; + } + + class PopupWindow extends BaseWindow { + popupXY(x: number, y: number): void; + popupWidget(widget: Widget): void; + } + + class PopupMenu extends PopupWindow {} + + class Window extends BaseWindow { + closeButtonVisible: boolean; + modal: boolean; + movable: boolean; + title: string; + + moveToFront(): void; + moveToBack(): void; + } + + class Dialog extends Window { + buttons: Widget[]; + buttonNames: string[]; + + addButton(widget: Widget, layoutOptions: any): void; + removeButton(widget: Widget): void; + } + + class ColorPickerDialog extends Dialog { + color: Color; + } + + // ----------------------------------- + + class TabItem extends Container { + tabHtml: HTMLElement; // readonly + title: string; + } + + class TabLayout extends Layout { + activeTab: Widget; + activeTabName: string; + padding: number; + tabsPosition: string; // top, bottom, left, right + } +} + +declare function _(string: string, replacements?: { [key: string]: string }): string; // alias of Translation.lazyGettext()