Skip to content

Commit

Permalink
add adjust layout colour helper class
Browse files Browse the repository at this point in the history
  • Loading branch information
vsicurella committed Aug 21, 2023
1 parent d3ef79a commit cea9fba
Show file tree
Hide file tree
Showing 11 changed files with 897 additions and 3 deletions.
6 changes: 4 additions & 2 deletions Source/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -586,11 +586,13 @@ bool TerpstraSysExApplication::canPasteSubBoardData() const
return false;
}

bool TerpstraSysExApplication::performUndoableAction(UndoableAction* editAction)
bool TerpstraSysExApplication::performUndoableAction(UndoableAction* editAction, bool newTransaction)
{
if (editAction != nullptr)
{
undoManager.beginNewTransaction();
if (newTransaction)
undoManager.beginNewTransaction();

if (undoManager.perform(editAction)) // UndoManager will check for nullptr and also for disposing of the object
{
setHasChangesToSave(true);
Expand Down
2 changes: 1 addition & 1 deletion Source/Main.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class TerpstraSysExApplication : public JUCEApplication
void setCalibrationMode(bool calibrationStarted) { inCalibrationMode = calibrationStarted; }
bool getInCalibrationMode() const { return inCalibrationMode; }

bool performUndoableAction(UndoableAction* editAction);
bool performUndoableAction(UndoableAction* editAction, bool newTransaction=true);
bool undo();
bool redo();

Expand Down
230 changes: 230 additions & 0 deletions Source/color/adjust_layout_colour.cpp
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 = &currentLayout.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 = &currentLayout.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 = &currentLayout.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 = &currentLayout.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);
}
74 changes: 74 additions & 0 deletions Source/color/adjust_layout_colour.h
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;
};
14 changes: 14 additions & 0 deletions Source/data/lumatone_layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -552,3 +552,17 @@ juce::Array<LumatoneKeyCoord> LumatoneLayout::getKeysWithColour(const juce::Colo

return keyCoords;
}

juce::Array<LumatoneKeyCoord> LumatoneLayout::getAllKeyCoords() const
{
juce::Array<LumatoneKeyCoord> coords;
for (int boardIndex = 0; boardIndex < getNumBoards(); boardIndex++)
{
for (int keyIndex = 0; keyIndex < getOctaveBoardSize(); keyIndex++)
{
coords.add(LumatoneKeyCoord(boardIndex, keyIndex));
}
}

return coords;
}
4 changes: 4 additions & 0 deletions Source/data/lumatone_layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ class LumatoneLayout

const LumatoneKey* readKey(int boardIndex, int keyIndex) const;

public:

juce::Array<LumatoneKeyCoord> getAllKeyCoords() const;

public:

int numBoards = 0;
Expand Down
Loading

0 comments on commit cea9fba

Please sign in to comment.