Question on widgets for classic mac os

Does Symantec projects not have a concept of multiple targets? Might be time to upgrade to Metrowerks. You can set that up to build everything with a single key press using multiple targets and dependencies.

You can look at the Metrowerks code resource examples and see how they might translate to Symantec.

MPW may also have examples.

Inside AppMaker CD #12, there's a "Third Party Products" folder which contains "Jims CDEFs v1.51".
I can't find AppMaker CD #12 online, but "Jims CDEFs v1.50" and a 1.51 update exist at Info-Mac. Search for "Jim's CDEFs"
https://info-mac.org/viewtopic.php?t=2567
https://info-mac.org/viewtopic.php?t=2568

Modeless dialogs (including multiple windows) example mentioned at https://68kmla.org/bb/threads/pop-up-menus-on-system-6.50915/post-574130 with static text elements, buttons, and pop-up menus (if you don't mind reading Pascal).

Would the Piano be a single control, such that you can use TrackControl to drag a mouse across all the piano keys?
 
Does Symantec projects not have a concept of multiple targets? Might be time to upgrade to Metrowerks. You can set that up to build everything with a single key press using multiple targets and dependencies.

I wrote about my experience of using Metrowerks' multiple target support as one of the steps toward creating MacRelix:


Would the Piano be a single control, such that you can use TrackControl to drag a mouse across all the piano keys?

If your piano is limited to 88 keys (which ought to be enough for anybody), you could regard each key as a separately highlightable indicator. I don't like how close it is to the upper bound of 125 or so, though that can be overlooked. But the design of control tracking is that you hit-test to see which indicator you clicked in, and then track that indicator. So you could only track a single key that way, not multiple keys. You definitely wouldn't want each key to be its own control.

You could have a single indicator as in a scroll bar, with a value ranging from 0 (no key) to 1 (lowest key, e.g. A0) to N (highest key, e.g. C8 for N=88). As you drag, instead of drawing a thumb in different locations and scrolling a document, you invert various key regions and alter the sound being played. You might need some special handling to set the value back to zero after tracking.

Another way is not to use a control at all, and handle the events yourself. That's how I did it in Organ Console (which comes with Legacynth as one of its test apps), though I was focused on handling keyDown / keyUp events first.
 
I was able to make it work in this specific combination:

* the whole 88 key piano is an entire single custom CDEF control
* inside the CDEF, the initCntl message has me calculated regions for each key for the sake of painting their highlights when they are "activated". The white keys have to DiffRgn away neighboring black keys when they are immediate neighbors, of course. it's also here that I stash specific Patterns I'll use, since I don't have access to A5 globals (I know I can pass a message, but meh, too much hassle for little gain)
* the testCntl simply checks if a mouse click location makes PtInRgn return true, based on the previously calculated regions
* drawCntl is reserved for the initial full drawing of the piano at the start of the program or for update events
* a custom message of '100' is reserved for when I need just one note to be redrawn
* I have helper functions that determine how to place black keys over white keys, detect if a key is white or black depending on the index from 0 to 87, etc.
* Using global arrays inside the CDEF in general was fraught with peril. Instead, I generate stuff with loops inside functions to make sure I don't have corrupted references - wild stuff that sent me in rabbit holes of debugging

in my main program
* I keep just one ControlHandle for the whole piano
* I let the regular update scheme of a window call its drawCntl just fine to redraw when needed (ie during an invalidrgn situation)
* in the event loop, where I would deal with an event record switch-case, I added a "mousePianoTracking" boolean check, followed by StillDown() check to let glissando note changes happen with a held down mouse click
* the most convoluted stuff though is in the function that's about to dispatch my sounds, regardless of destination, will ride a pascal long pointer like so:
proc = (CDEFProcPtr)*((*cPiano)->contrlDefProc);
which I use to send a message of '100' to trigger a one note redraw from inside the CDEF.

CDEFProcPtr is defined as:
typedef pascal long (*CDEFProcPtr)(
short varCode,
ControlHandle c,
short message,
long param
);

about 2 weeks of frustrations, but I'm very, very happy where I landed.

special thanks to joevt for his excellent suggestions, once again

See video results here:
 
Last edited:
Back
Top