Skip to content

Commit

Permalink
Merge pull request #70 from ericahrens/api-18
Browse files Browse the repository at this point in the history
Maschine Mikro Mk3 plus fixes to Arturia Minilab 3
  • Loading branch information
abique authored Nov 22, 2023
2 parents 11f2f2b + d041d22 commit 08a2bb5
Show file tree
Hide file tree
Showing 30 changed files with 1,390 additions and 701 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private void addPorts(final AutoDetectionMidiPortNamesList list, final String fo
final String portName = String.format(format, numberOfKeys);
list.add(new String[]{portName}, new String[]{portName});
for (int i = 0; i < appendWindowsCount; i++) {
String portAppended = "%d- s".formatted(i + 2, portName);
String portAppended = "%d- %s".formatted(i + 2, portName);
list.add(new String[]{portAppended}, new String[]{portAppended});
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,144 +1,140 @@
package com.bitwig.extensions.controllers.arturia.minilab3;

import com.bitwig.extension.controller.api.CursorBrowserResultItem;
import com.bitwig.extension.controller.api.CursorTrack;
import com.bitwig.extension.controller.api.PinnableCursorDevice;
import com.bitwig.extension.controller.api.PopupBrowser;
import com.bitwig.extension.controller.api.RelativeHardwareKnob;
import com.bitwig.extension.controller.api.*;
import com.bitwig.extensions.framework.Layer;

public class BrowserLayer extends Layer {

private static final String NO_SELECTION_MSG = "<no selection>";
public static final String FORMAT_BROWSE_TITLE = "Browser: %s";

private final MiniLab3Extension driver;

private final PopupBrowser browser;
private final PinnableCursorDevice cursorDevice;
private final CursorTrack cursorTrack;
private final CursorBrowserResultItem resultCursorItem;
private String[] contentTypeNames = new String[0];
private String currentContentType = "";

private boolean browsingInitiated = false;
private boolean isSelecting = false;

public BrowserLayer(final MiniLab3Extension driver) {
super(driver.getLayers(), "BROWSER_LAYER");
browser = driver.getHost().createPopupBrowser();
cursorDevice = driver.getCursorDevice();
cursorTrack = driver.getCursorTrack();
cursorDevice.exists().markInterested();
this.driver = driver;
browser.exists().markInterested();
browser.exists().addValueObserver(exists -> {
setIsActive(exists);
if (browsingInitiated) {
browser.shouldAudition().set(false);
isSelecting = true;
}
driver.browserDisplayMode(exists);
if (!exists) {
browsingInitiated = false;
} else {
updateInfo();
isSelecting = true;
}
});
browser.contentTypeNames().addValueObserver(contentTypeNames -> this.contentTypeNames = contentTypeNames);
browser.selectedContentTypeIndex().markInterested();
resultCursorItem = (CursorBrowserResultItem) browser.resultsColumn().createCursorItem();
resultCursorItem.exists()
.addValueObserver(selectionExists -> driver.getOled()
.sendTextInfo(DisplayMode.BROWSER, String.format(FORMAT_BROWSE_TITLE, currentContentType),
selectionExists ? resultCursorItem.name().get() : NO_SELECTION_MSG, false));
resultCursorItem.name()
.addValueObserver(selected -> driver.getOled()
.sendTextInfo(DisplayMode.BROWSER, String.format(FORMAT_BROWSE_TITLE, currentContentType),
selected, false));

browser.selectedContentTypeIndex().addValueObserver(selected -> {
if (selected < contentTypeNames.length) {
currentContentType = contentTypeNames[selected];
final boolean selectionExists = resultCursorItem.exists().get();
driver.getOled()
.sendTextInfo(DisplayMode.BROWSER, String.format(FORMAT_BROWSE_TITLE, currentContentType),
selectionExists ? resultCursorItem.name().get() : NO_SELECTION_MSG, false);
}
});

final RelativeHardwareKnob mainEncoder = driver.getMainEncoder();
final RelativeHardwareKnob shiftEncoder = driver.getShiftMainEncoder();
driver.bindEncoder(this, mainEncoder, inc -> scrollResultItem(resultCursorItem, inc));
driver.bindEncoder(this, shiftEncoder, this::scrollContentType);
}

public void updateInfo() {
driver.getOled()
.sendTextInfo(DisplayMode.BROWSER, String.format(FORMAT_BROWSE_TITLE, currentContentType),
resultCursorItem.exists().get() ? resultCursorItem.name().get() : NO_SELECTION_MSG, false);
}

private void scrollResultItem(final CursorBrowserResultItem resultCursorItem, final int inc) {
driver.getOled().enableValues(DisplayMode.BROWSER);
browser.shouldAudition().set(false);
isSelecting = true;
if (inc > 0) {
resultCursorItem.selectNext();
} else {
resultCursorItem.selectPrevious();
}
}

private void scrollContentType(final int inc) {
final int index = browser.selectedContentTypeIndex().get();
if (index >= 0 && index < contentTypeNames.length) {
driver.getOled().enableValues(DisplayMode.BROWSER);
int next = index + inc;
next = next < 0 ? contentTypeNames.length - 1 : (next >= contentTypeNames.length) ? 0 : next;
browser.selectedContentTypeIndex().set(next);
}
}

public void shiftPressAction() {
if (browser.exists().get()) {
browser.cancel();
} else {
if (cursorDevice.exists().get()) {
browsingInitiated = true;
cursorDevice.replaceDeviceInsertionPoint().browse();
private static final String NO_SELECTION_MSG = "<no selection>";
public static final String FORMAT_BROWSE_TITLE = "Browser: %s";

private final MiniLab3Extension driver;

private final PopupBrowser browser;
private final PinnableCursorDevice cursorDevice;
private final CursorTrack cursorTrack;
private final CursorBrowserResultItem resultCursorItem;
private final CursorBrowserFilterItem categoryItem;

private boolean browsingInitiated = false;
private boolean isSelecting = false;
private String currentCategory = "";

public BrowserLayer(final MiniLab3Extension driver) {
super(driver.getLayers(), "BROWSER_LAYER");
browser = driver.getHost().createPopupBrowser();
cursorDevice = driver.getCursorDevice();
cursorTrack = driver.getCursorTrack();
cursorDevice.exists().markInterested();

this.driver = driver;
browser.exists().markInterested();
browser.exists().addValueObserver(exists -> {
setIsActive(exists);
if (browsingInitiated) {
browser.shouldAudition().set(false);
isSelecting = true;
}
driver.browserDisplayMode(exists);
if (!exists) {
browsingInitiated = false;
} else {
updateInfo();
isSelecting = true;
}
});

categoryItem = (CursorBrowserFilterItem) browser.categoryColumn().createCursorItem();

resultCursorItem = (CursorBrowserResultItem) browser.resultsColumn().createCursorItem();
resultCursorItem.exists()
.addValueObserver(selectionExists -> driver.getOled()
.sendTextInfo(DisplayMode.BROWSER, String.format(FORMAT_BROWSE_TITLE, currentCategory),
selectionExists ? resultCursorItem.name().get() : NO_SELECTION_MSG, false));
resultCursorItem.name()
.addValueObserver(selected -> driver.getOled()
.sendTextInfo(DisplayMode.BROWSER, String.format(FORMAT_BROWSE_TITLE, currentCategory), selected, false));

categoryItem.name().addValueObserver(newName -> {
currentCategory = newName;
driver.getOled()
.sendTextInfo(DisplayMode.BROWSER, String.format(FORMAT_BROWSE_TITLE, newName),
resultCursorItem.exists().get() ? resultCursorItem.name().get() : NO_SELECTION_MSG, false);
});

final RelativeHardwareKnob mainEncoder = driver.getMainEncoder();
final RelativeHardwareKnob shiftEncoder = driver.getShiftMainEncoder();
driver.bindEncoder(this, mainEncoder, inc -> scrollResultItem(resultCursorItem, inc));
driver.bindEncoder(this, shiftEncoder, this::scrollContentType);
}

public void updateInfo() {
driver.getOled()
.sendTextInfo(DisplayMode.BROWSER, String.format(FORMAT_BROWSE_TITLE, currentCategory),
resultCursorItem.exists().get() ? resultCursorItem.name().get() : NO_SELECTION_MSG, false);
}

private void scrollResultItem(final CursorBrowserResultItem resultCursorItem, final int inc) {
driver.getOled().enableValues(DisplayMode.BROWSER);
browser.shouldAudition().set(false);
isSelecting = true;
if (inc > 0) {
resultCursorItem.selectNext();
} else {
resultCursorItem.selectPrevious();
}
}

private void scrollContentType(final int inc) {
if (inc > 0) {
categoryItem.selectNext();
} else {
categoryItem.selectPrevious();
}
}

public void shiftPressAction(long time) {
if (browser.exists().get()) {
browser.cancel();
} else {
if (cursorDevice.exists().get()) {
browsingInitiated = true;
if (time > 700) {
cursorDevice.afterDeviceInsertionPoint().browse();
} else {
browsingInitiated = true;
cursorTrack.endOfDeviceChainInsertionPoint().browse();
cursorDevice.replaceDeviceInsertionPoint().browse();
}
}
}

public void pressAction(final boolean down) {
if (!down || !browser.exists().get()) {
return;
}
if (isSelecting) {
browser.shouldAudition().set(true);
isSelecting = false;
driver.getOled().enableValues(DisplayMode.BROWSER_INFO);
driver.getOled().sendTextInfo(DisplayMode.BROWSER_INFO, "", "Click again to load", true);
} else {
browser.commit();
driver.notifyTurn(); // makes sure release doesn't trigger scene
}
}

@Override
protected void onActivate() {
super.onActivate();
}

@Override
protected void onDeactivate() {
super.onDeactivate();
}
} else {
browsingInitiated = true;
cursorTrack.endOfDeviceChainInsertionPoint().browse();
}
}
}

public void pressAction(final boolean down) {
if (!down || !browser.exists().get()) {
return;
}
if (isSelecting) {
browser.shouldAudition().set(true);
isSelecting = false;
driver.getOled().enableValues(DisplayMode.BROWSER_INFO);
driver.getOled().sendTextInfo(DisplayMode.BROWSER_INFO, "", "Click again to load", true);
} else {
browser.commit();
driver.notifyTurn(false); // makes sure release doesn't trigger scene
}
}

@Override
protected void onActivate() {
super.onActivate();
}

@Override
protected void onDeactivate() {
super.onDeactivate();
}


}
Loading

0 comments on commit 08a2bb5

Please sign in to comment.