diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index c8b7a286..143dd8b5 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -21,33 +21,17 @@ jobs: matrix: configuration: [Release] - runs-on: [ubuntu-latest] # For a list of available runner types, refer to + runs-on: [self-hosted, Windows, X64, L2] # For a list of available runner types, refer to # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on steps: - name: Checkout uses: actions/checkout@v3 with: - fetch-depth: '0' - - - name: "Setup the apax in the ci runner" - #uses: simatic-ax/actions/setup-apax-runner@main - uses: ./.github/actions/setup-apax-runner - with: - APAX_TOKEN: ${{ secrets.APAX_TOKEN }} - - - name: "Get github nuget source" - #uses: simatic-ax/actions/setup-apax-runner@main - run: sudo dotnet nuget add source --username ix-ax --password ${{ secrets.GH_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/ix-ax/index.json" - - - name: "login to apax" - run: sudo apax login -p ${{ secrets.APAX_TOKEN }} - shell: bash - + fetch-depth: '0' + - name: "Build script" - run: sudo dotnet build cake/Build.csproj - shell: bash - + run: dotnet build cake/Build.csproj + - name: "Run build script" - run: sudo dotnet run --project cake/Build.csproj --do-test true --do-pack true --test-level 1 - shell: bash + run: dotnet run --project cake/Build.csproj --do-test true --do-pack true --test-level 1 diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 1f94db2c..c9186aa9 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -21,7 +21,7 @@ jobs: matrix: configuration: [Release] - runs-on: [self-hosted] # For a list of available runner types, refer to + runs-on: [self-hosted, Windows, X64, L3] # For a list of available runner types, refer to # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on steps: - name: Checkout diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8449bd45..f49f9d2b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ jobs: matrix: configuration: [Release] - runs-on: [self-hosted] # For a list of available runner types, refer to + runs-on: [self-hosted, Windows, X64, L3] # For a list of available runner types, refer to # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on steps: - name: Checkout diff --git a/GitVersion.yml b/GitVersion.yml index 83f1afd9..abc83129 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -1,5 +1,5 @@ mode: ContinuousDeployment -next-version: 0.10.0 +next-version: 0.12.0 branches: main: regex: ^master$|^main$ diff --git a/README.md b/README.md index 243cf5d4..309dc4f7 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,31 @@ +# [WIP] RUNNING SOME POST PUBLISH TESTS + +![](assets/pics/banner_wider.png) # IX The **IX** is a series of tools that extend SIMATIC AX (Automation Xpansion) with a flexible and powerful connection with .NET ecosystem. IX includes a compiler (`ixc`) that translates PLC data structures into C# (PLC .NET Twin), which makes the PLC data available in a structured way for any .NET application. Furthermore, presentation libraries provide additional features for the automated rendering of PLC data in the UI/HMI. -**IX** is the underlying technology for the [ix.framework](https://github.com/ix-ax/ix.framework) that will provide a series of libraries and components for building automation projects. +## State of the project + +This project is under development; however, we are [releasing versions](https://github.com/ix-ax/ix/releases) that you can play with before the release of the full version. This project follows [semantic versioning](https://semver.org/). + +All versions released with a major version number `0` (e.g. 0.10.0) can have breaking changes to the previous version at any moment. Stable versions will be released with a major version number greater than `0` (e.g. 1.2.1). + +We plan to have production-ready libraries and tools in early spring 2024, that will cover: + +- compiler for building .NET twin object (ix compiler) +- communication layer between .NET twin objects and S71500 series PLCs +- user interface generator for Blazor application +- application templates for quick development and deployment. + + +**Documentation** is a work in progress should you find missing, unclear, or misleading content please feel free to [add an issue](https://github.com/ix-ax/ix/issues/new/choose) or to create a pull request with the fix you find appropriate. + +There are some **known issues** that we are looking into in the development process. The list of known issues is [here](https://github.com/ix-ax/ix/issues?q=is%3Aissue+is%3Aopen+label%3Aknown-issue). + + + +**IX** is the underlying technology for the [ix.framework](https://github.com/ix-ax/ix.framework) that will be rendered public in this organization and will provide a series of libraries and components for building automation projects. ## Disclaimer @@ -87,12 +110,6 @@ Entry.Plc.weather.GeoLocation.Write(); ![](assets/pics/2022-12-20-06-54-08.png) -## State of the project - -This project is under development; however, we will be releasing versions that you can play with before the release of the full version. This project follows [semantic versioning](https://semver.org/). - -All versions released with a major version number `0` (e.g. 0.10.0) can have breaking changes to the previous version at any moment. Stable versions will be released with a major version number greater than `0` (e.g. 1.2.1). - ## Getting started To get started, visit the documentation [here](docs/README.md#getting-started). @@ -102,6 +119,7 @@ To get started, visit the documentation [here](docs/README.md#getting-started). Examples can be found [here](src/ix.examples) + ## Contributing -Contributions are welcomed. Have a look at this repo [contributing document](CONTRIBUTING.md). +Contributions are welcomed. Have a look at [contributing document](CONTRIBUTING.md). diff --git a/assets/pics/banner_wider.png b/assets/pics/banner_wider.png new file mode 100644 index 00000000..ad81506c Binary files /dev/null and b/assets/pics/banner_wider.png differ diff --git a/docs/_coverpage.md b/docs/_coverpage.md index 4c73540a..334c9642 100644 --- a/docs/_coverpage.md +++ b/docs/_coverpage.md @@ -1,3 +1,5 @@ -# ix +![](_media/readme/logo-color-sm.png) + +# INDUSTRIAL AUTOMATION EXPANSION +## Bind SIMATIC AX based projects with .NET ecosystem -# take your PLC into .NET world. diff --git a/docs/_media/readme/logo-color-sm.png b/docs/_media/readme/logo-color-sm.png new file mode 100644 index 00000000..677c472a Binary files /dev/null and b/docs/_media/readme/logo-color-sm.png differ diff --git a/docs/_media/readme/logo-no-background-sm.png b/docs/_media/readme/logo-no-background-sm.png new file mode 100644 index 00000000..ecf3b8f9 Binary files /dev/null and b/docs/_media/readme/logo-no-background-sm.png differ diff --git a/docs/_media/readme/logo-no-background.png b/docs/_media/readme/logo-no-background.png new file mode 100644 index 00000000..7074935b Binary files /dev/null and b/docs/_media/readme/logo-no-background.png differ diff --git a/docs/_navbar.md b/docs/_navbar.md index 8b839ac8..f9621dd2 100644 --- a/docs/_navbar.md +++ b/docs/_navbar.md @@ -1,5 +1,5 @@ * # About - * [README](README.md) + * [What's in](README.md) diff --git a/docs/articles/blazor/LAYOUTS.md b/docs/articles/blazor/LAYOUTS.md index 3ca5ae5d..acb1c3f7 100644 --- a/docs/articles/blazor/LAYOUTS.md +++ b/docs/articles/blazor/LAYOUTS.md @@ -1,6 +1,6 @@ # Layouts -This file describes layouts, which are supported by Vortex.Presentation.Blazor framework. You will see examples and usage of supported layouts and how they can be nested. +This file describes layouts, which are supported by Ix.Presentation.Blazor framework. Following layouts are supported within the framework: @@ -11,9 +11,9 @@ Following layouts are supported within the framework: - Border - GroupBox -You can specify a layout in PLC code with the following attribute: +Layout can by specified in PLC code with the following attribute: ``` -{attribute wpf [Container(Layout.Name)]} +{#ix-attr:[Container(Layout.Name)]} ``` Where *Name* is replaced with the name of one of the supported layouts. @@ -28,16 +28,17 @@ UniformGrid will place elements in a row, where each element is of uniform width Let's have the following PLC code with a container attribute: ``` -{attribute wpf [Container(Layout.UniformGrid)]} -TYPE stExample : -STRUCT - testInteger : INT; - testEnum : stTestEnum; - testString : STRING := 'Hello World'; - testBool : BOOL; -END_STRUCT -END_TYPE +{#ix-attr:[Container(Layout.UniformGrid)]} +CLASS stExample : + VAR PUBLIC + testInteger : INT; + testEnum : stTestEnum; + testString : STRING := 'Hello World'; + testBool : BOOL; + END_VAR +END_CLASS ``` + And this is the result: ![alt text](assets/uniform.png "RenderIgnore and custom labels") @@ -54,21 +55,22 @@ This is the example behavior of wrap panel: ## Tabs Tabs layout will place each element in its own tab. You are able to switch between tabs to see corresponding UI. In example below, you can see PLC code with Layout.Tabs container attribute and corresponding auto-generated UI. ``` -{attribute wpf [Container(Layout.Tabs)]} -FUNCTION_BLOCK fbWorldWeatherWatch -VAR - {attribute addProperty Name "<#North pole station#>"} - NorthPole : structWeatherStation := (StationICAO := 'CYRB'); - - {attribute addProperty Name "<#South pole station#>"} - SouthPole : structWeatherStation := (StationICAO := 'NZSP'); - - {attribute addProperty Name "<#Verl, Germany#>"} - Verl : structWeatherStation := (StationICAO := 'EDLP'); - - {attribute addProperty Name "<#Kriva, Slovakia#>"} - Kriva : structWeatherStation := (StationICAO := 'LZIB'); -END_VAR +{#ix-attr:[Container(Layout.Tabs)]} +CLASS fbWorldWeatherWatch + VAR PUBLIC + {#ix-set:AttributeName = "North pole station"} + NorthPole : structWeatherStation := (StationICAO := 'CYRB'); + + {#ix-set:AttributeName = "South pole station"} + SouthPole : structWeatherStation := (StationICAO := 'NZSP'); + + {#ix-set:AttributeName = "Verl, Germany"} + Verl : structWeatherStation := (StationICAO := 'EDLP'); + + {#ix-set:AttributeName = "Kriva, Slovakia"} + Kriva : structWeatherStation := (StationICAO := 'LZIB'); + END_VAR +END_CLASS ``` ![alt text](assets/tabs.gif "Tabs layout") @@ -87,33 +89,33 @@ GroupBox layout will create border with name of first element around auto-genera --- ## Nested and multiple layouts -You can combine multiple container attributes in PLC code to create a complex layout of your elements. +It is possible to nest multiple container attributes in PLC code to create a complex layouts. Consider following the plc code: ``` -{attribute wpf [Container(Layout.Tabs)]} -TYPE stMultipleLayouts : -STRUCT - {attribute wpf [Container(Layout.Stack)]} - {attribute addProperty Name "A1"} - Piston_A1 : STRING; - {attribute addProperty Name "A2"} - Piston_A2 : STRING; - {attribute addProperty Name "A3"} - Piston_A3 : STRING; - {attribute addProperty Name "A4"} - Piston_A4 : STRING; - - {attribute wpf [Container(Layout.Wrap)]} - {attribute addProperty Name "A5"} - Piston_A21 : INT; - {attribute addProperty Name "A6"} - Piston_A22 : INT; - {attribute addProperty Name "A7"} - Piston_A23 : INT; - {attribute addProperty Name "A8"} - Piston_A24 : INT; -END_STRUCT -END_TYPE +{#ix-attr:[Container(Layout.Tabs)]} +CLASS stMultipleLayouts + VAR PUBLIC + {#ix-attr:[Container(Layout.Stack)]} + {#ix-set:AttributeName = "A1"} + Piston_A1 : STRING; + {#ix-set:AttributeName = "A2"} + Piston_A2 : STRING; + {#ix-set:AttributeName = "A3"} + Piston_A3 : STRING; + {#ix-set:AttributeName = "A4"} + Piston_A4 : STRING; + + {#ix-attr:[Container(Layout.Wrap)]} + {#ix-set:AttributeName = "A5"} + Piston_A21 : INT; + {#ix-set:AttributeName = "A6"} + Piston_A22 : INT; + {#ix-set:AttributeName = "A7"} + Piston_A23 : INT; + {#ix-set:AttributeName = "A8"} + Piston_A24 : INT; + END_VAR +END_CLASS ``` You will get the following auto-generated UI: diff --git a/docs/articles/blazor/LIBRARIES.md b/docs/articles/blazor/LIBRARIES.md index f370d46c..0c66c0b0 100644 --- a/docs/articles/blazor/LIBRARIES.md +++ b/docs/articles/blazor/LIBRARIES.md @@ -1,10 +1,11 @@ # Custom libraries +Custom libraries are a way to store own created views with different presentation types. -To create a custom components library, you have to create two projects: +To create a custom components library, two projects must be created: - **Connector project** - which will contain PLC compiled classes from Ix Builder. -- **Razor components project** - Razor class library, which will contain the implementation of corresponding views. Also, there must be a dependency on the Connector project. +- **Razor components project** - Razor class library, which will contain the implementation of corresponding views with dependency on Connector project. -It's important to note that the generated classes in the Connector project and created Razor views must be in **same namespace** to correctly locate views. +It is important to note that the generated classes in the Connector project and created Razor views must be in **same namespace** to correctly locate views. See the example below: @@ -19,7 +20,7 @@ Files in the *ComponentsExample* and the *PlcConnector* are in the same namespac *ComponentsExamples* library must contain `RenderableBlazorAssemblyAttribute()`. Thanks to this attribute RenderableContentControl is able to load its assembly and find all created custom view. -You can add this attribute to `AssemblyInfo.cs` class located in `Properties` folder. If there is no `Properties` folder, just create it with `AssemblyInfo.cs` class and paste there following code: +This attribute can be added to `AssemblyInfo.cs` class located in `Properties` folder. If there is no `Properties` folder, just create it with `AssemblyInfo.cs` class and paste there following code: ```C# using Ix.Presentation.Blazor.Attributes; @@ -27,18 +28,17 @@ using Ix.Presentation.Blazor.Attributes; [assembly: RenderableBlazorAssemblyAttribute()] ``` -If your PLC defined type has a C# counterpart in a `PlcConnector` project and `ComponentsExamples` contains a corresponding Razor view, it will be rendered by the RenderableContentControl. -There are two ways how to implement custom component: + +There are two ways for implementation of custom component: - Custom component with **code-behind** - Custom component with **ViewModel** support ## Component with code-behind -This is simple approach, where your Blazor view inherits from `RenderableComplexComponentBase` base class, where `T` is your custom component PLC type. However logic of your component must be specified in code-behind of view class. Important is, that both view and code-behind must be in same namespace as your `PlcConnector`. +This is simple approach, where Blazor view inherits from `RenderableComplexComponentBase` base class, where `T` is your custom component PLC type. However logic of your component must be specified in code-behind of view class. Important is, that both view and code-behind must be in same namespace as your `PlcConnector`. Look at the example below: - Blazor view `IxComponentServiceView.razor`: ```C# @@ -72,9 +72,10 @@ namespace Plc If you want your UI to be updated everytime, when PLC values change, you must call `UpdateValuesOnChange(Component)` method in `OnInitialized()` method in code-behind. ## Component with ViewModel -With this approach you can create component using MVVM design pattern. With MVVM, implementation of view and logic of your component is separated. Therefore your code is loosely coupled, more testable and reusable. -First, you need to create your ViewModel, which will inherits from abstract class `RenderableViewModelBase`: +With this approach it is possible to create component using MVVM design pattern. + +First, ViewModel must be created, which will inherits from abstract class `RenderableViewModelBase`: ViewModel `IxComponentBaseViewModel.cs` ```C# @@ -90,7 +91,7 @@ namespace Plc } } ``` -After that, you can create your Blazor view `IxComponentBaseView.razor`: +After that, Blazor view `IxComponentBaseView.razor` can be created: ```C# @namespace Plc @@ -111,7 +112,7 @@ After that, you can create your Blazor view `IxComponentBaseView.razor`: } ``` -Your view must inherits from `RenderableViewModelComponentBase` base class, where `T` is type of your ViewModel. Thanks to this, ViewModel instance is created and initialized with PLC type instance acquired within `RenderableContentControl`. After that, you are able to access your ViewModel within Blazor view. +The view must inherits from `RenderableViewModelComponentBase` base class, where `T` is type of your ViewModel. Thanks to this, ViewModel instance is created and initialized with PLC type instance acquired within `RenderableContentControl`. After that, ViewModel can be accessed within Blazor view. If you want your UI update everytime, when PLC values change, you can add `UpdatesValuesOnChange(ViewModel.Component)` directly to code section in view, or you can create partial class same as in previous example. @@ -127,5 +128,3 @@ When you call RenderableContentControl component like this: You will get generated UI, which you specified in your custom view: ![alt text](assets/baseview.png "Renderignore and custom labels") - -View contains real-time values from PLC. \ No newline at end of file diff --git a/docs/articles/blazor/README.md b/docs/articles/blazor/README.md index 6f4a4d09..fcc534e0 100644 --- a/docs/articles/blazor/README.md +++ b/docs/articles/blazor/README.md @@ -1,63 +1,56 @@ -# Ix.Framework.Blazor +# Ix.Presentation.Blazor + +Ix.Presentation.Blazor is set of libraries, which provides automatic generation of UI and custom styles. -This is Ix.Framework.Blazor framework. Providing automatic generation of simple UI from PLC objects for Blazor Server application. --- ## Prerequisites -TODO - +[Checkout you have installed all prerequisites](../../README.md#prerequisites) -- Blazor Server project based on .NET5 -- TwinCAT 3 project -- IX installed with PLC Connector set up and running -- Entry.cs class with PLC instance (look at app example for this class) +[Install package source](../../README.md#add-package-source) --- ## Installing -After you have created your Blazor Server project, you need to do the following steps: -**Install latest NuGet package Ix.Framework.Blazor** -~~~ -$ dotnet add package Ix.Presentation.Blazor.Controls --version 0.6.4-alpha.75 -~~~ +### **Install latest NuGet package Ix.Presentation.Blazor.Controls** + -or modify you csproj file ~~~ - +$ dotnet add package Ix.Presentation.Blazor.Controls ~~~ -**Add Ix.Framework renderable namespace to Blazor application.** +--- +### **Add Ix.Framework namespace to Blazor application.** -Add the following line to your `_Imports.razor` file: -``` -@using Ix.Presentation.Blazor.Controls.RenderableContent -``` -**Register Ix.Framework.Blazor services in DI container of your application.** +Add the following line to`_Imports.razor` file: -Add the following line to your `ConfigureServices` method located in `Startup.cs`: ``` -builder.Services.AddIxBlazorServices(); +@using Ix.Presentation.Blazor.Controls.RenderableContent ``` -Ix.Framework.Blazor services are located in *Ix.Presentation.Blazor.Services* namespace. +- - - +**Register Ix.Framework.Blazor services in DI container and build PLC connector.** -**Build and start your PLC Connector on startup of Blazor app.** +Add Ix services to container located in `Program.cs` file and build PLC connector: -Add the following line to your `Configure` method located in `Startup.cs`: ``` +builder.Services.AddIxBlazorServices(); Entry.Plc.Connector.BuildAndStart(); ``` -Note: Replace Plc with the name of your PLC instance. + +Notes: +- Replace `Plc` with the name of your PLC instance. +- Ix.Framework.Blazor services are located in *Ix.Presentation.Blazor.Services* namespace. --- -## How to use +## How to access PLC variables and automatically update UI +To access PLC variables and notify UI on value change, `RenderableComponentBase` class must be inherited and `UpdateValuesOnChange` must be invoked. Otherwise UI won't be updated on PLC value change. -To access PLC variables and enable two-way binding between source PLC object and UI elements you can look at the following example. ```C# @page "/" @@ -69,17 +62,17 @@ To access PLC variables and enable two-way binding between source PLC object and { protected override void OnInitialized() { - UpdateValuesOnChange(Entry.Plc.MAIN); + UpdateValuesOnChange(Entry.Plc.Counter); } } ``` -Thanks to the inheritance of *RenderableComponentBase* class and availability of *UpdateValuesOnChange* method values from PLC will be automatically updated in UI. --- -## RenderableContentControl +## Automatic renderer of UI +**RenderableContentControl** is Blazor component, which can automatically render UI from PLC structures. The changes of PLC values are automatically updated in UI. The following line demonstrates the basic usage of the RenderableContentControl component: ``` @@ -87,6 +80,6 @@ The following line demonstrates the basic usage of the RenderableContentControl Context="@Entry.Plc.prgWeatherStations"/> ``` -You can find the RenderableContentControl documentation in **[RENDERABLECONTENT](RENDERABLECONTENT.md)** file. +Documentation for RenderableContentControl component can be found in **[RENDERABLECONTENT](RENDERABLECONTENT.md)** file. + ---- diff --git a/docs/articles/blazor/RENDERABLECONTENT.md b/docs/articles/blazor/RENDERABLECONTENT.md index 993ad980..31ca361e 100644 --- a/docs/articles/blazor/RENDERABLECONTENT.md +++ b/docs/articles/blazor/RENDERABLECONTENT.md @@ -1,6 +1,6 @@ -# RenderableContent +# RenderableContentControl -This file describes the purpose, features and usage of the **RenderableContentControl** component. After reading this documentation, you will grasp the idea behind this component, see its purpose, features and how it can be used in real applications. +This file describes the purpose, features and usage of the **RenderableContentControl** component. ## Table of Contents 1. [What is RenderableContentControl?](#id-RenderableContentControl) @@ -17,7 +17,11 @@ This file describes the purpose, features and usage of the **RenderableContentCo
## What is RenderableContentControl? -RenderableContentControl is a Blazor component, which is able to automatically generate UI from C# objects acquired within Ix Framework. Ix compiler will create twin C# objects of PLC objects, which instances can be pass to RenderableContentControl to generate corresponding views. It's able to generate both complex objects (*IIxObject* type) and primitive objects containing values (*IValueTag* type). + +RenderableContentControl is a Blazor component, which is able to automatically generate UI from C# objects acquired within Ix Framework. +Ix compiler will create twin C# classes of PLC classes, which instances can be pass to RenderableContentControl to generate corresponding views. +It can render both complex objects (*ITwinObject* type) and primitive objects containing values (*ITwinPrimitive* type). +In addition, resulting UI can be adjusted with attributes from PLC code. --- @@ -27,16 +31,16 @@ RenderableContentControl is a Blazor component, which is able to automatically g ## Basic example Let's have following PLC structure *stExample*: ```T -TYPE stExample : -STRUCT - testInteger : INT; - testEnum : stTestEnum; - testString : STRING := 'Hello World'; - testBool : BOOL; -END_STRUCT -END_TYPE +CLASS stExample : + VAR PUBLIC + testInteger : INT; + testEnum : stTestEnum; + testString : STRING := 'Hello World'; + testBool : BOOL; + END_VAR +END_CLASS ``` -We can create an instance of stExample struct and run Ix build. After that, we can access instance of this struct and pass it as a parameter to the *RenderableContentControl* component like this: +IxCompiler will create *stExample* counterpart in C#. After that, this new object can be passed as parameter to `RenderableContentControl`. ```C# @@ -45,13 +49,12 @@ We will get the following auto-generated UI: ![alt text](assets/test_example.png "Generated UI from stExample") -As you can see, the parameter *Presentation* is set to *Control*. Because of the presentation type *Control* we can modify PLC values within Blazor application. We'll get to *Presentation types* later on. - ---
-## How it works +## How automatic generation of UI works + Ix.Presentation.Blazor framework contains two libraries: - **Ix.Presentation.Blazor** - Base classes @@ -61,67 +64,68 @@ Ix.Presentation.Blazor framework contains two libraries: - Styles - Layouts - UI templates of primitive types - - RenderableContentControl component + - *RenderableContentControl* component The diagram below represent fundamental logic of UI generation: ![alt text](assets/logic.png "Diagram of UI logic generation") -- When we use *RenderableContentControl* component it accepts context in form of **IIxObject/IValueTag** instance and presentation type. -- *RenderableContentControl* will parse the input and set presentation type for objects. -- It will determine, whether input instance is of type **IValueTag** or **IIxObject**: - - **IValueTag:** The framework will find a corresponding UI primitive template and then render the UI. - - **IIxObject:** The framework will try to find a corresponding UI complex template. If the complex template is found, UI will be rendered. Otherwise, **IIxObject** will be iterated down to primitive types, which then will be rendered with primitive UI templates. +- The *RenderableContentControl* accepts as parameters instance of plc structure and presentation type. +- Renderer will determine, whether input instance is of type **ITwinPrimitive** or **ITwinObject**: + - **ITwinPrimitive:** The renderer will find a corresponding UI primitive template and then render the UI. + - **ITwinObject:** The renderer will try to find a corresponding UI of complex template. If the complex template is found, UI will be rendered. Otherwise, **ITwinObject** will be iterated down to primitive types, which then will be rendered with primitive UI templates. -There is a lot of magic under the hood, but the main idea should be clear from the diagram above. This approach can save a lot of time when doing repetitive work. ---
## Features -This section describes features, which RenderableContentControl currently posses. +
-### **Presentation types and Presentation pipeline** +### **Presentation types** -**Presentation types** serve for specifying mode in which UI will be rendered. Within *Ix.Presentation.Blazor* framework following presentation types are supported. -- Display -- Control -- ShadowDisplay -- ShadowControl +**Presentation types** specify mode in which UI will be rendered. Within *Ix.Presentation.Blazor* framework following presentation types are supported. +- `Display` +- `Control` +- `ShadowDisplay` +- `ShadowControl` -In the **Control** presentation type, you can modify the values of objects. On the other hand, the **Display** presentation type serves for displaying values only -> they are read-only. If no presentation type is specified, Display presentation type will be used. +In the **Control** presentation type, values of rendered structure can be modified. +On the other hand, the **Display** presentation type serves for displaying values. +If no presentation type is specified, Display presentation type will be used. -> You can create components with your own presentation types, in which you wish to generate UI. +### **Presentation pipeline** -**Presentation pipeline** is represented by a string, where we can combine different presentation types in which UI will be rendered. -Each presentation type is separated by a dash '-'. RenderableContentControl will parse this string and will look for UI templates specified by presentation types in the pipeline. If the first presentation type is not found, it'll look for other one in the pipeline and so on... See the example below: +**Presentation pipeline** is represented by a string of presentation types. +Each presentation type is separated by a dash '-'. RenderableContentControl will parse this string and will look for UI templates specified by presentation types in the pipeline. If the first presentation type is not found, it'll look for other one in the pipeline and so on... -Let's add `testIxComponent: IxComponent` to the `stExample` structure. `IxComponent` is a component from an external library whose UI implementation is of **Manual** presentation type. +See the example below: -``` -TYPE stExample : -STRUCT - testInteger : INT; - testEnum : stTestEnum; - testString : STRING := 'Hello World'; - testBool : BOOL; - testIxComponent: IxComponent; //added property -END_STRUCT -END_TYPE +Let's add new property to the `stExample` structure. New type `IxComponent` is a component from an external library whose UI implementation is of **Manual** presentation type. +``` +CLASS stExample : + VAR PUBLIC + testInteger : INT; + testEnum : stTestEnum; + testString : STRING := 'Hello World'; + testBool : BOOL; + testIxComponent: IxComponent; //added property + END_VAR +END_CLASS ``` Let's have the following code, where we specify the presentation pipeline: ```C# ``` -You will get the following auto-generated UI: +Renderer will generate following UI: ![alt text](assets/pipeline.png "UI generated with presentation pipeline") -You can see, primitive types are generated in **Control** presentation type whereas IxComponent is generated in **Manual** presentation type. +Primitive types are generated in **Control** presentation type whereas IxComponent is generated in **Manual** presentation type, because Manual view have been found first.
@@ -132,44 +136,44 @@ Thanks to the support of custom attributes in the PLC code you can specify, whic Let's have the following PLC code with attributes: ``` -TYPE stExample : -STRUCT - {attribute addProperty Name "<#Custom label Integer#>"} - testInteger : INT; +CLASS stExample : + VAR PUBLIC + {#ix-set:AttributeName = "Custom label Integer"} + testInteger : INT; - {attribute clr [RenderIgnore()]} - testEnum : stTestEnum; + {#ix-attr:[RenderIgnore()]} + testEnum : stTestEnum; - {attribute addProperty Name "<#Custom label String#>"} - testString : STRING := 'Hello World'; + {#ix-set:AttributeName = "Custom label String"} + testString : STRING := 'Hello World'; - {attribute addProperty Name "<#Custom label Bool#>"} - testBool : BOOL; + {#ix-set:AttributeName = "Custom label Bool"} + testBool : BOOL; - {attribute clr [RenderIgnore()]} - testIxComponent: IxComponent; -END_STRUCT -END_TYPE + {#ix-attr:[RenderIgnore()]} + testIxComponent: IxComponent; + END_VAR +END_CLASS ``` -After rendering with RenderableContentControl you will get the following UI: +Renderer will render following UI: ![alt text](assets/renderignore_labels.png "Renderignore and custom labels") -You can see, *testEnum* and *testIxComponent* are ignored and the rest of the elements have custom labels. +Properties *testEnum* and *testIxComponent* are ignored and the rest of the elements have custom labels. -You can also specify `RenderIgnore` on an element, which will be ignored in the specific presentation types. For example, you can do it like this: +It is possible to ignore properties only in specific presentation types: ``` -{attribute clr [RenderIgnore("Display","ShadowDisplay")]} +{#ix-attr:[RenderIgnore("Display","ShadowDisplay")]} testIxComponent: IxComponent; ```
### **Layouts** -In the PLC code, you can use layouts attributes to customize auto-generated UI. -For more info about layouts and for examples look into **[LAYOUTS](LAYOUTS.MD)** file. +Auto-generated UI can be customized by layouts. +More information about layout is in **[LAYOUTS](LAYOUTS.MD)** file.
### **Styling** @@ -178,14 +182,17 @@ Ix.Presentation.Blazor contains in-built styles. Styling is provided by [Bootstr Currently, the framework contains a default style that can be added as a reference in the Blazor application file *_Host.cshtml* in the following way: ``` - + +``` +It is possible to add built-in javascript libraries as well: +``` + + ``` - -> It supports a generic Bootstrap library too - ### **Custom components libraries** -You can create a custom library of your components with corresponding views. When you reference the library from your Blazor project, the framework will automatically load its views, which then can be auto-generated with the RenderableContentControl component. +Ix.Presentation.Controls framework provides possibility to create a custom library of components with corresponding views. +When library is referenced from your Blazor project, the framework will automatically load its views, which then can be auto-generated with the RenderableContentControl component. For more information about custom libraries and how to create them, look into **[LIBRARIES](LIBRARIES.md)** file. diff --git a/docs/articles/blazor/assets/logic.png b/docs/articles/blazor/assets/logic.png index 61f10017..eba1207e 100644 Binary files a/docs/articles/blazor/assets/logic.png and b/docs/articles/blazor/assets/logic.png differ diff --git a/docs/index.html b/docs/index.html index a7cce666..0822db23 100644 --- a/docs/index.html +++ b/docs/index.html @@ -20,7 +20,7 @@ window.$docsify = { name: 'IX', repo: 'https://github.com/ix-ax/ix', - themeColor: '#e69138', + themeColor: '#010C80', relativePath: true, autoHeader: true, coverpage: true,