Technology Update 2021

Progress Day 11/12 (the weekend)

Made some nice improvements to GTL over the weekend.

Firstly, the boolean flag expression stuff I mentioned above has been retro fitted into GTL so themes can now do more complex control state tests (eg: Focused && !Disabled)

class UglyButton
{
    Background:
    {
        Checked && Focused: Color.Red,
        Focused && !Disabled: Color.Blue,
        else: Color.Orange,
    }
}

Also, I’ve added support for template classes which are a way to more concisely express the settings for multiple similar elements.

To explain, consider the image on the play button:

class PlayButton : Button
{
    Image:
    {
        Pressed: Image("PlayButton_pressed.png", Center),
        Disabled: Image("PlayButton.png", Center).WithAlpha(0.5),
        else: Image("PlayButton.png"),
    }
}

Previously that would have to be repeated for every button: the pause button, the stop button, the record button, the metronome button etc. Given the number of images like this in Cantabile, that would get tedious and messy to maintain.

With templates, you can define a base class that synthesizes the bulk of that content from parameters:

class ToolbarButton<basename> : Button
{
    Image:
    {
        Pressed: Image(basename + "_pressed.png", Center),
        Disabled: Image(basename + ".png", Center).WithAlpha(0.5),
        else: Image(basename + ".png"),
    }
}

Then each button definition becomes a simple one liner:

class PlayButton : ToolbarButton<"PlayButton"> {}
class StopButton : ToolbarButton<"StopButton"> {}
class PauseButton : ToolbarButton<"PauseButton"> {}
// etc..

I’m sure there’ll be more tweaks to GTL going forward but for now, all its major features are done.

5 Likes

Progress Day 13

A slow day today… after making great progress on some fairly complicated controls, it was this stupid tab bar that tripped me up.

It took all day to get those button in the right place and to reposition themselves in a sane manner when the window is narrow:

On the plus side, I used GTL’s new template feature for the first time in Cantabile and it worked great. The two buttons for switching between table and wiring diagram view reduced down to just this:

class GroupButton<align,image>
{
    Background:
    {
        Pressed: NineSliceImage("Group" + align + ".png", 5, 5).Recolor(#404143),
        Selected: NineSliceImage("Group" + align + ".png", 5, 5).Recolor(#002d62),
        else: NineSliceImage("Group" + align + ".png", 5, 5).Recolor(#313235),
    },
    Image:
    {
        Pressed || Selected: Image(image + ".png", Center).Recolor(#FFFFFF),
        else: Image(image + ".png", Center).Recolor(#979797),
    }
}

class TableViewButton : GroupButton<"Left","TableView"> {}
class DiagramViewButton : GroupButton<"Right","DiagramView"> {}

Hopefully tomorrow will go a little smoother.

4 Likes

Them ol’ tabs are stupid for sure! :wink:

3 Likes

Progress Day 14

Finished the styling on the tab bar and also implemented the tab panel (ie: the surrounding container that holds the tabs and the content view for that tab). The fruity buttons are for testing that focus is maintained correctly when switching between tabs:

The combined level meter/slider is finished:

As is this incredibly exciting Toolbar Text Button:

So that’s four more controls ticked off the list.

rect1416

Also, unrelated, Mitchell asked me about interesting technical problem with his game that required some fun hacking… see here.

6 Likes

Continuing to read with interest.

The OO-speak mostly means little to me, but I’ve finally done some C++ coding for an Arduino-based hardware project during lockdown (no, it’s not a control surface!), so parts are at least now recognisable.

I now know enough C++ to be able to hate it properly. Bring back Commodore BASIC!

3 posts were merged into an existing topic: Learning OO languages

Progress Day 15

Today I started on the first of the three remaining controls that need to be ported: the horizontal picker control, better known as the ticker bar. (The other two are the wiring diagram view and the media player time line view).

This is a perfect example paying off some technical debt. I probably could have ported this control in a couple of hours, but instead decided to completely rewrite it.

When I originally wrote this control I kept it completely independent of any other views because I didn’t want to break anything else. This control essentially started off a modified copy of the list view that Cantabile uses for all its vertically scrollable lists. As such it had to handle everything - layout, painting, scrolling, touch scrolling, mouse wheel, keyboard, scroll animations etc…

Since then I’ve also added the set list grid which was implemented by updating the existing list view to support pluggable layouts - of which there was a vertical layout and a grid layout.

Further, I’ve also updated GuiKit so that scrolling and content management are separated. ie: the list view no longer really knows about scrolling. Instead, if a list view is wrapped in a scroll view it automagically becomes scrollable - including all the touch interactions, the over scroll animations and the scrollbars.

In other words, I’ve now got some much better options for implementing the ticker bar:

  1. By writing a new layout for the list view I get the horizontal appearance along with all the interactions that the list view supports.
  2. By wrapping in a scroll view I get all the touch and scroll interactions.

In other words, by leveraging the existing list and scroll view classes I get about 80% of the functionality. And that’s what I got working today.

It doesn’t look much but I’ve deleted a lot of code (the old horizontal picker) and although this required reworking a couple of things in the list and scroll views, it’s a much cleaner solution.

More importantly, now’s the right time to do it (since this is all going to need some heavy testing anyway).

It’s not finished though - I still need to sort out a few details:

  • calculating and adding margins so the view can be over-scrolled enough to let the first and last items appear centered.
  • auto homing - how after a couple seconds delay the view re-centers itself on the selected song.
  • theming

I would have liked to finished this control today, but I’m much happier with this new approach.

12 Likes

Progress Day 16

Some days just don’t work out… made good progress this morning on the ticker bar’s theming, centering, animations and keyboard/mouse interactions, but this afternoon while looking at the touch interaction I broke everything.

Setting it aside till fresh brain tomorrow :frowning:

2 Likes

Hi Brad,

I’m going to go back to making you a video of me using the current version with the Dell 2 in 1 11" laptop just to show some things that happen in routine use. I don’t think there are any bugs and that everything is working as Microsoft Windows dictates touch should work but I’m thinking that perhaps there should be some touchscreen options such as locking the the grid view horizontal scrolling and requiring the user to swipe a scroll bar to move across. Every time I want to tap the green VST active button the whole grid sails off to the right :grinning:

1 Like

Progress Night 16

Yesterday the code was fighting back and winning.

Last night after a couple of hours break I sat down with pencil and paper and planned out how to attack things today. Here’s the plan:

  • Easier Fake Touch switching in GuiKit. GuiKit has built in support for “fake touch” which lets me simulate a touch screen with mouse on my dev machines. This is great, but it requires a code change to enable it. Today I’m going to add a hot key to enable it. The idea is to reduce the friction to testing touch interactions so I can more easily switch and confirm both touch and mouse are working.

  • Move the centering code from the picker control itself into the list layout component. I suspect the way I’m keeping the buttons centered at the moment is interfering with some of the scrolling interactions. Baking it in directly into the layout should help.

  • Review and formalize some of the event notifications from GuiKit. There’s a bunch of notifications from GuiKit that the picker relies on (list selection change, selection gesture finished, scroll started/ended). I suspect there’s some conflicts, bugs or ordering issues there.

  • Look into adding a way to check if GuiKit is currently tracking any mouse/touch interactions and to register for a notification when finished.

  • Look into updating the method that starts scroll animations to update an already running flick and bounce animation to prevent interference between the two.

  • Move the horizontal picker into GuiKit - at least until it’s working. Yesterday I was getting too distracted when moving between Cantabile and GuiKit workspaces and having to build two projects.

After that, I’ll look into fixing the actual problem. I might not get it sorted today, but at least I’ve got some strategies that’ll get me close… and I will win in the end :slight_smile:

6 Likes

Progress Day 17

Success! The newly named TickerView has now been tamed and trimmed to a healthy 230 lines of code.

Since the ticker is fairly interactive and since there’s been a bit of discussion about OO coding here I thought I’d put together a little video with a quick scan through the code and then a look at the working result. You’ll notice in the video the cursor change to a round circle… that’s where I enable to the fake touch mode.

Also, I thought I’d get a head start on next weeks work by setting up the graphic assets for the timeline:

and the wiring diagram:

This week I was set back a day or two, but still within guessed time frame.

5 Likes

It’s good to see another mind working through the same problems as I’ve done most of my life. When I worked in an IT team we used to do the ‘cardboard cut-out’ method of bug-solving. in other words, as soon as you show the problem to another programmer you figure it out yourself - it’s a tried and true method!

We used to joke that every desk needed a cardboard cut-out of another programmer behind us!

I think the modern day equivalent is to ask a question on StackOverflow… so many times I’ve gone to ask a question and in the process of writing it up worked it out myself.

4 Likes

Progress Day 18

Somehow I managed to forget the MIDI Channel Bar control and since it’s an easy one decided to knock it off. Still needs some theming work, but coding is done:

Over the years, I’ve written this control 3 or 4 times now. This time, the new GuiKit made it almost trivial - about 200 lines of code.

9 Likes

Progress Day 19

Starting Monday, my main goal is to get the timeline and wiring diagrams ported to the new GuiKit. This is going to be a bit of work so I thought I’d give myself a bit of a head start.

Similar to the way I separated the scrolling and content in the ticker view I want to do the same thing with the time line view. Again, the idea is to save duplicating the code for all those touch/drag/zoom interactions.

So to make sure GuiKit was up to the task I put together a simple test program to experiment with all the geometry calculations. It looks a mess, but does the job:

To explain what’s going on there:

  • The time line is split into three main areas, from top to bottom: the time axis (dark gray), the content area (black area) and the scrollbar
  • The scrollbar, the time axis and the content area all need to have their geometry synced - which is confirmed with the numbers displayed in each (content offset 173.5…, content size 992.85).
  • The crossed out blue box is just there so I can see something happen when I zoom/scroll and make sure it’s in the correct place and size.

Unlike other views, when you zoom in the timeline things like fonts don’t get bigger, you just zoom in on the data - so in this case, zooming works by adjusting the content size, not the content scale factor. GuiKit didn’t handle this before, but it does now and all the touch, scroll and zoom interactions appear to be working correctly (and this time I actually tested it on a real touch screen device to be sure).

8 Likes

Progress Night 19

Last night I did some experimenting with vector graphics for the new theming engine in GuiKit…

First some background… GuiKit’s theming uses a concept of “drawables”. Drawables are anything that can be used to fill a region of the screen. eg: a button control has a background drawable that controls how the background area of a button is drawn.

Currently GuiKit supports these drawables:

  • Solid Color
  • Gradient Fill (horizontal or vertical)
  • Raster Image (ie: aka png)
  • Nine Slice Raster Image
  • Selector (which selects a drawable based on the control state, eg: pressed, checked, normal etc…)

As you can see the two image drawables are based on raster images. This works, but there are cases where vector assets would be a better choice - either for performance, size or maintainability reasons.

So last night I started adding some vector drawables:

  • Border - filled area with colored border on selectable edges
  • Ellipse - ellipses and circles
  • Rectangle - with optional rounded corners
  • Path - svg style path data shapes

Also, some new utility drawables:

  • Composite - combines multiple drawables into one (will probably rename to group)
  • Padded - adds padding space around another drawable and optional positioning within it (need a better name for this one).

Of these, the Path drawable is the most interesting because it uses SVG path data to draw shapes. eg: here’s path drawable using the shape data from Cantabile’s panic button:

I need to think carefully about how I use this because depending on the content, vectors can be either faster, or much much slower to render.

But I’ll come back to this tonight.

3 Likes

Very cool Brad!!

Progress Day 20

Made some good progress today starting with finishing off the theming of the MIDI Channel Bar that I didn’t get to on the weekend:

Then it was on to the timeline view. I’m taking a different approach with this one… instead of rewriting it (like the ticker view) or just porting it (all the others), this time I’m pulling it apart and putting it back together piece by piece using bits of the original codebase combined with the improved parts of GuiKit.

So far I’ve got the time axis and position markers appearing and all the scrolling and zooming is working. (The long string of numbers are the remnants of my weekend experiments - they’ll be gone soon).

This is a complicated control this one… it’s probably going to take a few days.

4 Likes

4 posts were split to a new topic: Select multiple channels for MIDI routing

Progress Night 20

More experimenting with vector artwork in GuiKit. Everything in the following video was authored in GTL (GuiKit’s Theming Language) without any references to external images.

GTL Vector Art Experiments

(To be clear, this is not GTL support for SVG… rather it just lets you copy path data from path nodes in a SVG file to create the shape outlines).

4 Likes