BSA – WPF Dark Theme

And there we area – still a bit work in progress with styling details, but I have passed the point of no return.

Back in the days then I coded MFC for User Interface I often upgraded my apps almost for free by just sticking to classic development. This was what I did here as well – I ignored dark theme assuming I would find a solution that could provide that for free. The solution is the 2nd on Nuget list – import a single style sheet, write a few lines of code and style up the places that needed manual styling – and voila.

I am ok working with light style, but dark theme is so much cooler and most important of all – I use colors and styles that get me into better moods. And yes – I need to change some of the above as this still is work in progress, but I am actually impressed over how fast and easy this actually was.

What I have done technically speaking is to avoid caring about colors and used a style sheet that override colcors and style for standard Windows components. I don’t fully understand all the XAML code yet, but I like the results and way of doing this as it means I can have different style sheets and completely change the look of BSA – but, that’s for later.

BSA – WPF Dark Blend Theme

Work in progress. I found an example of how to change the style of Windows controls and voila – all the controls I have not styled myself changed. Notice the scroll bars etc. This is what I liked with Visual Studio back in the old days – you just stayed loyal to their scheme and suddenly get a lot of work for free. I need to update the rest of the color codes, but I can now go dark theme with close to no extra work. This is exactly what I hoped for as I decided not to dig into dark theme yet.

Also I discovered that the property folders I want actually exist – called “Expander” so I need to do less work than expected to build a property editor the excact way I want it. The Blend Style example that convinced me is seen below. This is basically a single xaml style file and a few lines of code added to you project. I was surpriced about how little extra code it was. For those interested you can find the original github code here https://github.com/DanPristupov/WpfExpressionBlendTheme.git under MIT license. Next time you see BSA will be in it’s final dark style. The all gray style used below is a bit booring in my eyes – I need a little bit more colours to light up the moods.

I don’t fully understand the styles.xaml yet and it is still a bit work in progress, but this was a very convinsing demo about how powerfully WPF/XAML actually is. I don’t pretend I like everything in it, but what I like is the sum speed of productivity you get – hours needed to make an advanced GUI solution. WPF is suprisingly fast to work. It’s been a few tweaks on the 2D engine, but I am very happy with the results and hours I needed to get there.

In comparison – I can (and am) doing the same in QML. I get the job done in Qt/QML as well, but working with QML is a steady stream of technical problems and an IDE that don’t do it’s job. The sum is that to do the same I use close to 5 x as much time. In WPF you write C# and XAML, but in QML you write C++, convert to Qt++, do QML bindings, write QML and JavaScript. It simply is a larger job to start with and add a poorly working IDE on top of that. That said – QML compares well to technologies we used 25 years ago like C++/MFC. And more important – QML and WPF is the only technologies I have seen that make using GPU’s decently easy. I have yet not tested the new MAUI, but I will.

The main reason I still work on QML is because I have auto-generated most of the difference and need a SDK that I can use to generate code for. While my primary target will be C# itself I also intend to pick up targets like QML. The result will be a huge difference in number of hours needed to code up systems – just stay tuned a few more months and BSA will be airborne.

Cost wise QML is a nightmare – Qt/QML with their designer cost ca 50,000.- NOK, while Visual Studio cost ca 5000.- NOK. And add to that the well of libraries like this one you find in Visual Studio. Just one advice – be very sceptical and think through what you import as you pick up nuget packages. Myself I only use MIT or similar licenses and source code unless I buy a commercial package. Make sure the library you pick up fits the bill.

Happy coding!

BSA – Starting HMI Components

This list will increase, but I need to start with some basic components. The first version I need is HMI only together with a few other components:

DataSource

Generic definition of a source that can be connected to a HMI component to read/write data. This will be a named component that is implemented manually allowing us to generate code.

Form

Window/Form used to hold everything else. Only components displayed over a Form is visible thought BSA allow invisible components outside the form. Form has options for Caption, System, minimalize, normal, maximize etc. Form is just the main container. Typical Form is a desktop window, but Form can also be a report or Web page.

Panel A square container that holds other components.
Label Text label.
String Edit Single line text edit.
Number Edit Specialized Number Edit.
Button Button with style options.
Checkbox Boolean checkbox.
ComboBox Edit box with selectable list.
TextBox

Multiline text edit field with optional mini-editor controls.

Group A frame container with title in the border.
HScrollBar Horizontal scroll bar.
VScrollBar Vertcal scroll bar.
Image Picture/Image.
Menu Main Menu
MenuItem Menu Item.
StatusBar Status Bar
ToolBar Tool Bar
TabBar Bar with tabs allowing you to select one of many pages.
TabPage

Container allowing one of many pages to be selected. The container outline the page area and link to an index component like TabBar. It can also visualize selected pages, but the pages are defined on separate Panel containers.

ListBox Standard List Box.
TreeGrid Grid/Tree hybrid allowing first column to be a Tree.
Layout Grid

Invisible grid allowing other components/containers to be positioned and scaled.

Circular Gauge Standard circular gauge.
Bar Gauge Standard Bar Gauge.
RT Line Plot

Specialized Real-Time Line Plot designed for high speed data visualization.

Led Colored status indicator.
User Components

All components are a visual representation with a property list used to generate code. So I want a list of “build-in” components that the user cannot change to get started, but I also want to give the user a capability to add their own content. I have to return to how to do this.

Gauge Designer

A specialized gauge consisting of multiple layers put on top of each other. Should give the user an easy path to design theire own animated gauges.

Timer

A mini state diagram allowing the user to specify a timer and what happens on that event.

This list will change and grow. The main challenge here is to limit the scope of this first release so I actually can release a first version. Also keep in mind that we are not just designing the screens here, we are actually coding the content as well. I have fetched HMI content from standard GUI designers, but it is important to remember that this is a design specification used to generate code. That gives us far more automation options. Using Modbus as an example – I want to grab a Modbus map as data source and be able to create a fancy desktop application in minutes and literally have the same on desktop and web without thinking about it – it needs to be that easy.

BSA – HMI Form Properties

The easiest way to discuss properties is by discussing actual components, so I start with HMI Form. The terminology “Form” is well known for C# developers. I could have used dialog, window or whatever, but decided that “Form” is a good word. What you see below is the current HMI Form draft used in BSA. I will make this a bit more WYSIWYG later, but this is NOT the actual Form – this is the design of a Form. The actual Form will be generated from BSA. In this case I illustrate a Form that is a Display dialog containing a property list that design look and behavior. The result will be a long list of properties, but my experience with this from C# and other tools is that I 99% of the time only use a few selected properties – so lets start with those:

Colors and Style is something I set and later reuse. So the best idea is I think to remember what was last use and use that as a starting template. Simply said this is something I change once and seldom use so it can go into background on a separate page.

  • Description is very nice to always have in front.
  • Name of component
  • Caption Enable and Title
  • System Box enable
  • Minimize, Normal and Maximize box.
  • Starting Window state
  • Window Size and Scale limitations.
  • Window style – modal etc

The idea is to put the properties you actually use a lot and will change on a default front-page, while all the colors and nitty gritty details can go on specialized pages. The rationale for this is that I often spend time looking for things, so I want to see if I can make this a bit easier. The components will need a lot of properties so it makes sence focusing like this.

To do this one I will need the following completed:

  • My mini dopcument editor.
  • Standard single line text editor for name, title.
  • Boolean to enable caption, boxes and features.
  • Number editor
  • Combo box.
  • Color editor.

Form is a container for other components so it has no direct data-links.

BSA – Property Editor

The next task on BSA is to get my Property Editor functional. What you see above is an early demo draft to test a concept. I just wanted to get a feeling with how this could be done and test out the “Text Edit” part. The concept with a Property Editor is that you click on a component in a diagram and get properties for this displayed. Some of these properties are documents, source code and tables making them a bit complex to integrate without to many trade offs.

I considered using an existing Property Editor, but (1) WPF does not contain one, (2) this is a very important component for BSA and (3) it is actually straight forward to implement if your not afraid of huge work loads. It is a large job and you will get tired of me blogging about various editor details as this evolves, I will need a specialized editor for each datatype I use. Some are very straight forward, while others will need a good design and some fresh ideas.

It is three editors that are of special concern – Tables, Text documents and Source Code. These can all be implemented as a property line. Text document is illustrated above. This was far more capable than I first expected as I can widen the Property editor and get a larger doc. But, having all tables, docs an source code like this have it’s usage and limitations. I will need something more.

Having source code as part of the property editor is usefully as you want a quick look by selecting a block on a diagram that contain source code. You can see and even edit in the mini editor, but I thing we all agree that we can’t do more serious work here – we will need a proper source code editor. So the idea is to do both allowing Tables, text doc and Source code to expand into being a full View in BSA itself. This might also work for sub-diagrams. I obviously need to experiment a little around this and see how this works out. But, this is a functional area that will decide the success of BSA – it is that important. If I don’t get this to become something that is very convenient to use the entire tool will become a big, clumbsy failure. The reason is obvious – time usage.

This is the one thing you need to have in mind all time – time. BSA is  a productivity tool that should enable you to do more faster. But, I have used so many tools in my carrier that ended up as a failure that I am well aware of the danger of repeating that failure if you make the wrong choises or compromizes.

BSA – Integrating PScript

I will need an editor for PScript and the most obvious path is to integrate this into BSA as a building block. PScript evolved from an experiment into being a Plain Interpreter and this makes it easier because I can actually generate source code for other languages from PScript. Meaning you can write PScript and either use Plain, C++ or C# as your target platform – which can be done by either integrating PScript or generating target code.

Plain will change based on the experience with PScript. The VM I drafted for Plain is complicated and I realized that I probably can simplify things a lot by building a Compiler based on the Interpreter. I need to test this new idea a bit later, but the only difference between an Interpreter and Compiler is that an Interpreter execute source code, while a Compiler generate executable code – in Plain’s case I can actually generate C++ or C# etc.

Obviously I can also use PScript as is. This was intended as an Interpreter running embedded and I can easily create a C# or QML PScript component adding HMI libs. For C# I need to create a component that convert between natice C++ code and C#. With Qt I basically need to do the same. While Qt is C++ it has so many tweaks and separate datatype definitions that you end up converting C++ to Qt++. QML/JavaScript Integration comes on top of that.

As for PScript Editor we also need an integrated debugger, but lets take one step at the time. My first PScript editor will not impress anyone, but it comes a day tomorrow 🙂

BSA – Line Moves

To move a line you select it. Selection is done by moving the mouse over the line and clicking the left button. As you select the line the end point markers will show and you move the mouse to an and point and simply move it with the mouse. If you move the marker outside the symbol and release the left mouse-button you delete the line. If you move the marker to a different symbol you establisk a new link with that symbol.

Lines in BSA are automated so you can chose line type, but you cannot change the line except for selecting position and connection of the end-points. This is done deliberately to avoid that you spend time on moving lines around. This is after all a programming tool, not a drawing tool. All links will behave like this, but some symbols will have more restricted connection options.  PLD Diagrams have a number of entry and exit paths that will show up as red or green connection points points. Red means they MUST be connected, Green means they can be left ‘as is’. In both cases you will need to connect the line to that exact connection point. I have done an earlier demo of this that I will use because if you use a diagram within a diagram you need to know what entry and exit points your connecting where. Just drawing a new link to a symbol would in theory create a new entry point – I did not get a good feeling about that one, but lets see.

The picture above show how a line is highlighted as you move the cursor over it. This is a GPU trick. The GPU will allow you to select the actual line, but hit test is very accurate and since the line is thin it becomes hard to select. So what I do is to create a helper line that is thicker to make selection easier. As mentioned only end-points can be moved on a link. I will at some point create an option to ,amually move corners as well, but I preffer automated lines to avoid that the developer use time fidling with lines. The rationale with this is experience with an earlier CASE tool where this was a big issue that used up a lot of time. You control lines by moving end-points and symbols, not by fiddling with line paths.

 

PScript Interpreter – Part 8 – RTOS

We will always have some kind of RTOS behind PScript regardless where we execute, so what I need a few system functions to interface to the RTOS in an uniform way. I my own linear scheduler that scale better than and that is perfect for extending thread shifters. The advantage is that I get the same RTOS functionality on STM32, Windows and Linux etc.

Timers I need to start and stop timer functions. A time function can be something I need to execute on regular basis or simply a function to be executed if I time out on an operation.
Modules I need to be able to start, stop, suspend and continue other modules. The cool thing is that this can be done locally and remotely. And a module on Windows is basically an executable.
Mutexes I need a mutex capability between threads. Events etc will execute as an interrupt and I need a smart way of locking that down.
File I/O Many devices have Serial SPI, TF Card or some way of storing data, so I need an uniform way of accessing this.
AL MCU’s with Hardware I/O needs to be accessed on an uniform way. This is easy as I will borrow a bit of the Arduino design.

I was considering threads, but for that I need a stack so I can as well stick with a capability to execute multiple modules.

I want to re-visit my notes on parallelism, mutex and transactions on Plain. PScript is growing into becoming an Interpreted version of Plain – I have to watch out for bloating/footprint size – adding RTOS, easyIPC etc will cost, but the result will be worth the extra Kb + I can always #ifdef on functionality to keep things down if I need to.

And – finally I think I am at the end. The list above together with modules and events is a bit of a scope creep, but it also makes PScript very attractive to use. I need to return on syntax details on this list.

PScript Interpreter – Part 7 – easyIPC

Part 6 introduces an easy way of communicating where one module raise an event and another receive it. But, for this to work I need some infrastructure that easyIPC provides for me. easyIPC uses a device address where device 0 is NMT (Network Master) on the local network. At this point I don’t care if this is CAN, RS485, SPI, Ethernet or Wifi – the device will have a primary, default network supporting easyIPC or a similar scheme.

This simple drawing illustrate what needs to happen. (1) as myDevice start it register TempMessage and myDevice as a resource to NMT. As myPC start it request that resource from NMT. NMT can be located anywhere in the system, but it is actually on the PC in this case. One challenge is that myPC might request myDevice.TempMessage before it is declared and resources might fall in/out of service. It’s NMT’s responsibility to keep track of this and send a new request answer once a resource becomes available. I want NMT to remember and notify rather based on requests to minimize messaging during start-up. This requires that NMT have a bit of memory – which should be ok.

The second challenge is that I might want two or more myDevice – lets say one for in-house temperature and one for outside temperature – how do I differ the two? The solution is that myPC can extend the resource name with an unique name. And that we in config say what device is what. myDevice and/or NMT need to store this. Once configured we get NMT to re-initialize the network with correct names.

 

PScript Interpreter – Part 6 – Events

I need a way to communicate with the rest of the world, and the method I like is “Events” where you send and receive packets or byte streams. Let’s annotate an example where I read temperature from an ADC once a second and display it on the PC. In this case I use PScript in both ends.

Device code:

module myDevice
    event timer(1000)
        float temp = readAnalog(14)
        raise TempMessage(temp)
    end
end

PC code:

module myPC
    event myDevice.TempMessage(float temp)
        print(“Temperature is “,temp)
    end
end

I introduce the keywords “module”, “raise” and “event” from Plain here. Module is a named application running in our network, while event is an external event.

This is a draft, so I need to work on the syntax details to make this work, but the key concept is that communication should be this easy. (1) I raise and event with parameters and (2) I receive and process the same event on a different device, in this case my PC.

I have a few challenges with the syntax above. (1) how do I handle multiple instances of “myDevice”? (2) how do I differ event filter parameters from call parameters, and (3) how do I send a respond back if I need to.