Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Launchpad Pro add full support for Track Control #102

Closed
cmtec opened this issue Nov 9, 2018 · 8 comments
Closed

Launchpad Pro add full support for Track Control #102

cmtec opened this issue Nov 9, 2018 · 8 comments

Comments

@cmtec
Copy link

cmtec commented Nov 9, 2018

Feature request:
Please add track controll support for all three modes.

@git-moss
Copy link
Owner

What 3 modes you mean?

@cmtec
Copy link
Author

cmtec commented Nov 10, 2018

Session, Note and Device.

Right now only "Volume", "Pan" and "Sends" return to previous mode. "Record Arm", "Track Select", "Mute", "Solo" and "Stop Clip" force switching to Session mode (as you described in the instructions)

@git-moss
Copy link
Owner

Ah, I see. Will be fixed in the next update.

@cmtec
Copy link
Author

cmtec commented Nov 18, 2018

Thanks,

EDIT: Based on v3.44

Please consider following:

  • Add "restoreView" for "DOWN" event in additional to "UP" event
  • Make the restored view be based on the preferred view (same as when changing track from the DAW)
  • Inhibit saving control mode/view when jump between control modes/views so that session,note or device are restored instead of previous control mode/view.

I have made a quick hack on the src/main/java/de/mossgrabers/controller/launchpad/command/trigger/AbstractTrackCommand.java that somwhat solves this (please see code below). The two first points are solved but the third is solved only by not permiting jumps between control modes/views.

I havn't had time to dig in to the code base so thats why this code is quite "hacky".

// Written by Jürgen Moßgraber - mossgrabers.de
// (c) 2017-2018
// Licensed under LGPLv3 - http://www.gnu.org/licenses/lgpl-3.0.txt

package de.mossgrabers.controller.launchpad.command.trigger;

import de.mossgrabers.controller.launchpad.LaunchpadConfiguration;
import de.mossgrabers.controller.launchpad.controller.LaunchpadControlSurface;
import de.mossgrabers.controller.launchpad.view.Views;
import de.mossgrabers.framework.command.core.AbstractTriggerCommand;
import de.mossgrabers.framework.daw.IModel;
import de.mossgrabers.framework.mode.ModeManager;
import de.mossgrabers.framework.utils.ButtonEvent;
import de.mossgrabers.framework.view.ViewManager;
import de.mossgrabers.framework.daw.data.ITrack;
import de.mossgrabers.framework.controller.DefaultValueChanger;


/**
 * Base command for entering a track mode.
 *
 * @author Jürgen Moßgraber
 */
public class AbstractTrackCommand extends AbstractTriggerCommand<LaunchpadControlSurface, LaunchpadConfiguration>
{
	private boolean firstRowUsed;
	private boolean temporaryView;
	private static boolean currentViewUsed;
	private static boolean currentModeUsed;
	private static Integer currentView;
	private static Integer currentMode;


	/**
	 * Constructor.
	 *
	 * @param model The model
	 * @param surface The surface
	 */
	public AbstractTrackCommand (final IModel model, final LaunchpadControlSurface surface)
	{
		super (model, surface);
		this.currentViewUsed = false;
		this.currentModeUsed = false;
		this.currentView = null;
		this.currentMode = null;
	}

	
	private void handleTrackChange ()
	{
		// Recall last used view (if we are not in session mode)
		final ViewManager viewManager = this.surface.getViewManager ();
		if (!viewManager.isActiveView (Views.VIEW_SESSION))
		{
			final ITrack selectedTrack = this.model.getSelectedTrack ();
			if (selectedTrack != null)
			{
				final Integer preferredView = viewManager.getPreferredView (selectedTrack.getPosition ());
				viewManager.setActiveView (preferredView == null ? Views.VIEW_PLAY : preferredView);
			}
		}

		if (viewManager.isActiveView (Views.VIEW_PLAY))
			viewManager.getActiveView ().updateNoteMapping ();

		if (viewManager.isActiveView (Views.VIEW_DRUM))
			viewManager.getView (Views.VIEW_DRUM).updateNoteMapping ();
	}


	protected void onModeButton (final ButtonEvent event, final Integer controlMode, final String notification)
	{
		final ModeManager modeManager = this.surface.getModeManager ();

		// If volume, pan or send is pressed then exit	
		if (this.currentViewUsed == true)
		{
			return;
		}

		// Check if this is the first controlMode button to be pressed	
		if ((this.currentModeUsed == false) && (modeManager.getActiveOrTempModeId () == null) && (event == ButtonEvent.DOWN))
		{
			this.currentMode = controlMode;
			this.currentModeUsed = true;
		}

		// Only react on the first pressed control button 
		if ((this.currentModeUsed == true) && (this.currentMode == controlMode))
		{ 
			switch (event)
			{
				case DOWN:
					if (modeManager.isActiveOrTempMode (controlMode))
					{
						modeManager.setActiveMode (null);
						this.surface.getViewManager ().restoreView ();
						this.handleTrackChange ();
						this.currentModeUsed = false;
						return;
					}
					this.firstRowUsed = false;
					modeManager.setActiveMode (controlMode);
					this.surface.getViewManager ().setActiveView (Views.VIEW_SESSION);
					this.surface.getDisplay ().notify (notification);
					break;

				case LONG:
					if (modeManager.isActiveOrTempMode (controlMode))
					{
						this.firstRowUsed = true;
					}
					break;

				case UP:
					if (this.firstRowUsed)
					{
						modeManager.setActiveMode (null);
						this.surface.getViewManager ().restoreView ();
						this.handleTrackChange ();
						this.currentModeUsed = false;
					}
					break;
			}
		}
	}


	protected void onFaderModeButton (final ButtonEvent event, final Integer view, final String notification)
	{
		final ViewManager viewManager = this.surface.getViewManager ();

		// If record arm, track select, mute solo or stop clip is pressed the exit	
		if (this.currentModeUsed == true)
		{
			return;
		}

		// Check if this is the first controlMode button to be pressed	
		if ((this.currentViewUsed == false) && (viewManager.getActiveViewId () != 1) && (viewManager.getActiveViewId () != 2) && (viewManager.getActiveViewId () != 3) && (event == ButtonEvent.DOWN))
		{
			this.currentView = view;
			this.currentViewUsed = true;
		}

		// Only react on the first pressed control button 
		if ((this.currentViewUsed == true) && (this.currentView == view))
		{ 
			switch (event)
			{
				case DOWN:
					if (viewManager.isActiveView (view))
					{
						viewManager.restoreView ();
						this.handleTrackChange ();
						this.currentViewUsed = false;
						return;
					}
					this.temporaryView = false;
					viewManager.setActiveView (view);
					this.surface.getModeManager ().setActiveMode (null);
					this.surface.getDisplay ().notify (notification);
					break;

				case LONG:
					if (viewManager.isActiveView (view))
					{
						this.temporaryView = true;
					}
					break;

				case UP:
					if (this.temporaryView)
					{
						viewManager.restoreView ();
						this.handleTrackChange ();
						this.currentViewUsed = false;
					}
					break;
			}
		}
	}
}

@git-moss
Copy link
Owner

As I wrote above I already changed that and it will be in the next update (hopefully today).

@cmtec
Copy link
Author

cmtec commented Nov 25, 2018

I got the impression that my initial request was solved in version 3.44. My bad.
Thanks for your time and effort on this request!

@git-moss
Copy link
Owner

Yes, it was. Sorry, for the confusion just trying to wrap my head around what has changed.

@cmtec
Copy link
Author

cmtec commented Nov 28, 2018

Clarification:
My suggenstion above was based on the v3.44 release (that only implemented the "case UP")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants