Cabbage Logo
Back to Cabbage Site

Mouse Grid

I’m in the process of creating a ‘mouse-state’-based grid (see attached) Grid1x7Cab01.csd (2.8 KB). I don’t really have experience with declaring loops in general and tried as much as I could to synthesize the code so as to leave one variable that can increment by 1. Still, I tried ‘while’ and ‘loop_lt’ to no avail. If anyone can help with this I’ll greatly appreciate it!

I’ve looked at the examples included (re: Lots of Widgets), but I prefer a system like this one because I’d like the user to quickly set grid values on one click&drag motion if that makes sense? (Actually, I’d love to have a ‘grid widget’ (kind of like the live.grid object in Max), where one could easily define the number of columns and rows + bounds and get some kind of array/list value in return?).

Thanks!

Can you post the PNG image too?

Actually, what exactly are you trying to do here? I’ve looked through the code but it’s not that obvious to me?

Yes, sorry, here it is: Grid7

And you want to enable or disable a cell by clicking on it with the mouse?

It’s a similar concept to the ‘Lots of Widgets’ idea but without using checkboxes. Will try to post a video soon if that helps.

I can run your example here. Are you looking for a cleaner way of updating the grid image position?

Apologies, I broke the code while trying to create a loop declaration beforehand, please have a look at the new code and video.

Yes, that’s right: I’d like the image to move with the mouse but I thought of having some kind of automated way of checking (hence the loop), also so I can copy the code for as many columns as I would wish to have?

Grid1x7Cab02.csd (2.8 KB)

Grid7

MouseGrid2

Here’s a quick updated version. It’s not working the best because the height of your png is not a multiple of the grid image. But it not longer uses all those tests:

<Cabbage>
form caption("Mouse Gridx7") size(500, 500), colour(240, 240, 240), pluginId("def1") guiMode("queue")
nslider bounds (450, 10, 40, 20), channel ("num1"), range(1, 500, 1, 1, 1)
nslider bounds (450, 40, 40, 20), channel ("num2"), range(1, 500, 1, 1, 1)
nslider bounds (450, 70, 40, 20), channel ("num3"), range(1, 120, 1, 1, 1)

image bounds(10, 10, 16, 112), file("grid.png"), channel("pngImage")
image bounds(12, 12, 12, 12), channel("grid1"), colour("black"), toFront()

</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>

ksmps = 64
nchnls = 2
0dbfs = 1

instr 1
kms chnget "MOUSE_DOWN_LEFT"
kmx chnget "MOUSE_X"
kmy chnget "MOUSE_Y"
cabbageSetValue  "num1", kmx
cabbageSetValue  "num2", kmy

iPngBounds[] cabbageGet "pngImage", "bounds"

if kms == 1 then
    if kmx > iPngBounds[0] && kmx < iPngBounds[0] + iPngBounds[2] && kmy > iPngBounds[1] && kmy < iPngBounds[1]+iPngBounds[3] then
       kyPos = int((kmy-iPngBounds[0])/12)*12 
       cabbageSet 1, "grid1", "bounds", iPngBounds[0]+2, iPngBounds[1]+kyPos+2, 12, 12
    endif
endif

;cabbageSetValue "num3", kg1
endin

</CsInstruments>
<CsScore>
i1 0 z
</CsScore>
</CsoundSynthesizer>

I would probably create a UDO for each column. Then you can create as many as you like.

That’s great, thank you very much Rory! Very kind :slight_smile: I can always make a new image that fits the purpose. I’ll look into making an UDO out of it, will keep you posted (should go study your code now so I can learn it!).

So, I started toying with creating an UDO for it, might be overkill but it does help nonetheless. Then, I thought of including the ‘cabbageGet…’ + ‘cabbageSet…’ instructions as part of the UDO AND also to create the images with a ‘while’ loop and ran into a few more questions, if that’s OK?

Please see files attached, ‘Grid…5’ [a successful preliminary UDO] & ‘Grid…5b’ [attempting to create the images automatically]

  1. Is it possible to include Cabbage opcodes inside the UDO itself?
  2. When automating images through ‘cabbageCreate’ .png files don’t load? (see 5b) –– also, to avoid potential confusion, for 5b I was going to modify the UDO so it made all calculations based on a single cell (haven’t done that yet), hence the 2nd image (Bgd.png).
  3. BTW, SVG files are not loading (should probably reply to existing thread about it) –– I tried the SVG example included and it doesn’t work either for me (running yesterday’s beta on Catalina).

I think that’s it for now :slight_smile:

Thanks!!

Grid1x7Cab05.csd (3.5 KB)
Grid1x7Cab05b.csd (1.1 KB)
Grid7
Bgd

Yes. If you look at the custom xypad code I posted earlier you’l see this is exactly what I did.

That’s odd. I’ll take a look a little later and see if I can spot the problem. It looks like the code is fine.

Some of the images don’t load in that SVG example, I have to fix it. But the rslider should work fine? They load here without any problem. I will double check again later.

Looks like you’re making good progress :wink:

Ah beautiful! Will look into it!

Thanks! I’ll post any updates as I get to them. And thank you for your generous dedication! BTW, I saw the Simpler Sampler tutorial –– they’re really great: I learn to think differently (no allusion intended!) and learn many a trick with regards to coding :slight_smile:

1 Like

I’ve fixe the issue with loading images when working with the cabbageCreate widget. And I also updated some thing regarding the loading of SVGs. It should all work as expected now. But be warned that the SVG parser is pretty minimal. So something things might not render correctly. But for most basic paths. shapes and colours it should work just fine.

Thanks!! Will try them out…

Ok, so I’ve made some progress (see attached).

  • ‘cabbageCreate image widgets’ works well with both SVG & PNG.
  • I managed to port over all the grid creation & manipulation into a couple of UDOs (one for drawing the widgets, the other for mouse polling).
  • So, new issues to deal with:
    • I think I’m doing something wrong and creating an unnecessary burden on the patch/CPU with my mouse polling? It’s not the snappiest GUI performance but it works; however, I’m not sure what’s less elegant, whether to leave the system as it stands or get rid of the polling UDO and just create if statements in the instrument section?
    • For the life of me I couldn’t figure out how to init the grid to a ‘user setting’ (because they’re automatically created), or to create some kind of feedback mechanism so that I may merge a ‘forced’ kvalue (the array being returned from the grid) – with any input from the actual mouse/GUI, if that makes sense?

But at least in terms of ‘widget’ creation, I’ve managed to synthesize the grid parameters so they can be dynamically declared, which is pretty cool :slight_smile:

Looking forward to whatever feedback you may have!

P.S. - UPDATE (and interesting observation): as I was uploading the related files, I noticed that the ‘forum’ site doesn’t accept SVGs, so I recreated a version using only PNGs and all of the sudden, the runtime performed much better (the original using SVGs seemed sluggish to me, but I thought it was bad code design on my part –– that may very well still be the case, but it might be worth running a few tests on your end @rorywalsh to see if you can replicate a difference in performance (using SVGs vs PNGs)? (or maybe I’m just bugging :woozy_face:)

GridAuto05b.csd (4.8 KB)

I’ll look into those performance issues when I get a chance regarding the images. For now I did test your instrument, and it is indeed a performance hog. I rewrote some of it. I don’t see the need to output global vars from your UDO. You can simple set the values of those nslider widgets inside your UDO.

GridAuto05b.csd (4.4 KB)

It’s running better for me now, but it seems that one has to move all cells at least once first before it starts to run smoothly. But once they have been moved it runs pretty snappy, even without the metro(100). I have to run for lunch now but I’ll take another look later. I’m curious to know why we need to initialise each cell before we get to normal UI speed.

I’m not sure about this:

 if kms == 1 then
        ;if metro(100) == 1 then
            kmetro = kmetro + 1

You’re looping through each columns 100s of times of second, when you only really need to be updated the column the user is interacting with? I would make metro dependant on the mouse x position. I can test this out later, but now I really do need to grab lunch :rofl:

Thanks! I’ll check out your new version now (I just grabbed breakfast, as I’m in Colombia!). Yes I thought the whole metro thing wasn’t so Kosher, I’m also wondering if it’s not just easier to create individual ‘if’ checkers for each column (and turn those into an UDO). Will report soon!

Ah yes, that makes sense. I think it’s because initially I wasn’t thinking of using nsliders (that was to quickly show the output of the grid), but maybe is better to use them as the final value reference (and hide them from the GUI if don’t want them?).