mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Update copyright and improve BLOCKS documentation
This commit is contained in:
parent
f88013e9b7
commit
169b5ede01
29 changed files with 127 additions and 126 deletions
|
|
@ -13,18 +13,18 @@ The concept of a BLOCKS topology and the methods for receiving callbacks from a
|
|||
|
||||
@section blocks_drawing_led_grid The LEDGrid Object
|
||||
|
||||
Lightpads have a 15x15 LED grid which can be accessed and controlled through the LEDGrid object, a pointer to which is returned by the Block::getLEDGrid() method (for more details on how the %LEDGrid object operates, see @ref controlling_led_grids). In the <code>topologyChanged()</code> method of <code>MainContentComponent</code> this %LEDGrid pointer is passed to the <code>setLEDProgram()</code> method, which sets the LEDGrid::Program to either a DrumPadGridProgram or BitmapLEDProgram, depending on the selected mode.
|
||||
Lightpads have a 15x15 LED grid which can be accessed and controlled through the LEDGrid object, a pointer to which is returned by the Block::getLEDGrid() method (for more details on how the %LEDGrid object operates, see @ref controlling_led_grids). In the <code>topologyChanged()</code> method of <code>MainComponent</code> this %LEDGrid pointer is passed to the <code>setLEDProgram()</code> method, which sets the LEDGrid::Program to either a DrumPadGridProgram or BitmapLEDProgram, depending on the selected mode.
|
||||
|
||||
@section blocks_drawing_colour_palette Colour Palette
|
||||
|
||||
In the colour palette mode the Lightpad displays a 3x3 grid of colours, constructed using the %DrumPadGridProgram class. A %DrumPadGridProgram pointer called <code>colourPaletteProgram</code> is declared as a private member variable of <code>MainContentComponent</code> and in the <code>MainContentComponent::setLEDProgram()</code> method this is set to point to a new %DrumPadGridProgram object and is passed the %LEDGrid object of the Lightpad in its constructor. After the program has been initialised, it is passed to the LEDGrid to display using the LEDGrid::setProgram() method and the layout of the grid is set up using the DrumPadGridProgram::setGridFills() method. This function takes 3 arguments: the number of rows, number of columns and an array of DrumPadGridProgram::GridFill objects containing a <code>GridFill</code> for each pad that controls its colour and fill type. The <code>ColourGrid</code> struct in MainComponent.h contains all of this information and handles the construction of the <code>GridFill</code> array in the <code>ColourGrid::constructGridFillArray()</code> method. An instance of this object called <code>layout</code> is declared as a member variable of <code>MainContentComponent</code> to easily change how the grid looks. The <code>ColourGrid::setActiveColourForTouch()</code> method is called in the <code>MainContentComponent::touchChanged()</code> callback and is used to determine which brush colour has been selected based on a Touch coordinate from the Lightpad.
|
||||
In the colour palette mode the Lightpad displays a 3x3 grid of colours, constructed using the %DrumPadGridProgram class. A %DrumPadGridProgram pointer called <code>colourPaletteProgram</code> is declared as a private member variable of <code>MainComponent</code> and in the <code>MainComponent::setLEDProgram()</code> method this is set to point to a new %DrumPadGridProgram object and is passed the %LEDGrid object of the Lightpad in its constructor. After the program has been initialised, it is passed to the LEDGrid to display using the LEDGrid::setProgram() method and the layout of the grid is set up using the DrumPadGridProgram::setGridFills() method. This function takes 3 arguments: the number of rows, number of columns and an array of DrumPadGridProgram::GridFill objects containing a <code>GridFill</code> for each pad that controls its colour and fill type. The <code>ColourGrid</code> struct in MainComponent.h contains all of this information and handles the construction of the <code>GridFill</code> array in the <code>ColourGrid::constructGridFillArray()</code> method. An instance of this object called <code>layout</code> is declared as a member variable of <code>MainComponent</code> to easily change how the grid looks. The <code>ColourGrid::setActiveColourForTouch()</code> method is called in the <code>MainComponent::touchChanged()</code> callback and is used to determine which brush colour has been selected based on a Touch coordinate from the Lightpad.
|
||||
|
||||
\image html BlocksDrawing_palette.JPG "Colour palette mode"
|
||||
|
||||
@section blocks_drawing_canvas Canvas
|
||||
|
||||
In canvas mode, the %LEDGrid program is set to an instance of %BitmapLEDProgram and uses the BitmapLEDProgram::setLED() method to set individual LEDs on the Lightpad to a particular colour. The <code>ActiveLED</code> struct declared in the private section of <code>MainContentComponent</code> is used to keep track of which LEDs are on and their colour and brightness. <code>MainContentComponent</code> contains an %Array of these objects called <code>activeLeds</code>.
|
||||
In the <code>MainContentComponent::setLEDProgram()</code> method the program is set up and passed to the %LEDGrid object the same way as in the colour palette mode but the <code>MainContentComponent::redrawLEDs()</code> method is also called which iterates over the <code>activeLeds</code> array and sets the appropriate LEDs on the Lightpad so the LED states persist between mode switches. When a Touch is received in the <code>MainContentComponent::touchChanged()</code> callback the <code>MainContentComponent::drawLEDs()</code> method is called with 4 arguments: x and y coordinates, touch pressure and brush colour. This method iterates over the <code>activeLed</code> array and checks to see if there is an active LED at the given coordinate. If it is blank, an <code>ActiveLED</code> object is created and added to the array with the given coordinates and colour using touch pressure for brightness. If there is already an active LED at the coordinate, the colour of that LED will be blended with the current brush colour, the proportion of which is determined by the touch pressure.
|
||||
In canvas mode, the %LEDGrid program is set to an instance of %BitmapLEDProgram and uses the BitmapLEDProgram::setLED() method to set individual LEDs on the Lightpad to a particular colour. The <code>ActiveLED</code> struct declared in the private section of <code>MainComponent</code> is used to keep track of which LEDs are on and their colour and brightness. <code>MainComponent</code> contains an %Array of these objects called <code>activeLeds</code>.
|
||||
In the <code>MainComponent::setLEDProgram()</code> method the program is set up and passed to the %LEDGrid object the same way as in the colour palette mode but the <code>MainComponent::redrawLEDs()</code> method is also called which iterates over the <code>activeLeds</code> array and sets the appropriate LEDs on the Lightpad so the LED states persist between mode switches. When a Touch is received in the <code>MainComponent::touchChanged()</code> callback the <code>MainComponent::drawLEDs()</code> method is called with 4 arguments: x and y coordinates, touch pressure and brush colour. This method iterates over the <code>activeLed</code> array and checks to see if there is an active LED at the given coordinate. If it is blank, an <code>ActiveLED</code> object is created and added to the array with the given coordinates and colour using touch pressure for brightness. If there is already an active LED at the coordinate, the colour of that LED will be blended with the current brush colour, the proportion of which is determined by the touch pressure.
|
||||
|
||||
\image html BlocksDrawing_canvas.JPG "Unleash your inner Picasso!"
|
||||
|
||||
|
|
|
|||
|
|
@ -9,19 +9,19 @@ BlocksMonitor is a simple JUCE application that shows currently connected Lightp
|
|||
|
||||
Navigate to the <tt>JUCE/examples/BLOCKS/BlocksMonitor/Builds/</tt> directory and open the code project in your IDE of choice. Run the application and connect your Blocks (if you do not know how to do this, see @ref connecting_blocks). Any devices that you have connected should now show up in the application window and this display will be updated as you add and remove Blocks. Lightpads are represented as a black square and will display the current touches as coloured circles, the size of which depend on the touch pressure, and Control Blocks are shown as rectangles containing the LED row and clickable buttons on the hardware. If you hover the mouse cursor over a %Block, a tooltip will appear displaying the name, UID, serial number and current battery level.
|
||||
|
||||
\image html BlocksMonitor.png "The BlocksMonitor application with a Lightpad and Control %Block connected"
|
||||
\image html BlocksMonitor.png "The BlocksMonitor application with a Lightpad and Control Block connected"
|
||||
|
||||
@section blocks_monitor_topology Topology
|
||||
|
||||
One of the fundamental concepts of the BLOCKS API is topology - a topology is a set of physically connected Blocks and the connections between them. Knowing when the topology has changed and accessing a data structure containing the current topology is the basis of any Blocks application.
|
||||
|
||||
To access the current topology, <code>MainContentComponent</code> inherits from the TopologySource::Listener base class and implements the TopologySource::Listener::topologyChanged() method, a callback which is used to inform listeners when any physical devices have been added or removed. In order to receive these callbacks, <code>MainContentComponent</code> contains an instance of the PhysicalTopologySource class and registers itself as a listener to this object in its constructor. When the <code>topologyChanged()</code> method is called, this object can be used to access the updated topology through the PhysicalTopologySource::getCurrentTopology() method which returns a BlockTopology struct containing an array of currently connected Block objects and an array of BlockDeviceConnection structs representing the connections between them.
|
||||
To access the current topology, <code>MainComponent</code> inherits from the TopologySource::Listener base class and implements the TopologySource::Listener::topologyChanged() method, a callback which is used to inform listeners when any physical devices have been added or removed. In order to receive these callbacks, <code>MainComponent</code> contains an instance of the PhysicalTopologySource class and registers itself as a listener to this object in its constructor. When the <code>topologyChanged()</code> method is called, this object can be used to access the updated topology through the PhysicalTopologySource::getCurrentTopology() method which returns a BlockTopology struct containing an array of currently connected Block objects and an array of BlockDeviceConnection structs representing the connections between them.
|
||||
|
||||
@section blocks_monitor_block_object The Block Object
|
||||
|
||||
The array of %Block objects contained in the %BlockTopology struct can be used to access individual %Block objects and determine their type using the Block::getType() method. The application uses this information to construct an on-screen representation of the currently connected Blocks by creating either a <code>LightpadBlockComponent</code> or <code>ControlBlockComponent</code> object for each %Block in the current topology. Both of these classes derive from <code>BlockComponent</code>, a relatively simple base class that contains some virtual functions for painting the %Block on screen and handling callbacks from the touch surface and/or buttons on the %Block. In its constructor, <code>BlockComponent</code> takes a reference to the %Block object that it represents and adds itself as a listener to the touch surface (if it is a Lightpad) and buttons using the Block::getTouchSurface() and Block::getButtons() methods, respectively. It inherits from the TouchSurface::Listener and ControlButton::Listener classes and overrides the TouchSurface::Listener::touchChanged(), ControlButton::Listener::buttonPressed() and ControlButton::Listener::buttonReleased() methods to call its own virtual methods, which are implemented by the <code>LightpadBlockComponent</code> and <code>ControlBlockComponent</code> classes to update the on-screen components.
|
||||
The array of %Block objects contained in the %BlockTopology struct can be used to access individual %Block objects and determine their type using the Block::getType() method. The application uses this information to construct an on-screen representation of the currently connected Blocks by creating either a <code>LightpadComponent</code> or <code>ControlBlockComponent</code> object for each %Block in the current topology. Both of these classes derive from <code>BlockComponent</code>, a relatively simple base class that contains some virtual functions for painting the %Block on screen and handling callbacks from the touch surface and/or buttons on the %Block. In its constructor, <code>BlockComponent</code> takes a reference to the %Block object that it represents and adds itself as a listener to the touch surface (if it is a Lightpad) and buttons using the Block::getTouchSurface() and Block::getButtons() methods, respectively. It inherits from the TouchSurface::Listener and ControlButton::Listener classes and overrides the TouchSurface::Listener::touchChanged(), ControlButton::Listener::buttonPressed() and ControlButton::Listener::buttonReleased() methods to call its own virtual methods, which are implemented by the <code>LightpadComponent</code> and <code>ControlBlockComponent</code> classes to update the on-screen components.
|
||||
|
||||
To visualise touches on the Lightpad, <code>LightpadBlockComponent</code> contains an instance of the TouchList class called <code>touches</code> and calls the TouchList::updateTouch() method whenever it receives a touch surface listener callback in the <code>LightpadBlockComponent::handleTouchChange()</code> method. The <code>LightpadBlock::paint()</code> method then iterates over the current TouchSurface::Touch objects in the %TouchList and visualises them on the component at 25Hz.
|
||||
To visualise touches on the Lightpad, <code>LightpadComponent</code> contains an instance of the TouchList class called <code>touches</code> and calls the TouchList::updateTouch() method whenever it receives a touch surface listener callback in the <code>LightpadComponent::handleTouchChange()</code> method. The <code>LightpadBlock::paint()</code> method then iterates over the current TouchSurface::Touch objects in the %TouchList and visualises them on the component at 25Hz.
|
||||
|
||||
The <code>ControlBlockComponent</code> class represents a generic Control %Block with 15 LEDs, 8 circular buttons and 1 rounded rectangular button. When a button is pressed on the physical Control %Block, the <code>BlockComponent::handleButtonPressed()</code> function is called and this class uses the ControlButton::ButtonFunction variable to determine which button was pressed and should be activated on the on-screen component. The same process is repeated for when the button is released. This class also overrides the <code>BlockComponent::handleBatteryLevelUpdate()</code> method to update which LEDs should be on based on the battery level, which is accessed in the <code>BlockComponent</code> base class using the Block::getBatteryLevel() and Block::isBatteryCharging() methods.
|
||||
|
||||
|
|
|
|||
|
|
@ -13,21 +13,21 @@ The concept of a BLOCKS topology and the methods for receiving callbacks from th
|
|||
|
||||
@section blocks_synth_note_grid Note Grid
|
||||
|
||||
In the synthesiser mode the Lightpad displays a 5x5 grid constructed using the DrumPadGridProgram class. The <code>SynthGrid</code> struct in <tt>MainComponent.h</tt> handles the setup and layout of this grid and sets the colours of the pads to white for tonics, green for notes in the C major scale and black for notes that are not in the C major scale. The <code>ColourGrid::getNoteNumberForPad()</code> method is called in the <code>MainContentComponent::touchChanged()</code> callback and returns the corresponding MIDI note number for a Touch coordinate on the Lightpad. This note number is then passed to the <code>Audio</code> class to be played on the synthesiser.
|
||||
In the synthesiser mode the Lightpad displays a 5x5 grid constructed using the DrumPadGridProgram class. The <code>SynthGrid</code> struct in <tt>MainComponent.h</tt> handles the setup and layout of this grid and sets the colours of the pads to white for tonics, green for notes in the C major scale and black for notes that are not in the C major scale. The <code>ColourGrid::getNoteNumberForPad()</code> method is called in the <code>MainComponent::touchChanged()</code> callback and returns the corresponding MIDI note number for a Touch coordinate on the Lightpad. This note number is then passed to the <code>Audio</code> class to be played on the synthesiser.
|
||||
|
||||
\image html BlocksSynth_grid.JPG "Synthesiser note grid"
|
||||
|
||||
@section blocks_synth_waveshape_display Waveshape Display
|
||||
|
||||
In the waveshape selection mode the LEDGrid::Program is set to an instance of BitmapLEDProgram and uses a Timer to draw moving waveshapes onto the LEDs of the Lightpad. In the constructor of <code>MainContentComponent</code> the <code>MainContentComponent::generateWaveshapes</code> method is called - this function generates 45 Y coordinates scaled and offset to fit the LED grid of the Lightpad for each of the 4 waveshapes and stores them in 4 separate arrays: <code>sineWaveY</code>, <code>squareWaveY</code>, <code>sawWaveY</code> and <code>triangleWaveY</code>. Then in the <code>MainContentComponent::timerCallback</code> method, a for loop iterates over the 15 LEDs on the X-axis and draws an LED 'circle' using the <code>MainContentComponent::drawLEDCircle()</code> method at the corresponding Y coordinate for the selected waveshape. The read position of the array is offset using the <code>yOffset</code> variable which is incremented each timer callback and wraps back around when the end of the array is reached to draw a 'moving' waveshape.
|
||||
In the waveshape selection mode the LEDGrid::Program is set to an instance of BitmapLEDProgram and uses a Timer to draw moving waveshapes onto the LEDs of the Lightpad. In the constructor of <code>MainComponent</code> the <code>MainComponent::generateWaveshapes()</code> method is called - this function generates 45 Y coordinates scaled and offset to fit the LED grid of the Lightpad for each of the 4 waveshapes and stores them in 4 separate arrays: <code>sineWaveY</code>, <code>squareWaveY</code>, <code>sawWaveY</code> and <code>triangleWaveY</code>. Then in the <code>MainComponent::timerCallback()</code> method, a <code>for</code> loop iterates over the 15 LEDs on the X-axis and draws an LED 'circle' using the <code>MainComponent::drawLEDCircle()</code> method at the corresponding Y coordinate for the selected waveshape. The read position of the array is offset using the <code>yOffset</code> variable which is incremented each timer callback and wraps back around when the end of the array is reached to draw a 'moving' waveshape.
|
||||
|
||||
\image html BlocksSynth_waveshape.gif "A sine wave dispayed in the waveshape selection mode"
|
||||
|
||||
@section blocks_synth_audio Audio
|
||||
|
||||
The <code>Audio</code> class handles the audio synthesis for this application and overrides the AudioIODeviceCallback::audioDeviceIOCallback() method to call the Synthesiser::renderNextBlock() method of a Synthesiser object. This object is initialised to be capable of rendering sine, square, sawtooth and triangle waves on separate MIDI channels in the constructor of <code>Audio</code>, and <code>Audio</code> contains methods for sending note on, note off, channel pressure and pitch wheel messages to the Synthesiser. When a note is triggered on the Lightpad, the <code>Audio::noteOn()</code> method is called with 3 arguments: a MIDI channel corresponding to the waveshape that should be generated, a MIDI note number and an initial velocity. Whilst the note is playing, the amplitude and pitch are modulated by calling the <code>Audio::pressureChange()</code> and <code>Audio::pitchChange()</code> methods from the <code>MainContentComponent::touchChanged</code> callback. The pressure value of the Touch instance is used to directly control the Synthesiser amplitude and the distance from the initial note trigger on the X-axis of the Lightpad is scaled to +/-1.0 and used to modulate the frequency of the currently playing note.
|
||||
The <code>Audio</code> class handles the audio synthesis for this application and overrides the AudioIODeviceCallback::audioDeviceIOCallback() method to call the Synthesiser::renderNextBlock() method of a Synthesiser object. This object is initialised to be capable of rendering sine, square, sawtooth and triangle waves on separate MIDI channels in the constructor of <code>Audio</code>, and <code>Audio</code> contains methods for sending note on, note off, channel pressure and pitch wheel messages to the Synthesiser. When a note is triggered on the Lightpad, the <code>Audio::noteOn()</code> method is called with 3 arguments: a MIDI channel corresponding to the waveshape that should be generated, a MIDI note number and an initial velocity. Whilst the note is playing, the amplitude and pitch are modulated by calling the <code>Audio::pressureChange()</code> and <code>Audio::pitchChange()</code> methods from the <code>MainComponent::touchChanged()</code> callback. The pressure value of the Touch instance is used to directly control the Synthesiser amplitude and the distance from the initial note trigger on the X-axis of the Lightpad is scaled to +/-1.0 and used to modulate the frequency of the currently playing note.
|
||||
The <tt>Oscillators.h</tt> file contains the waveshape rendering code. It contains an <code>Oscillator</code> base class which inherits from SynthesiserVoice and has a pure virtual <code>Oscillator::renderWaveShape()</code> method that is overridden by subclasses to render the 4 different waveshapes.
|
||||
|
||||
\image html BlocksSynth_waveshape.gif "The sine wave dispayed in the waveshape selection mode"
|
||||
|
||||
@section blocks_synth_summary Summary
|
||||
|
||||
This tutorial and the accompanying code project have expanded on the topics covered by previous tutorials, showing you how to display more complex programs on the %LEDGrid and how to control simple audio synthesis parameters using the Lightpad.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
|
||||
/**
|
||||
Represents an individual block device.
|
||||
Represents an individual BLOCKS device.
|
||||
*/
|
||||
class Block : public juce::ReferenceCountedObject
|
||||
{
|
||||
|
|
@ -33,29 +33,8 @@ public:
|
|||
/** Destructor. */
|
||||
virtual ~Block();
|
||||
|
||||
/** The Block class is reference-counted, so always use a Block::Ptr to
|
||||
keep references to them.
|
||||
*/
|
||||
using Ptr = juce::ReferenceCountedObjectPtr<Block>;
|
||||
/** The different block types.
|
||||
|
||||
/** The Block class is reference-counted, so Block::Array is a handy array
|
||||
type when working with lists of them.
|
||||
*/
|
||||
using Array = juce::ReferenceCountedArray<Block>;
|
||||
|
||||
/**
|
||||
*/
|
||||
const juce::String serialNumber;
|
||||
|
||||
/** The UID for a Block. */
|
||||
using UID = uint64;
|
||||
|
||||
/** This Block's UID. This will be globally unique, and remains constant for
|
||||
a particular device.
|
||||
*/
|
||||
const UID uid;
|
||||
|
||||
/** Preset types of block.
|
||||
@see Block::getType()
|
||||
*/
|
||||
enum Type
|
||||
|
|
@ -64,35 +43,45 @@ public:
|
|||
lightPadBlock,
|
||||
liveBlock,
|
||||
loopBlock,
|
||||
developerControlBlock,
|
||||
seaboardBlock,
|
||||
rotaryDialBlock
|
||||
developerControlBlock
|
||||
};
|
||||
|
||||
/** Returns the type of this device. */
|
||||
virtual Type getType() const = 0;
|
||||
/** The Block class is reference-counted, so always use a Block::Ptr when
|
||||
you are keeping references to them.
|
||||
*/
|
||||
using Ptr = juce::ReferenceCountedObjectPtr<Block>;
|
||||
|
||||
/** Returns a textual description of this device type */
|
||||
virtual juce::String getDeviceDescription() const = 0;
|
||||
/** The Block class is reference-counted, so Block::Array is useful when
|
||||
you are storing lists of them.
|
||||
*/
|
||||
using Array = juce::ReferenceCountedArray<Block>;
|
||||
|
||||
/** Returns the battery level in the range 0 to 1.0 */
|
||||
virtual float getBatteryLevel() const = 0;
|
||||
/** The Block's serial number. */
|
||||
const juce::String serialNumber;
|
||||
|
||||
/** Returns true if the battery is currently charging. */
|
||||
virtual bool isBatteryCharging() const = 0;
|
||||
using UID = uint64;
|
||||
|
||||
/** This Block's UID.
|
||||
|
||||
This will be globally unique, and remains constant for a particular device.
|
||||
*/
|
||||
const UID uid;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the width of the device in logical device units. */
|
||||
virtual int getWidth() const = 0;
|
||||
/** Returns the type of this device.
|
||||
|
||||
/** Returns the height of the device in logical device units. */
|
||||
virtual int getHeight() const = 0;
|
||||
@see Block::Type
|
||||
*/
|
||||
virtual Type getType() const = 0;
|
||||
|
||||
/** Returns the length of one logical device unit as physical millimeters. */
|
||||
virtual float getMillimetersPerUnit() const = 0;
|
||||
/** Returns a human-readable description of this device type. */
|
||||
virtual juce::String getDeviceDescription() const = 0;
|
||||
|
||||
/** Returns true if the device is a physical hardware block (i.e. not a virtual block). */
|
||||
virtual bool isHardwareBlock() const = 0;
|
||||
/** Returns the battery level in the range 0.0 to 1.0. */
|
||||
virtual float getBatteryLevel() const = 0;
|
||||
|
||||
/** Returns true if the battery is charging. */
|
||||
virtual bool isBatteryCharging() const = 0;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if this block is connected and active. */
|
||||
|
|
@ -105,14 +94,20 @@ public:
|
|||
*/
|
||||
virtual bool isMasterBlock() const = 0;
|
||||
|
||||
/** If this block has a pressure-sensitive surface, this will return an object to
|
||||
access its data.
|
||||
Note that the pointer returned does is owned by this object, and the caller must
|
||||
neither delete it or use it after the lifetime of this Block object has finished.
|
||||
If the device is not touch-sensitive, then this method will return nullptr.
|
||||
*/
|
||||
virtual TouchSurface* getTouchSurface() const = 0;
|
||||
//==============================================================================
|
||||
/** Returns the width of the device in logical device units. */
|
||||
virtual int getWidth() const = 0;
|
||||
|
||||
/** Returns the height of the device in logical device units. */
|
||||
virtual int getHeight() const = 0;
|
||||
|
||||
/** Returns true if the device is a physical hardware block (i.e. not a virtual block). */
|
||||
virtual bool isHardwareBlock() const = 0;
|
||||
|
||||
/** Returns the length of one logical device unit as physical millimeters. */
|
||||
virtual float getMillimetersPerUnit() const = 0;
|
||||
|
||||
//==============================================================================
|
||||
/** If this block has a grid of LEDs, this will return an object to control it.
|
||||
Note that the pointer that is returned belongs to this object, and the caller must
|
||||
neither delete it or use it after the lifetime of this Block object has finished.
|
||||
|
|
@ -133,13 +128,21 @@ public:
|
|||
*/
|
||||
virtual juce::Array<StatusLight*> getStatusLights() const = 0;
|
||||
|
||||
/** If this block has a pressure-sensitive surface, this will return an object to
|
||||
access its data.
|
||||
Note that the pointer returned does is owned by this object, and the caller must
|
||||
neither delete it or use it after the lifetime of this Block object has finished.
|
||||
If the device is not touch-sensitive, then this method will return nullptr.
|
||||
*/
|
||||
virtual TouchSurface* getTouchSurface() const = 0;
|
||||
|
||||
/** If this block has any control buttons, this will return an array of objects to control them.
|
||||
Note that the objects in the array belong to this Block object, and the caller must
|
||||
neither delete them or use them after the lifetime of this Block object has finished.
|
||||
*/
|
||||
virtual juce::Array<ControlButton*> getButtons() const = 0;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** This returns true if the block supports generating graphics by drawing into a JUCE
|
||||
Graphics context. This should only be true for virtual on-screen blocks; hardware
|
||||
blocks will instead use the LED Grid for visuals.
|
||||
|
|
@ -200,10 +203,12 @@ public:
|
|||
using Timestamp = uint32;
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
Block (const juce::String& serialNumberToUse);
|
||||
|
||||
juce::ListenerList<DataInputPortListener> dataInputPortListeners;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Block)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
|
||||
/**
|
||||
Represents the touch surface of a block device.
|
||||
Represents the touch surface of a BLOCKS device.
|
||||
*/
|
||||
class TouchSurface
|
||||
{
|
||||
|
|
@ -41,55 +41,62 @@ public:
|
|||
int index;
|
||||
|
||||
/** The X position of this touch on the device, in logical units starting from 0 (left).
|
||||
|
||||
See Block::getWidth() for the maximum X value on the device.
|
||||
*/
|
||||
float x;
|
||||
|
||||
/** An approximation of the velocity at which the X value is changing.
|
||||
Measured in units/second. This is intended as a useful hint to help with gesture
|
||||
detection, but may be 0 if the device doesn't provide this data.
|
||||
/** An approximation of the velocity at which the X value is changing, measured in
|
||||
units/second. This is intended as a useful hint to help with gesture detection, but
|
||||
may be 0 if the device doesn't provide this data.
|
||||
*/
|
||||
float xVelocity;
|
||||
|
||||
/** The Y position of this touch on the device, in logical units starting from 0 (top).
|
||||
|
||||
See Block::getHeight() to find the maximum Y on the device.
|
||||
*/
|
||||
float y;
|
||||
|
||||
/** An approximation of the velocity at which the Y value is changing.
|
||||
Measured in units/second. This is intended as a useful hint to help with gesture
|
||||
detection, but may be 0 if the device doesn't provide this data.
|
||||
/** An approximation of the velocity at which the Y value is changing, measured in
|
||||
units/second. This is intended as a useful hint to help with gesture detection, but
|
||||
may be 0 if the device doesn't provide this data.
|
||||
*/
|
||||
float yVelocity;
|
||||
|
||||
/** The current pressure of this touch, in the range 0 (no pressure) to 1 (very hard) */
|
||||
/** The current pressure of this touch, in the range 0.0 (no pressure) to 1.o (very hard). */
|
||||
float z;
|
||||
|
||||
/** The rate at which pressure is currently changing.
|
||||
Measured in units/second. This is intended as a useful hint to help with gesture
|
||||
detection, but may be 0 if the device doesn't provide this data.
|
||||
/** The rate at which pressure is currently changing, measured in units/second. This is
|
||||
intended as a useful hint to help with gesture detection, but may be 0 if the device
|
||||
doesn't provide this data.
|
||||
*/
|
||||
float zVelocity;
|
||||
|
||||
/** The timestamp of this event, in milliseconds since the device was booted. */
|
||||
Block::Timestamp eventTimestamp;
|
||||
|
||||
/** True if this is the first event for this finger. */
|
||||
/** True if this is the first event for this finger/index. */
|
||||
bool isTouchStart;
|
||||
|
||||
/** True if this is the final event as this finger is lifted off. */
|
||||
/** True if this is the final event as this finger/index is lifted off. */
|
||||
bool isTouchEnd;
|
||||
|
||||
/** The ID of the block that generated this touch. */
|
||||
Block::UID blockUID;
|
||||
|
||||
/** The initial X position of the touchStart event corresponding to this finger. */
|
||||
/** The initial X position of the touchStart event corresponding to this finger/index. */
|
||||
float startX;
|
||||
|
||||
/** The initial Y position of the touchStart event corresponding to this finger. */
|
||||
/** The initial Y position of the touchStart event corresponding to this finger/index. */
|
||||
float startY;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Forces a touch-off message for all active touches. */
|
||||
virtual void cancelAllActiveTouches() noexcept = 0;
|
||||
|
||||
//==============================================================================
|
||||
/** Receives callbacks when a touch moves or changes pressure. */
|
||||
struct Listener
|
||||
{
|
||||
|
|
@ -98,30 +105,24 @@ public:
|
|||
virtual void touchChanged (TouchSurface&, const Touch&) = 0;
|
||||
};
|
||||
|
||||
/** Adds a listener to be called when there's a change to this surface. */
|
||||
void addListener (Listener*);
|
||||
|
||||
/** Removes a previously-registered listener. */
|
||||
void removeListener (Listener*);
|
||||
|
||||
/** For a Seaboard unit, this will return the number of keys.
|
||||
For other types of touch-surface, it will return 0.
|
||||
*/
|
||||
virtual int getNumberOfKeywaves() const = 0;
|
||||
|
||||
/** The block that owns this touch surface. */
|
||||
Block& block;
|
||||
|
||||
/** Testing feature: allows you to inject touches into a touch-surface. */
|
||||
/** Testing feature: this allows you to inject touches onto a touch surface. */
|
||||
void callListenersTouchChanged (const TouchSurface::Touch& t)
|
||||
{
|
||||
listeners.call (&Listener::touchChanged, *this, t);
|
||||
}
|
||||
|
||||
/** Forces touch-off messages for all active touches. */
|
||||
virtual void cancelAllActiveTouches() noexcept = 0;
|
||||
/** Adds a listener to be called when the surface is touched. */
|
||||
void addListener (Listener*);
|
||||
|
||||
/** Removes a previously-registered listener. */
|
||||
void removeListener (Listener*);
|
||||
|
||||
//==============================================================================
|
||||
/** The block that owns this touch surface. */
|
||||
Block& block;
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
juce::ListenerList<Listener> listeners;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TouchSurface)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
@ -1416,11 +1416,6 @@ struct PhysicalTopologySource::Internal
|
|||
det->activeTouchSurfaces.removeFirstMatchingValue (this);
|
||||
}
|
||||
|
||||
int getNumberOfKeywaves() const noexcept override
|
||||
{
|
||||
return blockImpl.modelData.numKeywaves;
|
||||
}
|
||||
|
||||
void broadcastTouchChange (const TouchSurface::Touch& touchEvent)
|
||||
{
|
||||
auto& status = touches.getValue (touchEvent);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2015 - ROLI Ltd.
|
||||
Copyright (c) 2016 - ROLI Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue