Technology Update 2021

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

Progress Day 21

More progress on the timeline:

  • Focus management of selected marker/content view
  • Keyboard interaction to scroll and move markers (including fine and coarse mode)
  • Dragging of play position and range markers (including snap/no-snap)
  • Properties for all the marker positions and view ranges
  • Notifications when scroll, move marker, play position etc…
  • Zoom In/Out/ToMarkers/ToPlayPosition
  • Content renderer wired up. (I won’t be hooking up real MIDI/audio data in this view yet because I need the audio engine for that… so I’ve just plugged a content renderer that draws a big X)

Still lots of fiddly things to sort out:

  • Test Labels
  • Label hit testing and selection
  • Stretch view range when view resized?
  • Auto-scroll when current position moved programmatically
  • Larger hit area for handles on touch screens
  • Clicking a label should move current position
  • Suppress dangerous click when giving focus
  • Cursor highlight
  • Z + click and drag to zoom
  • Alt + click and drag to set play range
  • Only fire range marker changed on drag release
  • Maintain range marker order and update play position
  • Test with null timescale
  • Overscroll past end
  • Testing, testing, testing…

I’m hoping to get most, if not all of that knocked off tomorrow.

9 Likes

Progress Day 22

Timeline view finished. Nothing new to show because it looks the same as yesterday, but everything on the todo list in the previous post is done.

Nice bonus… even though I’ve added a bunch of XML doc comments, the code for the new timeline is only 80% of the size (by line count) of the old one - primarily because I’m leveraging cool stuff in the new GuiKit.

Tomorrow I’ll give it some more testing and final tidy up of the code before moving on to the last GUI control - the wiring view.

10 Likes

Progress Day 23

Today I started on the Wiring View. This is another fairly complicated control but since it was developed after the original version of GuiKit’s ScrollView class I don’t need to tease out the scrolling code this time.

Porting requires addressing two major areas:

  1. Converting its theme to GTL.
  2. Reworking the mouse/touch interactions

Today’s job was the theming which involved converting this wall of code:

to this nicely structured GTL and updating the wiring view to use it - which it now does:

Tomorrow’s I’ll be converting a gigantic 600 line function that does all the mouse/touch click and drag interactions into a series of clean GuiKit gesture handlers.

5 Likes

I’ve become used to the table view but at the beginning I remember losing quite some time troubleshooting some copied/pasted blocks and was unaware of multiple routes from same source to the same plugin. This info is clearly evident in table view but gets lost in diagram view. Is some improvement planned here?
Regards,
Matej

1 Like

Hi @matejb,

Right now I’m just aiming to match the existing functionality but I was thinking about how to address this problem and one thought was to simply offset the wires so you can there are multiple, something like this:

No promises, but would that help?

Brad

3 Likes

Hi Brad, it would sure very much help. Personally I now actually prefer the table view as it provides much more functionality and metering, but for those who prefer the simple diagram view your offset suggestion would solve and eliminate trouble I had at the beginning.
Thanks and regards,
Matej

1 Like

Hi Brad, Great work! Have you given any thought to making the psuedo-presets list dynamic? Kind of like the set lists or states.

Thanks,
John

Hi @Jtoth,

I have, but not as this part of this batch of work. I’ve logged it here for now.

Progress Day 24

When I originally wrote the WiringView I was on a time push to get it done. I remember thinking at the time that I should separate out the different UI interactions but laziness won and I left it as a bit of a mess.

So today was the tedious job of separating out all those UI interactions. That’s now done and everything is working again.

Technical side note for the devs: One thing I’ve found that’s been working really well in this work is using closures to maintain the state. For example this is the code that handles the “click’n’drag box selection” action:

Previously I would have implemented this with either a separate nested class or a bunch of member variables to maintain the state. Instead I’m now using closures to encapsulate everything to do with this action into a single function. The WiringView’s entire UI interaction model is now is just a bunch of functions like this:

(end side note)

Now that the WiringView is done, the porting of Cantabile.Gui is complete and I’ve got a nice collection of cleaned up, refactored, ported, documented controls ready to go.

I’m probably going to take a couple of days break now since I’ve been at this for over 3 weeks straight. After that these posts will become more sporadic as the next task is a bit of a black box and I won’t have much to show until it’s done.

10 Likes

Well done - have a coffee and a bun! :+1:

2 Likes

Thanks! (But I’m thinking more along the lines of Bourbon and snacks. :slight_smile:)

6 Likes

Have a “Steam goat” beer - one of my favourite Aussie beers (along with Coopers) when I was in Melbourne. Seems like a lifetime ago, but I can still taste that Steam goat!

2 Likes

Weekend Update

Earlier in the week I mentioned working on adding vector support to GuiKit’s theming capabilities. I’ve now completed that work and converted GuiKit’s two built-in themes to exclusively use vectors (instead of pngs at multiple resolutions).

I’m really pleased with the result because:

  1. The final themes packages are much smaller…

old:

image

vs new:

image

  1. They’re now infinitely scalable with no pixelation artefacts. Full screen radio buttons anyone? Ah the crispness.

  1. They’re just as performant because the vector data is rasterized on demand. eg: note the Rasterize() call on the first line of the GTL code to make a checkbox:
var makeCheckBox = (fillColor, borderColor, checkColor) => Rasterize()
{
    Size: (13,13),
    Inner: [
        BorderFrame(fillColor, borderColor),
        Frame()
        {
            Padding: 2,
            Inner: Path()
            {
                SvgData: "M 11.091797,2.7460938 A 0.625,0.625 0 0 0 10.646484,2.921875 L 5.1484375,8.2480469 3.1035156,6.0507812 a 0.625,0.625 0 0 0 -0.8828125,-0.03125 0.625,0.625 0 0 0 -0.03125,0.8828125 l 2.4785156,2.6640626 a 0.6250625,0.6250625 0 0 0 0.8925782,0.021484 L 11.515625,3.8203125 A 0.625,0.625 0 0 0 11.53125,2.9355469 0.625,0.625 0 0 0 11.091797,2.7460938 Z",
                FillColor: checkColor,
                MaintainAspectRatio: true,
            }
        }
    ]
};
  1. They’re a little harder to setup, but much easier to maintain and re-use. eg: instead of drawing a bunch of radio button images, I can now programmatically generate them for each state:
Checked && Disabled: makeRadio(colorDisabledFill, colorDisabledBorder, colorDisabledBorder),
Disabled: makeRadio(colorDisabledFill, colorDisabledBorder, Color.Clear),
Checked && Pressed: makeRadio(colorFocus, colorFocus, Color.White),
Pressed: makeRadio(colorFocus, colorFocus, Color.Clear),
Checked && Focused: makeRadio(colorFill, colorFocus, Color.White),
Checked: makeRadio(colorFill, colorBrightBorder, Color.White),
Focused: makeRadio(colorFill, colorFocus, Color.Clear),
else: makeRadio(colorFill, colorBrightBorder, Color.Clear),
  1. The Light theme just imports the Dark theme and overrides the colors. Again, this reduces maintainance because most theme changes only need to be done in one place. This is the entire Light theme gtl file:
// GuiKit Standard Light Theme

// Start with Dark theme
import("GuiKit.Dark");

// Redefine colors...
var colorForm = #f5f5f5;
var colorText = #000000;
var colorScrollbar = #f5f5f5;
var colorScrollbarThumb = #C2C3C9;
var colorFocus = #0095fe;
var colorDisabledFill = #F5F5F5;
var colorDisabledBorder = #BBBBBB;
var colorDisabledText = #808080;
var colorFill = #FFFFFF;
var colorBorder = #AAAAAA;
var colorBrightBorder = #666666;
var colorButtonFill = #ECECF0;
var colorButtonBorder = #ACACAC;
var colorSubtleText = #333333;
var colorProgressBar = #00b200;

I even went to the trouble of reducing banding in linear gradients. It’s a subtle change, but stops my eyes bleeding:

I still need to convert Cantabile’s themes to a similar approach, but I’ll do that as a side project in parallel with on-going development - but will definitely aim to getting it finished before releasing this Tech Update.

11 Likes

Great job Brad!

2 Likes

Quick update… spent most of this week on support and build 3695 with the new bindings changes.

Also, I was looking into some possible issues with MIDI timing (turned out to be no issues so far anyway) and dug out an old feature from Cantabile 2 - MIDI port recording. This was the ability for Cantabile to capture everything it received from a MIDI port to a file that I can then list out or replay. You’ll notice build 3695 has a new setting in Options -> Diagnostics to enable MIDI-In port recording.

The tool that I use to work with those recordings is called “PortPlay” and hadn’t been rebuild since before I started work on Cantabile 3. So I cleaned it up an got it working again, but it lead me down a bit of a side path…

For all my C++ projects I use a library I developed probably 15+ years ago called SimpleLib - it’s a lightweight template library for C++ with it’s main advantage being it’s not std/stl - which I mostly despise. A cut down version of the original SimpleLib is also used in Cantabile 3’s core C++ audio engine.

Anyway, I decided it was time to give SimpleLib a refresh - removed obsolete functionality, cleaned up what was left, added some new stuff, merged in some stuff from Cantabile that has broader appeal and, got it working on Windows (msvc) and Linux (gcc).

It’s available here if you’re interested, but it’s still very much a work in progress.

Currently includes:

  • Vector, Map, KeyedArray and RingBuffer collection classes
  • String class with support for various character widths (char, wchar_t, char32_t) along with StringBuilder class
  • utf8, utf16 and utf32 character conversion
  • Cross platform sprintf-style formatter (ie: CString::Format works the same on all platforms)
  • Path manipulation functions
  • File and Memory streams
  • More to come…

The best thing about SimpleLib though - it’s just a bunch of header files, no lib to build - include the header, get the stuff.

Anyway, all this reminded just how much I really don’t like C++ :frowning: and I’m looking forward to next week when I’ll return to updating Cantabile to GuiKit3. :slight_smile:

5 Likes

It’s Monday morning and this week’s job is to get the rest of Cantabile building against the new GuiKit.

This is my starting point:

4 Likes

Brad, see the good side, you’ve 71 warnings only. :upside_down_face: Just kidding

2 Likes