YAY !!!!!!!!!!!!!

For the past 3 days I’ve been on a training course and today I got my certification as a CSIA level 1 instructor !!!!!

Fixing code by not touching it

The other day I was helping a friend with some code that worked fine in several versions of Xojo but then in a newer one wouldn’t compile

Seems he found a compiler regression Whether this _should_ have been caught by regression tests etc is an entirely different question.

It exists. And now his large project doesn’t compile.

The code this affects is old and has worked for many years.
And he’d rather NOT have to alter all of it to fix the issue.

Since the code in question is in a subclass he was not looking forward to making significant changes to it and having to retest all his changes

So how can he fix this compiler issue and NOT have to touch all the code that suddenly doesnt compile ?

There are several options

Of course he could “fix” the code in the class directly – not something he relished

Another option is to just NOT use a new version of Xojo that breaks things this way – not a great option if he wants to support Ventura & newer

There is at least 1 more that is fairly simple, testable, and does fix this without actually modifying the code in the original class ๐Ÿ™‚

I’ll let you noodle on that until tomorrow.



Never had to think about this before

Was chatting with a potential client. And they are new to Xojo.

When I mentioned that I had worked at Xojo Inc for more than 10 years they didn’t believe me. And they asked for some proof. I had never encountered this before.
So here’s a quick few references where you can see that I was once a member of their development team.

Xojo XDC 2018 Ask the Engineers
Thats me on the far right

XDC 2016 Highlights
Geoff, the CEO, specifically names me
Later on thats me at far right

Posts like, and this one and this one saying “Norman fixed …”
Thats me

Announcements about the FIRST Xojo developer to go to Germany for the MBS Conference

And in the new bug tracking system issues under @normanpalardy1
Xojo gave me a new account when I departed and renamed my existing one, to normanpalardy1, so as a non-employee I no longer had access to the same cases I did as an employee (Makes sense to me)
(They have done the same with other former employees like Greg O’Lone)
Cases like this one

You’ll see this issue is marked as FIXED by normanpalardy1 – thats me
And there are lots more like that

And I’m sure if you ask in the forums that many users would reply that yes I worked there
An I expect Xojo’s staff would as well

JUST to archive the things I wrote while I worked there – a list of URLS

https://blog.xojo.com/2019/02/27/binary-magic-with-signed-integers/
https://blog.xojo.com/2019/02/12/how-code-one-liners-can-make-debugging-harder/
https://blog.xojo.com/2019/01/28/if-vs-if-and-conditional-compilation/
https://blog.xojo.com/2019/01/24/some-follow-up-regarding-byref/
https://blog.xojo.com/2019/01/23/byref-vs-reference-types/
https://blog.xojo.com/2018/12/12/what-kind-of-variable-are-you/
https://blog.xojo.com/2018/12/04/are-your-macos-apps-ready-for-64-bit/
https://blog.xojo.com/2018/06/03/which-dlls-can-i-move-and-where/
https://blog.xojo.com/2018/05/14/getting-the-mysql-server-version/
https://blog.xojo.com/2018/03/14/code-tip-be-careful-with-loops/
https://blog.xojo.com/2018/02/12/setting-constants/
https://blog.xojo.com/2018/01/25/supporting-multiple-cores/

Other links that show I was engaged byXojo
https://blog.xojo.com/2016/10/11/xdc-2016-recap/
alternate – https://web.archive.org/web/20161117055842/https://blog.xojo.com/2016/10/11/xdc-2016-recap/

https://blog.xojo.com/2015/03/11/xojotalk-009-its-my-dog/
alternate – https://web.archive.org/web/20230324163333/https://blog.xojo.com/2015/03/11/xojotalk-009-its-my-dog/

https://blog.xojo.com/2014/09/10/6-years-and-still-ticking/
alternate – https://web.archive.org/web/20201204173921/https://blog.xojo.com/2014/09/10/6-years-and-still-ticking/

XojoScript debugging

if you’ve EVER tried to debug a Xojo Script its truly a pain in the rear end

Since one of my current projects requires a lot of Xojo Script that became really apparent and really annoying

So, for this project, we made a XojoScript debugger ๐Ÿ˜›
You can run & single step. And with each step the values of all variables in scope will be reported; where possible. Since there’s no introspection in XojoScript I cant make it dump out the values of properties of classes or other reference types ๐Ÿ™

But – here’s what it looks like so far ๐Ÿ˜›

INN

Over the last week I’ve been asked repeatedly about INN’s status
So I’ll post the same answer I’ve give n out several times

It seems to have been aย series of bad luck & timing

Garry was in the process of transferring operation of INN to me
Just as  I was going on holidays

And apparently Digital Ocean had a node failure and thats where INN was housedAs far as I know Garry hasnโ€™t investigated or invested any time to get it back up and running since he was moving away from being the admin anyway

And Iโ€™ve been on hotel wifi so couldnโ€™t get anything done

The intent IS to get the domain transferred and the discourse instance back up and running as quickly as possible

UPDATE : I am HOPING that once the domain transfers that INN will be back up
That could be later this week after Nov 23
Fingers crossed !

Graphics in C# on macOS

The Einhugur framework has similarities to Xojo in many ways

It has a Canvas, just like Xojo

And when you use its paint event you can do many of the same things like drawing text and shapes and pictures.

We can add a canvas just like other controls. And we can implement the paint event in the same way.

canvas = new Canvas(left,top,width,height);
canvas.Paint += canvas_Paint;

And the paint event would look like

private void canvas_Paint(object sender, PaintEventArgs args)
{
    GraphicsContext g = args.Graphics;

    // GraphicsContext is in many respect like Xojo's
    // Graphics

}

Now you can change the fill colors, stroke colors (borders), and draw shapes & text. You also have built in rotation, clipping, and scaling. There are no bezier paths and some more complex drawing operations – yet.

One thing you will notice is that getting an RGB or RGBA color is a little different.
Since colors in the Einhugur framework are based on CGColors internally they permit a really wide range of colors. Much more than the 0 – 255 based Xojo colors.
So, each component of a RGB color is a floating point value in the range 0 – 1 like the following

g.FillColor = Einhugur.Drawing.Color.RGB((nfloat).6, (nfloat).3, (nfloat).4);

RGBA is similar with the Alpha also being a value ni the range 0 – 1.

Once you have the basics in place you can draw most anything you want.

private void canvas_Paint(object sender, PaintEventArgs args)
{
   GraphicsContext g = args.Graphics;

   g.FillColor = 
     Einhugur.Drawing.Color.RGB((nfloat).6, (nfloat).3, (nfloat).4);

   g.StrokeColor = 
     Einhugur.Drawing.Color.RGB((nfloat)0, (nfloat)1.0, (nfloat)0);

   g.DrawRoundRectangle(1, 1, 
         (float)(canvas.Width - 2), (float)(canvas.Height - 2),
         4, 4);
}

Oh and yes, with creativity you can combine drawing pictures with threads !

As usual a link to the project as it is now

Hanging on by a …

THREAD !!!!!!!!!!

yeah ok bad joke. I’ve been so dang busy with studying and work that I just haven’t had a reasonable chance to write any updates for the C# on macOS series.

But now that my Canadian Ski Patrol exams are done I can get back to some fun.

How to make our little project use a thread instead of a timer. The biggest place in the project you might notice this is in the level indicator.

Right now when you press & hold a menu item the updates to the level indicator will pause until you release the menu item. It sure would be nice to not have that occur.

And, the reality is that since we are using C#, most of what we need is already built in, or easy to acquire.

We’ll need to add a Nuget package

We’ll need to add the Xamarin Essentials package

And we’ll want to add a using clause so the compiler is alerted to the fact we’re going to use the Xamarin.Essentials package.

We need to declare a variable to hold out thread instance

We’ll change the window SetUpControl method to NOT create a timer but instead create a Thread.

This new line creates the thread and tell it what method to call when the thread runs. This method is one that gets called ASYNCHRONOUSLY – so it has some slightly special set up.

 private async void Thread_Action()
 {
    while (true)
    {
       await Xamarin.Essentials.MainThread.InvokeOnMainThreadAsync( () =>      Update_Indicator() );
       System.Threading.Thread.Sleep(100);
    }
}

Note the ASYNC keyword on this method – thats the entire “special set up” ๐Ÿ™‚

The other thing I’ve done is refactored the old timer code so the thread and timer can both use the same method to update the indicator.

The only remaining thing to do now is start the thread running right where we used to have the Timer getting started.

Now because we have added some C# runtime references, and a using clause for System.Threading, you may see an error like

You can have VS take you right to the location of the error by right clicking the error and choosing “Go To Task”

We can correct the issue by simply fully qualifying the Type name to Einhugur.Threading.Timer

Once fixed you should be able to run and, note what when you press & hold the Edit item in the menu bar the level indicator continues to move up & down unlike what it did with the timer.

The speed with which the indicator moves up and down can be adjusted by changing the sleep value for he thread. The shorter the sleep period the faster indicator will update.

Once again – the project in its current state

Lions and Timers and Such ! Oh My !

Anyone following along that has poked around what exists for the Einhugur C# UI Framework should notice that there IS a Timer object in there already.

Since its in the Einhugur.Threading namespace we need to add that using clause to our project

using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using AppKit;
using CloudKit;
using Einhugur.Forms;
using Einhugur.Threading; // <<<<<<<<<<<<<<<

using Mono.Data.Sqlite;
using Npgsql;

Using one is as simple as declaring the property for it, creating it, setting its period, or interval, and adding a method for it to call whenever the Timer needs to run some action.

            timer = new Timer();
            timer.Interval = 0.05;
            timer.Action += timer_Action;

One thing you dont need to do, since its not a visual control, is add it to the list of controls in SetUpControls. Since its actually a property on the layout thats enough for it to function exactly as we want.

However a timer by itself isn’t very interesting. Let’s have it drive something visual like a Level Indicator.

    TextField textfield1;
    TextField textfield2;
    ListBox list;
    Button pushButton;
    Timer timer;
    LevelIndicator indicator;

We’ll want to add one more using clause to access the Einhugur Drawing namespace where things like color and gb functions are defined

using Einhugur.Drawing;

And then in SetupControls we need to add code to set the indicator up

indicator = new LevelIndicator((float)(pushButton.Left + pushButton.Width + 12), (float)pushButton.Top, 200, 22);
indicator.Style = LevelIndicator.LevelIndicatorStyle.DiscreteCapacity;
indicator.CriticalFillColor = Color.RGB(255, 0, 0);
indicator.WarningFillColor = Color.RGB(0, 0, 255);
indicator.FillColor = Color.RGB(0, 0, 0);
indicator.MinValue = 0;
indicator.MaxValue = 100;
indicator.WarningValue = indicator.MinValue + (0.50 * (indicator.MaxValue - indicator.MinValue));
indicator.CriticalValue = indicator.MinValue + (0.90 * (indicator.MaxValue - indicator.MinValue));
indicator.Value = 0;

return new Control[] { textfield1, textfield2, 
                         list, pushButton, indicator };

Indicators come in several styles. They are explained on this Apple page. But they are easy to play with. One gives you a segmented capacity, like an audio meter, one a continuous bar that has not marked gradation, one shows as a star rating. Try them all ๐Ÿ™‚

Certain settings, like critical fill color warning fill color, warning value and critical value may not make sense with some styles.

If you use the discrete and continue capacity styles they do. And when the value of the level indicator is above the warning, and less than critical that portion of the indicator in the warning color. Same for critical. We’ll set all these up and hook it to a timer that will reveal what I mean.

Using the settings above now all we need is the timer action method to do something to the level indicator. Lets make it count up and down to animate the level indicator.

 private int increment = 1;
 private void timer_Action(object sender, EventArgs a)
 {
   if (indicator.Value <= indicator.MinValue)
   {
      // reverse and go up 
      increment = 1;
   }
   else if (indicator.Value >= indicator.MaxValue)
   {
      // reverse & go down
      increment = -1;
   }
  
   // change the level indicator
   indicator.Value = indicator.Value + increment;
 }

OK we have most everything set up. Instead of hooking this timer up to start when we push the button on our layout, which would be simple, lets start it when the window opens.

We dont want to put the call to the timers start method in the Setup of the controls. So how do we get this into what would be the equivalent of the Open event ?

If you right click on “Window” in our definition of the class

	public class MainWindow : Window

and select “Go To Definition”

you get the assembly browser. In there you can see that a Window has an Opening method we can make use of. Perfect !

To override the default implementation we need to tell the compiler this IS an override

 protected override void Opening()
 {
    timer.Start();
 }

Often the easiest way to get the right definition for the method you want to override is to copy the declaration from the assembly browser, paste it into your code and change virtual to override.

And now as the timer runs its action event it affects the value of the level indicator. On the way up as the level indicator gets to the warning value the color changes to the warning fill color. And when it gets to the critical value it again changes. And as it goes back down in value the colors change again.

Again – our project as it is now

Using other databases in C#

A new version of the Einhugur C# UI framework was released a short while ago.

Since the framework is still literally a work in progress some changes an dupes are to be expected. Listbox now exists and its constructor now takes an array of column titles as well as the initial dimensions. So you may need to update code like


list = new ListBox(10, 20, 80, 20 );

to add a new last parameter

list = new ListBox(10, 20, 80, 20, new string[] {"col 1", "col 2"} );

to set the column titles.

Dont be surprised won the road if there are several constructors to pick from where you dont have to set the titles right then.

With that out of the way lets turn to using the Mono.SQLite database – with one on disk !

In prior editions of the tutorial we used the in memory SQLite database. We had

sqlite_conn = new SqliteConnection("Data Source=:memory:");

To switch this to use a database on disk we just need to alter the connection string.

  sqlite_conn = new SqliteConnection("URI=file:/Users/npalardy/testdb.sqlite;");

With the Mono driver for SQLite when you connect this will create the database if it doesnt already exist.

And .. tada ! Thats it ๐Ÿ™‚ Instead of an in memory database now we are using one from disk.
Here’s the project as it exists so far.

In the poll I posted half the respondents ๐Ÿ˜›Sia they wanted to see how to use a different db. So we’ll alter this to use PostgreSQL since I happen to have a handy configuration already on my machine – but the steps will be similar for most databases.

First we need to grab a PostgreSQL database driver. We’ll add a NuGet package for this. Right click on Packages

We can filter using the field in the upper right to quickly find relevant packages

Note there are many PostgreSQL packages we can pick from. I honestly dont know all the pro’s and cons of the different packages. I have used the Nppqsql package ands so far it works as I need & expect.

Select that package and add it to the project. You may see several other packages also get aded. When a package depends on another to be able to work the packages that are depended on are also brought in automatically.

In Xojo terms we’ve basically added a “plugin” – but only to this project. Projects in VS have “per project plugins”

In our code we’ll need to addd a using clause to let the compiler know it should expect references to this new plugin in this code.

using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using CloudKit;
using Einhugur.Forms;

using Mono.Data.Sqlite;
using Npgsql; // <<<<<<<<<<<<<<<<<

As well we need to adjust our connection so instead of using SQLite it uses PostgreSQL.

 // I deliberately left the variable name the same so you can see how
 // little needs adjustment

 // Mono.Data.Sqlite.SqliteConnection sqlite_conn;
 NpgsqlConnection sqlite_conn;

And the code where we create the connection needs to connect to the server

// sqlite_conn = 
// new SqliteConnection("URI=file:/Users/npalardy/testdb.sqlite;");

sqlite_conn = 
new NpgsqlConnection("Host=localhost;Username=XXXX;Password=XXXX;Database=norm_csharp");

The ONE other things we have to account for, since we’re using raw SQL. While the following will work for SQLite it wont work for PostgreSQL.

IDbCommand dbcmd = sqlite_conn.CreateCommand();
string sql = "create table if not exists employee ( firstname, lastname )";

SQLite is OK with an untyped create statement. PostgreSQL isn’t. So we do need to alter that as well.

IDbCommand dbcmd = sqlite_conn.CreateCommand();
string sql = "create table if not exists employee ( firstname varchar(50), lastname varchar(50) )";

And with that change everything should work again and now were using PostreSQL.

We could use a more generic data type for the now badly named sqlite_conn. Something more akin to Xojo’s Database. We could declare it as

            System.Data.IDbConnection sqlite_conn;

And our code could create & assign either a new sqlite connection or PostgreSQL one

Here’s the project as it exists so far.