|
|||
|
Core Graphics AudioUnit GUI CAUGUiSDK is now XCode/Panther/CoreAudio SDK 1.3.1 savvy The example project passes AUValidation Tool download CAUGuiSDK 1.0 with documentation browse documentation online |
|||
easy implementation: For average use, you only need to make CAUGui's manager object (of class CAUGuiMan) a member of your gui class. In createUI() you instantiate the manager, and then subsequently add Images/Graphics objects, one or more Panes to it. Inbetween you create Control objects or nested panes that you add to these panes. Due to CoreAudio's notification scheme, you don't have to worry about dispatching events or such anymore. This makes it all less hassle. When your GUI gets destroyed, you only have to destroy the manager class which then tidies everything up and releases any ressources. I think this makes it quite comfortable to implement. Ann.: As of today, loaded bitmaps are not static data. I'm gonna change this soon, hopefully in a way that data gets shared even accross several different AUViews if they're in the same Bundle. |
|||
using CoreGraphics: CAUGui stands for CoreGraphics AudioUnit Graphical User Interface. It doesn't make much use of QuickDraw. CoreGraphics has a lot of nice advantages over QuickDraw: Easy alphablending (transparency), instant antialiasing, image transformations (incl. scale & rotate). Hence you don't have to accomplish Photoshop orgies to get those precomposited stacked images for nice looking Knobs. |
|||
Control functionality vs. graphical representation: Speaking of paradigms, in VSTGUI for example, you add graphics to control objects and the control objects decide how to paint the graphics. This is not the case in CAUGui. It seperates user interaction (control object) from representation (graphics object). Thus you can combine any type of user interaction (slider-like dragging, knob-stirring, button pushing or just watching) with any type of visual feedback (textual value representation, animated graphics, moving handles, transparency by value etc.). |
|||
Controls: Controls are usually tied to AUVParameters from which they inherit a Range (min-max, i.e. -50.f - +50.f) and set up a custom carbon control that takes advantage of the notification scheme in AUBase/AUView APIs. Furtherly, they typically get a resolution that reflects the parameter's granularity. Continuous parameters might get a 100th resolution while indexed parameters best work with 1/1 resolution :-) The common control object wants a foreground graphic (value representation) and a background graphic (what it says). If the foreground graphic doesn't sport any transparency, you can leave away the background. Knob: A knob control transforms radial mouse input ("stirring") to values in the range of an AUVParameter. If you just stirr it with the mouse, you get all the integer values in the Parameter's range. If you press shift, you also get the fine resolution. When pressing alt/option, you get a horizontal slider-like behaviour. Knobs usually get "SpinImages" attached that display radial rotation. Slider: A slider (or fader, if you like that more) can be determined vertical or horizontal. Shift sends them in fine-mode and every 2 pixels of dragging represent one step in the fine resolution. Sliders usually get "HandleImages" attached, that move along a specified rectangle to represent the value. But you could also use a VU-Meter type "CroppingImage" that displays only a portion of itself according to the value of the control. BTW sliders can be used to implement "Switches", "RockerSwitches" and other stuff if they are attached to indexed parameters. Display: A display in CAUGui is not just what it says. Of course, it is meant to display values, either by a graphics object or by a text generation callback, but it also receives mouse events. It changes values in two ways: If the resolution is 1/1, it works like a coarse grained vertical slider. If the resolution is higher, say 10th, 50th or 100th, the left half of the display acts as a coarse slider while the right side acts fine grained. Thus you don't have to access the shift key to easily change fine values. Buttons: Buttons come in various flavours and do a bit more than just trigger anything. Okay, they can trigger userdata contaminated callbacks, but they can also act as radio buttons (representing one value in the range of an indexed parameter), as incrementors/decrementors (oops, I need to add that shift/fine thing here) or as the usual pushbuttons (setting maxvalue on mousedown, minvalue on mouseup). Panes: Panes are the soul of layout. The simple pane gets a background image (or not) and the you can add control objects (including more panes) in pane-relative coordinates. The root-control in a CAUGui-driven AUView should be a simple pane with the background image attached. A special pane is the "LayeredPane". It's abit like "tabbed panes". - It receives controls as usual but can also get controls added with a layerindex specified. Thus you can make groups of controls visible or hidden by a button that iterates the layers with one visible at a time. Quite simple screen estate saver. Of course, layers can optionally display individual background images. There are some more Control types like Meters and Selectors. See the docs for details. Future control functionality: I'm trying to find a workaround for the limitation of one AUVParameter attached to one Carbon Control. Dunno much about notification and listeners, yet. We'll see what 2003 brings. |
|||
Graphics: The common way to import an images into CAUGui is from PNG files. These can be either 8-Bit (with pixel-based transparency) or 24-Bit (with smooth alphablending). I'm working on importing PICT-resources, too. CAUGuiGraphic: The trivial graphics object is an image or a stack of images that simply draw. SpinImages: These are meant for rotation tasks. There are two modes available: fixed and rotating. "Rotating" means that the specified images gets rotated around a center point (pivot) while "fixed" keeps the image's orientation and orbits that around the pivot (which typically resides outside the image itself). Minimum and maximum angle can be set as well as the preferred pivot (if not set by the control object). HandleImages: Your control passes a rectangle and a value, and this type of image moves along the rectangle (along the direction it fits best). It also has a pivot, that corresponds to the mousespot. The value is mapped over the whole width or height of the rectangle, so the image can extend the rectangles boundaries on small or high values. - I think, this is easier to setup, providing a rectangle like height = 10px, width = 100px and then the image is proportionally scaled to match the 10px and the active area will be 100px. (But I'll add an optional convenience function to sliders that keeps the image inside the bounds.) CroppingImages: These draw only portions of themselves according to the value and boundaries passed by the controls. You can specify the direction of the crop and if the image should be shifted along with the value. Good for VU_Meter type of controls (displays), eh? Yeah, and they do scaling as well. |
|||
Some Q&As: What about About-boxes? - Uhm, make a new window on a button's user procedure or implement the rootpane by a LayeredPane? What's that "Poof"-thing in the SDK? - It's the beginning of a funny control type. Currently, it's a button that displays a transparent window with an "stack"-animated image (5 frames) at the mouse position. Who knows what can be made up from that? Where's offscreen-drawing? - Palim palim! Not needed with CoreGraphics drawing. No flickering. What if controls draw outside themselves? - They can't. 'tis all done with a clipping region. What about performance? - Dunno. May all be slower than QD drawing. But what gives? There are some prevention-of-unnecessary-draws type of functions inside. I think, the benefits of CG outpace the performance trade-offs (if there are any). What about Fonts? - Okay, it's one Font & colour to be specified in the config-file. But you can alter the Font and Colour for each single control now (but not for Graphics...). What about non-host-visible parameters? - There's an internal parameter scheme which fetches internal values during idle()-calls (did I mention these?). Controls can access these via the manager class. - Howbeit, this my be obsolete if write-only, read-only parameters are set in stone (which I now think it is by using "private" AU parameters...). idle()? - Every control receives idle()-calls on a timer-based mechanism. |
|||
|
|