Added minimal functionality for Robot teaching

- Added minimal HMI
- Added possibility to open and close all chamber doors
This commit is contained in:
2026-01-17 09:20:39 +01:00
parent 9f058db2a3
commit 2d11c43579
2274 changed files with 912690 additions and 162 deletions

View File

@@ -0,0 +1,274 @@
{
"$schema": "../../TcHmiFramework/Schema/ControlDescription.Schema.json",
"apiVersion": 1,
"name": "TcHmiRecipeSelect",
"namespace": "TcHmi.Controls.Beckhoff",
"displayName": "Recipe Select",
"version": {
"full": "14.4.1.0",
"major": 14,
"minor": 4,
"build": 1,
"revision": 0
},
"visible": true,
"themeable": "Standard",
"base": "TcHmi.Controls.System.TcHmiControl",
"description": "A control to select recipes at runtime",
"defaultDesignerEvent": "",
"properties": {
"containerControl": false,
"geometry": {
"width": 350,
"height": 101
}
},
"icons": [
{
"name": "Icons/16x16.png",
"width": 16,
"height": 16
}
],
"template": "Template.html",
"dependencyFiles": [
{
"name": "Style.css",
"type": "Stylesheet",
"description": ""
},
{
"name": "../dist/TcHmiRecipeSelect/TcHmiRecipeSelect.esm.js",
"type": "EsModule",
"description": "Contains all the main logic as ES module."
}
],
"themes": {
"Base": {
"resources": [
{
"name": "Themes/Base/Style.css",
"type": "Stylesheet",
"description": ""
}
]
},
"Base-Dark": {
"resources": [
{
"name": "Themes/Base-Dark/Style.css",
"type": "Stylesheet",
"description": ""
}
]
}
},
"attributes": [
{
"name": "data-tchmi-server-domain",
"propertyName": "ServerDomain",
"propertySetterName": "setServerDomain",
"propertyGetterName": "getServerDomain",
"displayName": "Server Domain",
"visible": true,
"displayPriority": 100,
"type": "tchmi:general#/definitions/String",
"category": "Common",
"themeable": "Advanced",
"description": "The domain of the recipe management extension in the server. Defaults to 'TcHmiRecipeManagement'.",
"readOnly": false,
"bindable": true,
"defaultBindingMode": "OneWay",
"heritable": true,
"defaultValue": null,
"defaultValueInternal": "TcHmiRecipeManagement"
},
{
"name": "data-tchmi-server-interval",
"propertyName": "ServerInterval",
"propertySetterName": "setServerInterval",
"propertyGetterName": "getServerInterval",
"displayName": "Server Interval",
"visible": true,
"displayPriority": 100,
"type": "tchmi:general#/definitions/Number",
"category": "Common",
"themeable": "Advanced",
"description": "Sets the interval for the subscription to the Config::recipeList and GetActiveRecipes symbols of the configured server domain in milliseconds. This might be expensive performance wise, so do not set to a very low value.",
"readOnly": false,
"bindable": true,
"defaultBindingMode": "OneWay",
"heritable": true,
"defaultValue": 1000,
"defaultValueInternal": null
},
{
"name": "data-tchmi-selected-recipe-full-name",
"propertyName": "SelectedRecipeFullName",
"propertyGetterName": "getSelectedRecipeFullName",
"displayName": "Selected Recipe Full Name",
"visible": true,
"displayPriority": 100,
"type": "tchmi:general#/definitions/String",
"category": "Common",
"description": "The full name of the selected recipe",
"readOnly": true,
"bindable": false,
"defaultBindingMode": "OneWay",
"heritable": true
},
{
"name": "data-tchmi-selected-recipe-name",
"propertyName": "SelectedRecipeName",
"propertyGetterName": "getSelectedRecipeName",
"displayName": "Selected Recipe Name",
"visible": true,
"displayPriority": 100,
"type": "tchmi:general#/definitions/String",
"category": "Common",
"description": "The name of the selected recipe",
"readOnly": true,
"bindable": false,
"defaultBindingMode": "OneWay",
"heritable": true
},
{
"name": "data-tchmi-selected-recipe-path",
"propertyName": "SelectedRecipePath",
"propertyGetterName": "getSelectedRecipePath",
"displayName": "Selected Recipe Path",
"visible": true,
"displayPriority": 100,
"type": "tchmi:general#/definitions/String",
"category": "Common",
"description": "The path of the selected recipe",
"readOnly": true,
"bindable": false,
"defaultBindingMode": "OneWay",
"heritable": true
},
{
"name": "data-tchmi-allowed-recipe-types",
"propertyName": "AllowedRecipeTypes",
"propertySetterName": "setAllowedRecipeTypes",
"propertyGetterName": "getAllowedRecipeTypes",
"displayName": "Allowed Recipe Types",
"visible": true,
"displayPriority": 12,
"type": "tchmi:framework#/definitions/TcHmi.Controls.Beckhoff.TcHmiRecipeSelect.NameArray",
"category": "Common",
"themeable": "Advanced",
"description": "Which recipe types are allowed. Recipes that are based on other types are hidden.\nIf not set, or set to an empty array, recipes of all types will be shown.",
"readOnly": false,
"bindable": true,
"defaultBindingMode": "OneWay",
"heritable": true,
"allowSymbolExpressionsInObject": true,
"defaultValue": null,
"defaultValueInternal": null
},
{
"name": "data-tchmi-prompt-before-activating",
"propertyName": "PromptBeforeActivating",
"propertySetterName": "setPromptBeforeActivating",
"propertyGetterName": "getPromptBeforeActivating",
"displayName": "Prompt Before Activating",
"visible": true,
"displayPriority": 15,
"type": "tchmi:general#/definitions/Boolean",
"category": "Common",
"themeable": "Advanced",
"description": "Whether to display a popup asking the user for confirmation before activating a recipe.",
"readOnly": false,
"bindable": true,
"defaultBindingMode": "OneWay",
"heritable": true,
"defaultValue": null,
"defaultValueInternal": false
},
{
"name": "data-tchmi-prompt-before-teaching",
"propertyName": "PromptBeforeTeaching",
"propertySetterName": "setPromptBeforeTeaching",
"propertyGetterName": "getPromptBeforeTeaching",
"displayName": "Prompt Before Teaching",
"visible": true,
"displayPriority": 16,
"type": "tchmi:general#/definitions/Boolean",
"category": "Common",
"themeable": "Advanced",
"description": "Whether to display a popup asking the user for confirmation before teaching a recipe.",
"readOnly": false,
"bindable": true,
"defaultBindingMode": "OneWay",
"heritable": true,
"defaultValue": null,
"defaultValueInternal": false
}
],
"attributeCategories": [],
"functions": [],
"events": [
{
"name": ".onRecipeActivated",
"displayName": ".onRecipeActivated",
"visible": true,
"displayPriority": 6,
"category": "Operator",
"description": "The onRecipeActivated event is fired when the selected recipe is activated.",
"heritable": true,
"arguments": [
{
"type": "tchmi:framework#/definitions/TcHmiRecipeSelectRecipeNameEventObject",
"description": "The event object containing information about the recipe name."
}
]
},
{
"name": ".onRecipeTaught",
"displayName": ".onRecipeTaught",
"visible": true,
"displayPriority": 6,
"category": "Operator",
"description": "The onRecipeTaught event is fired when the selected recipe is taught.",
"heritable": true,
"arguments": [
{
"type": "tchmi:framework#/definitions/TcHmiRecipeSelectRecipeNameEventObject",
"description": "The event object containing information about the recipe name."
}
]
}
],
"access": [
{
"name": "activateRecipe",
"displayName": "Activate Recipe",
"description": "Controls the ability to activate the selected recipe. This defaults to true.",
"visible": true,
"defaultValueInternal": true,
"dependsOn": [
"operate"
]
},
{
"name": "teachRecipe",
"displayName": "Teach Recipe",
"description": "Controls the ability to teach the selected recipe. This defaults to true.",
"visible": true,
"defaultValueInternal": true,
"dependsOn": [
"operate"
]
}
],
"dataTypes": [
{
"schema": "Schema/Types.Schema.json"
}
],
"languages": {
"en": "Lang/Language.en.json",
"de": "Lang/Language.de.json"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

View File

@@ -0,0 +1,23 @@
{
"$schema": "../../../TwinCAT-HMI-Common/JsonSchemas/Language.Schema.json",
"locale": "de",
"localizedText": {
"Label_Text_Select": "Auswählen",
"Header_Recipes": "Rezepte",
"Button_Text_Activate": "Aktivieren",
"Button_Tooltip_Activate": "Rezept aktivieren",
"Button_Tooltip_Activate_MissingSymbolAccess": "Rezept aktivieren. Sie benötigen Schreibzugriff auf das 'ActivateRecipe' Symbol der Rezeptverwaltung",
"Button_Text_Teach": "Anlernen",
"Button_Tooltip_Teach": "Rezept anlernen",
"Button_Tooltip_Teach_MissingSymbolAccess": "Rezept anlernen. Sie benötigen Schreibzugriff auf die 'Config', 'ReadFromTarget' und 'UpdateRecipe' Symbole der Rezeptverwaltung",
"Button_Text_Ok": "OK",
"Button_Text_Cancel": "Abbrechen",
"Popup_Button_Text_Yes": "Ja",
"Popup_Button_Text_No": "Nein",
"Popup_Header_ConfirmActivate": "Aktivieren",
"Popup_Text_ConfirmActivate": "Sind Sie sicher, dass Sie dieses Rezept aktivieren wollen?\nDies wird alle im Rezept enthaltenen Variablen in die SPS schreiben.",
"Popup_Header_ConfirmTeach": "Anlernen",
"Popup_Text_ConfirmTeach": "Sind Sie sicher, dass Sie dieses Rezept anlernen wollen?\nDies wird alle Rezeptvariablen mit den aktuellen Werten aus der PLC überschreiben.",
"Popup_Text_NoRecipes": "Keine Rezepte verfügbar."
}
}

View File

@@ -0,0 +1,23 @@
{
"$schema": "../../../TwinCAT-HMI-Common/JsonSchemas/Language.Schema.json",
"locale": "en",
"localizedText": {
"Label_Text_Select": "Select",
"Header_Recipes": "Recipes",
"Button_Text_Activate": "Activate",
"Button_Tooltip_Activate": "Activate recipe",
"Button_Tooltip_Activate_MissingSymbolAccess": "Activate recipe. You need write access to the 'ActivateRecipe' symbol of the recipe management domain for this",
"Button_Text_Teach": "Teach",
"Button_Tooltip_Teach": "Teach recipe",
"Button_Tooltip_Teach_MissingSymbolAccess": "Teach recipe. You need write access to the 'Config', 'ReadFromTarget' and 'UpdateRecipe' symbols of the recipe management domain for this",
"Button_Text_Ok": "OK",
"Button_Text_Cancel": "Cancel",
"Popup_Button_Text_Yes": "Yes",
"Popup_Button_Text_No": "No",
"Popup_Header_ConfirmActivate": "Activating",
"Popup_Text_ConfirmActivate": "Are you sure you want to activate this recipe?\nThis will write all variables contained in the recipe to the PLC.",
"Popup_Header_ConfirmTeach": "Teaching",
"Popup_Text_ConfirmTeach": "Are you sure you want to teach this recipe?\nThis will overwrite all recipe variables with the current values from the PLC.",
"Popup_Text_NoRecipes": "No recipes available."
}
}

View File

@@ -0,0 +1,34 @@
{
"$schema": "http://json-schema.org/draft-04/schema",
"definitions": {
"TcHmi.Controls.Beckhoff.TcHmiRecipeSelect": {
"$schema": "http://json-schema.org/draft-04/schema",
"type": "object",
"frameworkInstanceOf": "TcHmi.Controls.System.TcHmiControl",
"frameworkControlType": "TcHmiRecipeSelect",
"frameworkControlNamespace": "TcHmi.Controls.Beckhoff"
},
"TcHmi.Controls.Beckhoff.TcHmiRecipeSelect.NameArray": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
},
"TcHmiRecipeSelect": {
"$ref": "tchmi:framework#/definitions/TcHmi.Controls.Beckhoff.TcHmiRecipeSelect"
},
"TcHmi.Controls.Beckhoff.TcHmiRecipeSelect.RecipeNameEventObject": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"additionalProperties": false
},
"TcHmiRecipeSelectRecipeNameEventObject": {
"$ref": "tchmi:framework#/definitions/TcHmi.Controls.Beckhoff.TcHmiRecipeSelect.RecipeNameEventObject"
}
}
}

View File

@@ -0,0 +1,78 @@
/** Styles for all themes */
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect {
overflow: hidden;
container: control / size;
}
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect .TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-template {
position: relative;
width: 100%;
height: 100%;
padding: 10px;
}
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect .TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-buttons {
display: flex;
gap: 5px;
}
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-buttons
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-selected-recipe {
height: 35px;
flex-grow: 1;
padding: 0 3px;
box-sizing: border-box;
line-height: 35px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-buttons
.TcHmi_Controls_Beckhoff_TcHmiButton {
position: relative;
min-width: 75px;
height: 35px;
}
@container control (width < 300px) {
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect .TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-buttons {
flex-wrap: wrap;
}
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-buttons
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-selected-recipe {
width: 100%;
}
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-buttons
.TcHmi_Controls_Beckhoff_TcHmiButton {
flex-grow: 1;
}
}
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect .TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-path-box {
margin-top: 10px;
}
.TcHmi_Controls_Helpers_Popup-SelectRecipePrompt .TcHmi_Controls_Helpers_Popup-content {
width: 600px;
height: 400px;
}
.TcHmi_Controls_Helpers_Popup-SelectRecipePrompt .TcHmi_Controls_Helpers_Popup-content .empty-notification {
position: absolute;
top: 0;
left: 0;
right: 0;
padding-top: 10px;
}
.TcHmi_Controls_Helpers_Popup-SelectRecipePrompt .TcHmi_Controls_Helpers_Popup-content .empty-notification:not(.show) {
display: none;
}

View File

@@ -0,0 +1,347 @@
// Compatibility file for non-module typescript compiles without adjustments.
// Use the following line for modern code (needs adjustments to tsconfig.json#configOptions/paths)
// import { TcHmiControl } from "Beckhoff.TwinCAT.HMI.Framework/index.esm.js";
// ***************************************************************************
declare class TcHmiRecipeSelect extends TcHmi.Controls.System.TcHmiControl {
#private;
/**
* Constructor Creates a new control instance.
* @param element The element that hosts the control.
* @param pcElement Precompiled element.
* @param attrs The control attributes.
*/
constructor(element: JQuery, pcElement: JQuery, attrs: TcHmi.Controls.ControlAttributeList);
protected __elementTemplateRoot: HTMLElement;
protected __elementSelectedRecipe: HTMLElement;
protected __elementPathBox: HTMLDivElement;
protected __buttonActivate: TcHmiButton;
protected __buttonTeach: TcHmiButton;
protected __selectRecipePrompt: SelectRecipePrompt;
protected __serverDomain: string | undefined;
protected __serverInterval: number | undefined;
protected __allowedRecipeTypes: string[] | null | undefined;
protected __promptBeforeActivating: boolean | undefined;
protected __promptBeforeTeaching: boolean | undefined;
protected __confirmationPrompt: TextAndButtonsPrompt<boolean> | null;
protected __unwatchRecipeList: TcHmi.DestroyFunction | null;
protected __unwatchRecipeManagementDomain: TcHmi.DestroyFunction | null;
protected __watchRecipeConditions: {
extensionLoaded: boolean;
userHasRights: boolean;
};
protected __activeRecipesSubscriptionId: number | null;
protected __watchActiveRecipeConditions: {
extensionLoaded: boolean;
userHasRights: boolean;
};
protected __symbolAccessSubscriptionId: number | null;
protected __symbolAccess: {
'{0}.Config': import("Beckhoff.TwinCAT.HMI.Framework/dist/API/Server.js").ACCESS;
'{0}.ActivateRecipe': import("Beckhoff.TwinCAT.HMI.Framework/dist/API/Server.js").ACCESS;
'{0}.ReadFromTarget': import("Beckhoff.TwinCAT.HMI.Framework/dist/API/Server.js").ACCESS;
'{0}.UpdateRecipe': import("Beckhoff.TwinCAT.HMI.Framework/dist/API/Server.js").ACCESS;
'{0}.GetActiveRecipes': import("Beckhoff.TwinCAT.HMI.Framework/dist/API/Server.js").ACCESS;
};
protected __selectedRecipe: TcHmi.ObjectPath | null;
protected __isEnabledLock: {
locked: boolean;
unlockValue: boolean | null;
};
protected __localizedElements: Map<HTMLElement, {
key: string;
parameters?: any[];
}>;
protected __localizationReader: TcHmi.Locale.LocalizationReader | undefined;
/**
* If raised, the control object exists in control cache and constructor of each inheritation level was called.
* This function is only to be used by the System. Other function calls are not intended.
*/
__previnit(): void;
/**
* If raised, all attributes have been set to it's default or dom values.
* This function is only to be used by the System. Other function calls are not intended.
*/
__init(): void;
/**
* Is called by the system after the control instance gets part of the current DOM.
* This function is only to be used by the System. Other function calls are not intended.
*/
__attach(): void;
/**
* Is called by the system after the control instance is no longer part of the current DOM.
* This function is only to be used by the System. Other function calls are not intended.
*/
__detach(): void;
/**
* Destroy the current control instance.
* Will be called automatically if system destroys control!
*/
destroy(): void;
/**
* Add an element to be localized.
* @param element The element.
* @param key The localization key.
* @param parameters Optional parameters to pass to tchmi_format_string.
*/
protected __addLocalizedElement(element: HTMLElement, key: string, ...parameters: any[]): void;
/**
* Remove a localized element.
* @param element The element to remove.
*/
protected __removeLocalizedElement(element: HTMLElement): void;
/**
* Event handler for the click event of the selected recipe element and the path box.
* @param _event The event to handle.
*/
protected __onRecipeClick(_event: MouseEvent): Promise<void>;
/**
* Selects the recipe with the given name.
* @param fullName The path and name of the recipe to select.
*/
protected __select(fullName: string): void;
/**
* Unselects the currently selected recipe.
*/
protected __unselect(): void;
/**
* Returns a TextAndButtonsPrompt with a yes and a no button.
* @param headerKey The localization key for the header text.
* @param contentKey The localization key for the content text.
*/
protected __getConfirmationPrompt(headerKey: string, contentKey: string): TextAndButtonsPrompt<boolean>;
/**
* Event handler for the onPressed event of the activate button.
*/
protected __onActivatePressed(): Promise<void>;
/**
* Event handler for the onPressed event of the teach button.
*/
protected __onTeachPressed(): Promise<void>;
/**
* Sets the current value of attribute ServerDomain.
* @param valueNew
*/
setServerDomain(valueNew: string | null): void;
/**
* Returns the current value of attribute ServerDomain.
*/
getServerDomain(): string | undefined;
/**
* Processes the current value of attribute ServerDomain.
*/
protected __processServerDomain(): void;
/**
* Sets the current value of attribute ServerInterval.
* @param valueNew
*/
setServerInterval(valueNew: number | null): void;
/**
* Returns the current value of attribute ServerInterval.
*/
getServerInterval(): number | undefined;
/**
* Processes the current value of attribute ServerInterval.
*/
protected __processServerInterval(): void;
/**
* Returns the current value of attribute SelectedRecipeFullName.
*/
getSelectedRecipeFullName(): string | null;
/**
* Returns the current value of attribute SelectedRecipeName.
*/
getSelectedRecipeName(): string | null;
/**
* Returns the current value of attribute SelectedRecipePath.
*/
getSelectedRecipePath(): string | null;
/**
* Sets the current value of attribute AllowedRecipeTypes.
* @param valueNew The new value.
*/
setAllowedRecipeTypes(valueNew: string[] | null): void;
/**
* The watch callback for the AllowedRecipeTypes object resolver
*/
protected __onResolverForAllowedRecipeTypesWatchCallback(data: TcHmi.Symbol.ObjectResolver.IWatchResultObject<string[]>): void;
/**
* Returns the current value of attribute AllowedRecipeTypes.
*/
getAllowedRecipeTypes(): string[] | null | undefined;
/**
* Processes the current value of attribute AllowedRecipeTypes.
*/
protected __processAllowedRecipeTypes(): void;
/**
* Sets the current value of attribute PromptBeforeActivating.
* @param valueNew
*/
setPromptBeforeActivating(valueNew: boolean | null): void;
/**
* Returns the current value of attribute PromptBeforeActivating.
*/
getPromptBeforeActivating(): boolean | undefined;
/**
* Sets the current value of attribute PromptBeforeTeaching.
* @param valueNew
*/
setPromptBeforeTeaching(valueNew: boolean | null): void;
/**
* Returns the current value of attribute PromptBeforeTeaching.
*/
getPromptBeforeTeaching(): boolean | undefined;
/**
* Updates the RecipeManagementDomainWatch. Also unwatches the recipe list watch.
* @param unwatchOnly Set to true to only destroy the existing watch. Defaults to false.
*/
protected __updateRecipeWatches(unwatchOnly?: boolean): void;
/**
* Lock the isEnabled state to false.
*/
protected __lockIsEnabled(): void;
/**
* Unlock the isEnabled state and apply the stored unlockValue.
*/
protected __unlockIsEnabled(): void;
/**
* Sets the value of attribute IsEnabled.
*/
setIsEnabled(valueNew: boolean | null): void;
/**
* Updates the recipe list watch, if the recipe extension is loaded and the user has the necessary access rights.
* @param extensionLoaded Whether the recipe extension is loaded.
* @param userHasRights Whether the user has the necessary access rights.
*/
protected __updateRecipeListWatch(extensionLoaded: boolean | null, userHasRights: boolean | null): void;
/**
* Callback function for TcHmi.Server.RecipeManagement.watchRecipeList.
* @param data The recipes.
*/
protected __onRecipeListWatch(data: TcHmi.Server.RecipeManagement.IWatchResultObject<TcHmi.Server.RecipeManagement.FolderRecipe>): void;
/**
* Update the subscription to GetActiveRecipes.
* @param unsubscribeOnly Only unsubscribe. Should be used on detach.
*/
protected __updateActiveRecipesSubscription(extensionLoaded: boolean | null, userHasRights: boolean | null, recipeChanged?: boolean): void;
/**
* Update the subscription to GetSymbolAccess.
* @param unsubscribeOnly Only unsubscribe. Should be used on detach.
*/
protected __updateSymbolAccessSubscription(unsubscribeOnly?: boolean): void;
/**
* Forces the buttons operate rights to Deny if the user doesn't have the necessary symbol TcHmi.Access.
*/
protected __updateButtonAccess(): void;
/**
* Expands the given localization key to a full symbol expression.
* @param key The key to expand.
*/
protected __expandLocalizationSymbol(key: string): string;
}
export { TcHmiRecipeSelect as Control };
declare const _TcHmiRecipeSelect: typeof TcHmiRecipeSelect;
type tTcHmiRecipeSelect = TcHmiRecipeSelect;
declare global {
namespace TcHmi.Controls.Beckhoff {
const TcHmiRecipeSelect: typeof _TcHmiRecipeSelect;
type TcHmiRecipeSelect = tTcHmiRecipeSelect;
}
}
export declare class SelectRecipePrompt extends OkCancelPrompt<{
name: string;
recipe: TcHmi.Server.RecipeManagement.Recipe;
}> {
#private;
protected __parentControl: TcHmi.Controls.System.TcHmiControl;
protected __recipeBrowser: DirectoryBrowser<TcHmi.Server.RecipeManagement.Recipe, TcHmi.Server.RecipeManagement.FolderRecipe>;
protected __initialPath: string[] | null;
protected __emptyNotification: HTMLDivElement;
/**
* Creates a new SelectRecipePrompt instance.
* @param pathDisplay The display to show the currently chosen path in.
* @param parentControl The control which owns the popup.
*/
constructor(pathDisplay: PathDisplay, parentControl: TcHmiRecipeSelect);
/**
* Handler for the PathChanged event of the recipe type browser.
* @param currentItem The current item.
* @param path The path to the current item.
*/
protected __onPathChanged(currentItem: DirectoryBrowser.Item<TcHmi.Server.RecipeManagement.Recipe, TcHmi.Server.RecipeManagement.FolderRecipe> | null, _path: string[] | null): void;
/**
* Handler for the SelectionChanged event of the recipe type browser.
* @param selectedItem The selected item, or null if nothing is selected.
* @param path The current path.
* @param selectedItemName The name of the selected item, or null if nothing is selected.
*/
protected __onSelectionChanged(selectedItems: DirectoryBrowser.DescendantItem<TcHmi.Server.RecipeManagement.Recipe, TcHmi.Server.RecipeManagement.FolderRecipe>[] | null): void;
/**
* Destroys the popup and all its controls.
* @param force If true, child controls will be removed from the parent control before destruction, to ensure destruction in case of keepAlive === true.
*/
destroy(force?: boolean): void;
/**
* Suspends the RecipeBrowser of this popup.
*/
suspend(): void;
/**
* Resumes the RecipeBrowser of this popoup.
*/
resume(): void;
/**
* Sets the path of the RecipeBrowser to the specified value.
* @param value The path.
*/
setPath(value: string[]): Promise<{
name: string;
recipe: import("Beckhoff.TwinCAT.HMI.Framework/dist/API/Server.RecipeManagement.js").Recipe;
} | null>;
/**
* Sets the path of the RecipeBrowser to the root directory.
*/
reset(): void;
/**
* Callback function for TcHmi.Server.RecipeManagement.watchRecipeList.
* @param data The recipes.
*/
setRecipeList(rootDirectory: TcHmi.Server.RecipeManagement.FolderRecipe | null): void;
/**
* Performs the action for the OK button, i.e. calling prompt.answer(). Must be implemented by inheriting class.
*/
protected __ok(): Promise<void>;
/**
* Performs the action for the Cancel button.
*/
protected __cancel(): void;
/**
* Shows the popup and waits for the user to answer the prompt. A Promise is returned that will be resolved with the value the user provides.
*/
prompt(): Promise<{
isOk: true;
value: {
name: string;
recipe: TcHmi.Server.RecipeManagement.Recipe;
};
} | {
isOk: false;
value?: void | undefined;
}>;
/**
* Sets localizable texts to the given localization symbols.
* @param texts A collection of localization symbol expressions.
*/
setTexts(texts: Partial<LocalizableTexts>): void;
}
export interface LocalizableTexts extends OkCancelPrompt.LocalizableTexts {
headerText: TcHmi.Localizable;
noRecipesText: TcHmi.Localizable;
}

View File

@@ -0,0 +1,59 @@
<div class="TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-template tchmi-box">
<div class="TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-buttons">
<div
class="TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-selected-recipe"
data-tchmi-localized-content-key="Label_Text_Select"
>
Label_Text_Select
</div>
<div
id="{Id}_ButtonActivate"
class="button-activate"
data-tchmi-type="TcHmi.Controls.Beckhoff.TcHmiButton"
data-tchmi-text="%l%Control::TcHmi.Controls.Beckhoff.TcHmiRecipeSelect::Button_Text_Activate%/l%"
data-tchmi-tooltip="%l%Control::TcHmi.Controls.Beckhoff.TcHmiRecipeSelect::Button_Tooltip_Activate%/l%"
data-tchmi-is-enabled="false"
>
<script data-tchmi-target-attribute="data-tchmi-virtual-control-right-mappings" type="application/json">
[{ "controlRight": "operate", "virtualControlRight": "activateRecipe" }]
</script>
<script data-tchmi-target-attribute="data-tchmi-text-padding" type="application/json">
{
"left": 3,
"right": 3,
"top": 3,
"bottom": 3,
"leftUnit": "px",
"rightUnit": "px",
"topUnit": "px",
"bottomUnit": "px"
}
</script>
</div>
<div
id="{Id}_ButtonTeach"
class="button-teach"
data-tchmi-type="TcHmi.Controls.Beckhoff.TcHmiButton"
data-tchmi-text="%l%Control::TcHmi.Controls.Beckhoff.TcHmiRecipeSelect::Button_Text_Teach%/l%"
data-tchmi-tooltip="%l%Control::TcHmi.Controls.Beckhoff.TcHmiRecipeSelect::Button_Tooltip_Teach%/l%"
data-tchmi-is-enabled="false"
>
<script data-tchmi-target-attribute="data-tchmi-virtual-control-right-mappings" type="application/json">
[{ "controlRight": "operate", "virtualControlRight": "teachRecipe" }]
</script>
<script data-tchmi-target-attribute="data-tchmi-text-padding" type="application/json">
{
"left": 3,
"right": 3,
"top": 3,
"bottom": 3,
"leftUnit": "px",
"rightUnit": "px",
"topUnit": "px",
"bottomUnit": "px"
}
</script>
</div>
</div>
<div class="TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-path-box"></div>
</div>

View File

@@ -0,0 +1,26 @@
/** Styles for the theme: Base-Dark */
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect {
--tchmi-control-background: var(--tchmi-background-color-1);
--tchmi-control-shadow: var(--tchmi-card-shadow);
--tchmi-selected-recipe-background: var(--tchmi-highlight-color-1);
--tchmi-selected-recipe-background-active: var(--tchmi-ready-color);
--tchmi-selected-recipe-text-color: var(--tchmi-foreground-color-1);
background: var(--tchmi-control-background);
box-shadow: var(--tchmi-control-shadow);
}
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-selected-recipe {
background-color: var(--tchmi-selected-recipe-background);
color: var(--tchmi-selected-recipe-text-color);
}
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-selected-recipe.active {
background-color: var(--tchmi-selected-recipe-background-active);
}
.TcHmi_Controls_Helpers_Popup-SelectRecipePrompt .TcHmi_Controls_Helpers_Popup-content .empty-notification {
font-style: italic;
text-align: center;
}

View File

@@ -0,0 +1,26 @@
/** Styles for the theme: Base */
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect {
--tchmi-control-background: var(--tchmi-background-color-1);
--tchmi-control-shadow: var(--tchmi-card-shadow);
--tchmi-selected-recipe-background: var(--tchmi-highlight-color-1);
--tchmi-selected-recipe-background-active: var(--tchmi-ready-color);
--tchmi-selected-recipe-text-color: var(--tchmi-foreground-color-2);
background: var(--tchmi-control-background);
box-shadow: var(--tchmi-control-shadow);
}
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-selected-recipe {
background-color: var(--tchmi-selected-recipe-background);
color: var(--tchmi-selected-recipe-text-color);
}
.TcHmi_Controls_Beckhoff_TcHmiRecipeSelect-selected-recipe.active {
background-color: var(--tchmi-selected-recipe-background-active);
}
.TcHmi_Controls_Helpers_Popup-SelectRecipePrompt .TcHmi_Controls_Helpers_Popup-content .empty-notification {
font-style: italic;
text-align: center;
}