Programmatically pressing a HardwareButton

Post Reply New Topic
RELATED
PRODUCTS

Post

There is controller button that sends sysex and nothing else. It had to be special for some mysterious reason, thanks, NI. I'd like to create a HardwareButton for it so I can bind to it like I do with all the other buttons, but I'm hitting a wall.

I can set a sysex callback and I can getHost().createHardwareButton(). I cannot figure out how to get the button to think it's being pressed.

I could try creating my own HardwareActions without needing a button and invoking them from the sysex callback, but I don't see a way to do that either.

Finally, I could try setting a HardwareActionMatcher but I don't see a way to create a matching expression for sysex. All examples in bitwig-extensions are for notes and CC. All the documentation has to say on the subject is "expression: Expression returns true if the event matches", which is lovely.

What am I missing?

Post

Angry-coded my own button.

Code: Select all

case class FakeAction(protected val invokeCallback:() => Unit)
  extends HardwareBindingSource[HardwareActionBinding] {
  val callbacks: mutable.HashSet[Runnable] = mutable.HashSet.empty
  def invoke(): Unit = {
    invokeCallback()
    callbacks.foreach(_.run())
  }
  def addBinding(f: Runnable): HardwareActionBinding = {
    callbacks.addOne(f)
    () => callbacks.remove(f)
  }
  def setBinding(f: Runnable): HardwareActionBinding = {
    callbacks.clear()
    addBinding(f)
  }
  def clearBindings(): Unit = callbacks.clear()

  override def canBindTo(o: Any): Boolean = o match {
    case _: Runnable => true
    case _: HardwareActionBindable => true
    case _ => false
  }

  override def addBinding(h: HardwareBindable): HardwareActionBinding = h match {
    case hab: HardwareActionBindable => addBinding(() => hab.invoke())
    case _ => ??? // better be never
  }

  override def setBinding(h: HardwareBindable): HardwareActionBinding = h match {
    case hab: HardwareActionBindable => setBinding(() => hab.invoke())
    case _ => ???
  }
}
case class FakeButton() {
  var isPressed: Boolean = false
  val pressedAction: FakeAction = FakeAction(() => isPressed = true)
  val releasedAction: FakeAction = FakeAction(() => isPressed = false)
}

Post

Nice glad to see I wasn't the only one running into this problemo...I had to do the same thing when I wanted to make a fake Hardware knobs... :)

This is missing some dependancies but the idea is here...

Code: Select all

package com.kirkwoodwest.hardware;
import com.kirkwoodwest.utils.Math;

import java.util.ArrayList;
import java.util.function.DoubleConsumer;

public class HardwareValueTarget implements DoubleConsumer {

  public ArrayList<RelativeHardwareValueListener> knob_listeners    = new ArrayList<>();
  public ArrayList<Integer>                       knob_listener_ids = new ArrayList<>();
  public double internal_value = -1;
  public HardwareValueTarget() {
  }

  /**
   * Adds a listener for when the knob value has changed.
   * @param knob_listener The parent class that listens for the events.
   * @param id  ID is used to distinguish multiple knobs from the listener. its up to the programmer to determine
   *            if that is used or not.
   * @return  True if a listener was actually added.
   */
  public boolean addListener(RelativeHardwareValueListener knob_listener, int id) {
    boolean added_listener = false;
    if (!knob_listeners.contains(knob_listener)) {
      knob_listeners.add(knob_listener);
      knob_listener_ids.add(id);
      added_listener = true;
    }
    return added_listener;
  }

  public boolean removeListener(RelativeHardwareValueListener knob_listener) {
    int index = knob_listeners.indexOf(knob_listener);
    if (index == -1) {
      return false;
    } else {
      knob_listeners.remove(index);
      knob_listener_ids.remove(index);
    }
    return true;
  }

  public boolean removeListener(int knob_listener_id) {
    int index = knob_listener_ids.indexOf(knob_listener_id);
    if (index == -1) {
      return false;
    } else {
      knob_listeners.remove(index);
      knob_listener_ids.remove(index);
    }
    return true;
  }

  private void updateListeners() {
    int size = knob_listeners.size();
    for (int i=0; i < size; i++) {
      RelativeHardwareValueListener knob_listener    = knob_listeners.get(i);
      int                           knob_listener_id = knob_listener_ids.get(i);
      knob_listener.knob_updated(knob_listener_id, internal_value);
    }
  }

  @Override
  public void accept(double adjustment_value) {
    double new_internal_value = adjustment_value;
    setInternalValue(new_internal_value);
  }

  public void setInternalValue(double value) {
    value = Math.valueLimit(value,0,1);
    if (value == internal_value) return;
    internal_value = value;
    updateListeners();
  }

  public void setInternalValueInt(int value) {
    double internalValue = value / 127;
    setInternalValue(internalValue);
  }
}
----------------------------------------------------------------------
http://instagram.com/kirkwoodwest/
http://soundcloud.com/kirkwoodwest

Post Reply

Return to “Controller Scripting”