forked from hsstraub/TerpstraSysEx.2014
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add adjust layout colour helper class
- Loading branch information
1 parent
d3ef79a
commit cea9fba
Showing
11 changed files
with
897 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
#include "adjust_layout_colour.h" | ||
#include "../Main.h" | ||
|
||
AdjustLayoutColour::AdjustLayoutColour() | ||
: hexMap(*TerpstraSysExApplication::getApp().getMappingData()) | ||
{ | ||
endAction(); | ||
} | ||
|
||
AdjustLayoutColour::~AdjustLayoutColour() | ||
{ | ||
} | ||
|
||
void AdjustLayoutColour::replaceColour(juce::Colour oldColour, juce::Colour newColour, bool sendUpdate) | ||
{ | ||
auto keyCoords = layoutBeforeAdjust.getKeysWithColour(oldColour); | ||
juce::Array<MappedLumatoneKey> keyUpdates; | ||
|
||
for (auto coord : keyCoords) | ||
{ | ||
auto key = ¤tLayout.getBoard(coord.boardIndex)->theKeys[coord.keyIndex]; | ||
keyUpdates.add(MappedLumatoneKey(key->withColour(newColour), coord)); | ||
} | ||
|
||
if (sendUpdate) | ||
sendSelectionUpdate(keyUpdates); | ||
} | ||
|
||
void AdjustLayoutColour::rotateHue(float change, bool sendUpdate) | ||
{ | ||
auto coords = currentLayout.getAllKeyCoords(); | ||
rotateHue(change, coords, false); | ||
if (sendUpdate) | ||
sendMappingUpdate(currentLayout); | ||
} | ||
|
||
void AdjustLayoutColour::rotateHue(float change, const juce::Array<LumatoneKeyCoord>& selection, bool sendUpdate) | ||
{ | ||
if (currentAction != AdjustLayoutColour::Type::ROTATEHUE) | ||
{ | ||
beginAction(AdjustLayoutColour::Type::ROTATEHUE); | ||
currentLayout = *TerpstraSysExApplication::getApp().getMappingData(); | ||
} | ||
|
||
juce::Array<MappedLumatoneKey> updateKeys; | ||
for (auto coord : selection) | ||
{ | ||
auto key = ¤tLayout.getBoard(coord.boardIndex)->theKeys[coord.keyIndex]; | ||
auto colour = (&layoutBeforeAdjust.getBoard(coord.boardIndex)->theKeys[coord.keyIndex])->colour; | ||
if (colour.isTransparent() | ||
|| (colour.getRed() == colour.getGreen() && colour.getRed() == colour.getBlue()) | ||
) | ||
continue; | ||
|
||
auto rotated = colour.withRotatedHue(change); | ||
key->colour = rotated; | ||
updateKeys.add(MappedLumatoneKey(*key, coord)); | ||
} | ||
|
||
if (sendUpdate) | ||
sendSelectionUpdate(updateKeys); | ||
} | ||
|
||
void AdjustLayoutColour::multiplyBrightness(float change, bool sendUpdate) | ||
{ | ||
auto coords = currentLayout.getAllKeyCoords(); | ||
multiplyBrightness(change, coords, false); | ||
if (sendUpdate) | ||
sendMappingUpdate(currentLayout); | ||
} | ||
|
||
void AdjustLayoutColour::multiplyBrightness(float change, const juce::Array<LumatoneKeyCoord>& selection, bool sendUpdate) | ||
{ | ||
if (currentAction != AdjustLayoutColour::Type::ADJUSTBRIGHTNESS) | ||
{ | ||
beginAction(AdjustLayoutColour::Type::ADJUSTBRIGHTNESS); | ||
currentLayout = *TerpstraSysExApplication::getApp().getMappingData(); | ||
} | ||
|
||
juce::Array<MappedLumatoneKey> updateKeys; | ||
for (auto coord : selection) | ||
{ | ||
auto key = ¤tLayout.getBoard(coord.boardIndex)->theKeys[coord.keyIndex]; | ||
auto colour = (&layoutBeforeAdjust.getBoard(coord.boardIndex)->theKeys[coord.keyIndex])->colour; | ||
if (colour.isTransparent()) | ||
continue; | ||
|
||
auto adjusted = colour.withMultipliedBrightness(change); | ||
key->colour = adjusted; | ||
updateKeys.add(MappedLumatoneKey(*key, coord)); | ||
} | ||
|
||
if (sendUpdate) | ||
sendSelectionUpdate(updateKeys); | ||
} | ||
|
||
void AdjustLayoutColour::setGradient(SetGradientOptions options) | ||
{ | ||
float originColumn = 0; | ||
float originRow = 0; | ||
|
||
float furthestColumn = 0; | ||
float furthestRow = 0; | ||
|
||
juce::Array<int> presentColumns; | ||
juce::Array<int> presentRows; | ||
|
||
juce::Array<Hex::Point> updateHexCoords; | ||
for (auto coord : options.selection) | ||
{ | ||
auto hex = hexMap.keyCoordsToHex(coord); | ||
updateHexCoords.add(hex); | ||
|
||
if (hex.q < originColumn) | ||
originColumn = hex.q; | ||
if (hex.r < originRow) | ||
originRow = hex.r; | ||
|
||
if (hex.q > furthestColumn) | ||
furthestColumn = hex.q; | ||
if (hex.r > furthestRow) | ||
furthestRow = hex.r; | ||
|
||
presentColumns.addIfNotAlreadyThere(hex.q); | ||
presentRows.addIfNotAlreadyThere(hex.r); | ||
} | ||
|
||
presentColumns.sort(); | ||
presentRows.sort(); | ||
|
||
auto selectionOrigin = Hex::Point(originColumn, originRow); | ||
auto furthestPoint = Hex::Point(furthestColumn, furthestRow); | ||
int selectionDistance = furthestPoint.distanceTo(selectionOrigin); | ||
|
||
auto boardOrigin = Hex::Point(0, 0); | ||
int maxBoardDistance = 35; | ||
|
||
juce::Array<MappedLumatoneKey> keyUpdates; | ||
|
||
float maxGradientDistance = 1.0f; | ||
if (options.selectionOrigin) | ||
{ | ||
if (options.fillRelative) | ||
maxGradientDistance = presentColumns.size(); | ||
else | ||
maxGradientDistance = selectionDistance; | ||
} | ||
else | ||
{ | ||
maxGradientDistance = maxBoardDistance; | ||
} | ||
|
||
float keyGradientDistance = 0.0f; | ||
for (int i = 0; i < options.selection.size(); i++) | ||
{ | ||
auto mappedKey = options.selection[i]; | ||
auto hex = updateHexCoords[i]; | ||
|
||
if (options.selectionOrigin) | ||
{ | ||
if (options.fillRelative) | ||
{ | ||
keyGradientDistance = hex.q - presentColumns[0]; | ||
} | ||
else | ||
{ | ||
keyGradientDistance = hex.distanceTo(selectionOrigin); | ||
} | ||
} | ||
else | ||
{ | ||
keyGradientDistance = hex.distanceTo(boardOrigin); | ||
} | ||
|
||
float t = (maxGradientDistance == 0.0f) ? 0.0f : keyGradientDistance / maxGradientDistance; | ||
auto colour = options.gradient.getColourAtPosition(t); | ||
auto key = ¤tLayout.getBoard(mappedKey.boardIndex)->theKeys[mappedKey.keyIndex]; | ||
key->colour = colour; | ||
|
||
keyUpdates.add(MappedLumatoneKey(*key, mappedKey.boardIndex, mappedKey.keyIndex)); | ||
} | ||
|
||
sendSelectionUpdate(keyUpdates); | ||
} | ||
|
||
void AdjustLayoutColour::beginAction(AdjustLayoutColour::Type type) | ||
{ | ||
if (type == AdjustLayoutColour::Type::NONE) | ||
return endAction(); | ||
|
||
if (currentAction != type) | ||
{ | ||
if (currentAction == AdjustLayoutColour::Type::NONE) | ||
{ | ||
layoutBeforeAdjust = *TerpstraSysExApplication::getApp().getMappingData(); | ||
} | ||
} | ||
|
||
currentAction = type; | ||
} | ||
|
||
void AdjustLayoutColour::endAction() | ||
{ | ||
layoutBeforeAdjust = *TerpstraSysExApplication::getApp().getMappingData(); | ||
currentLayout = layoutBeforeAdjust; | ||
currentAction = AdjustLayoutColour::Type::NONE; | ||
} | ||
|
||
void AdjustLayoutColour::commitChanges() | ||
{ | ||
endAction(); | ||
} | ||
void AdjustLayoutColour::resetChanges() | ||
{ | ||
TerpstraSysExApplication::getApp().getLumatoneController()->sendCompleteMapping(layoutBeforeAdjust); | ||
endAction(); | ||
} | ||
|
||
void AdjustLayoutColour::sendSelectionUpdate(const juce::Array<MappedLumatoneKey>& keyUpdates) | ||
{ | ||
auto updateAction = new LumatoneEditAction::MultiKeyAssignAction(TerpstraSysExApplication::getApp().getLumatoneController(), keyUpdates); | ||
|
||
TerpstraSysExApplication::getApp().performUndoableAction(updateAction); | ||
} | ||
|
||
void AdjustLayoutColour::sendMappingUpdate(const LumatoneLayout& updatedLayout) | ||
{ | ||
for (int i = 0; i < TerpstraSysExApplication::getApp().getNumBoards(); i++) | ||
TerpstraSysExApplication::getApp().performUndoableAction(new LumatoneEditAction::SectionEditAction(TerpstraSysExApplication::getApp().getLumatoneController(), i, *updatedLayout.readBoard(i)), i == 0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#pragma once | ||
|
||
#include "../LumatoneController.h" | ||
#include "../actions/edit_actions.h" | ||
#include "../hex/lumatone_hex_map.h" | ||
|
||
class AdjustLayoutColour | ||
{ | ||
|
||
public: | ||
enum class Type | ||
{ | ||
NONE, | ||
FINDREPLACE, | ||
ROTATEHUE, | ||
ADJUSTBRIGHTNESS, | ||
SETGRADIENT | ||
}; | ||
|
||
struct SetGradientOptions | ||
{ | ||
const juce::Array<LumatoneKeyCoord>& selection; | ||
juce::ColourGradient gradient; | ||
bool selectionOrigin = true; | ||
bool fillRelative = true; | ||
int numColumns = 1; | ||
int numRows = 1; | ||
|
||
SetGradientOptions(const juce::Array<LumatoneKeyCoord>& selectionIn, juce::ColourGradient gradientIn, bool selectionOriginIn = true, bool fillRelativeIn=true, int numColumnsIn = 1, int numRowsIn = 1) | ||
: selection(selectionIn) | ||
, gradient(gradientIn) | ||
, selectionOrigin(selectionOriginIn) | ||
, fillRelative(fillRelativeIn) | ||
, numColumns(numColumnsIn) | ||
, numRows(numRowsIn) {} | ||
}; | ||
|
||
public: | ||
|
||
AdjustLayoutColour(); | ||
~AdjustLayoutColour(); | ||
|
||
void replaceColour(juce::Colour oldColour, juce::Colour newColour, bool sendUpdate=true); | ||
|
||
void rotateHue(float change, bool sendUpdate=true); | ||
void rotateHue(float change, const juce::Array<LumatoneKeyCoord>& selection, bool sendUpdate=true); | ||
|
||
void multiplyBrightness(float change, bool sendUpdate=true); | ||
void multiplyBrightness(float change, const juce::Array<LumatoneKeyCoord>& selection, bool sendUpdate=true); | ||
|
||
void setGradient(SetGradientOptions options); | ||
|
||
void commitChanges(); | ||
void resetChanges(); | ||
|
||
private: | ||
|
||
void beginAction(AdjustLayoutColour::Type type); | ||
void endAction(); | ||
|
||
private: | ||
|
||
void sendSelectionUpdate(const juce::Array<MappedLumatoneKey>& keyUpdates); | ||
void sendMappingUpdate(const LumatoneLayout& updatedLayout); | ||
|
||
private: | ||
|
||
LumatoneHexMap hexMap; | ||
|
||
LumatoneLayout layoutBeforeAdjust; | ||
LumatoneLayout currentLayout; | ||
|
||
AdjustLayoutColour::Type currentAction; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.