142b7984aSPete Goodeve/* PatchRow.cpp 242b7984aSPete Goodeve * ------------ 342b7984aSPete Goodeve * 442b7984aSPete Goodeve * Copyright 2013, Haiku, Inc. All rights reserved. 542b7984aSPete Goodeve * Distributed under the terms of the MIT License. 642b7984aSPete Goodeve * 742b7984aSPete Goodeve * Revisions by Pete Goodeve 842b7984aSPete Goodeve * 942b7984aSPete Goodeve * Copyright 1999, Be Incorporated. All Rights Reserved. 1042b7984aSPete Goodeve * This file may be used under the terms of the Be Sample Code License. 1142b7984aSPete Goodeve */ 1242b7984aSPete Goodeve 1342b7984aSPete Goodeve#include "PatchRow.h" 14e1d5f30eSPhilippe Houdoin 15e1d5f30eSPhilippe Houdoin#include <stdio.h> 16e1d5f30eSPhilippe Houdoin#include <CheckBox.h> 17e1d5f30eSPhilippe Houdoin#include <Debug.h> 18e1d5f30eSPhilippe Houdoin#include <MidiRoster.h> 19e1d5f30eSPhilippe Houdoin#include <MidiConsumer.h> 20e1d5f30eSPhilippe Houdoin#include <MidiProducer.h> 21e1d5f30eSPhilippe Houdoin#include <Window.h> 2282fbbe21SPete Goodeve 23e1d5f30eSPhilippe Houdoin#include "MidiEventMeter.h" 24e1d5f30eSPhilippe Houdoin 25e1d5f30eSPhilippe Houdoinextern const float ROW_LEFT = 50.0f; 26e1d5f30eSPhilippe Houdoinextern const float ROW_TOP = 50.0f; 27e1d5f30eSPhilippe Houdoinextern const float ROW_HEIGHT = 40.0f; 28e1d5f30eSPhilippe Houdoinextern const float COLUMN_WIDTH = 40.0f; 29e1d5f30eSPhilippe Houdoinextern const float METER_PADDING = 15.0f; 30e1d5f30eSPhilippe Houdoinextern const uint32 MSG_CONNECT_REQUEST = 'mCRQ'; 31e1d5f30eSPhilippe Houdoin 3242b7984aSPete Goodevestatic const BPoint kBoxOffset(8, 7); 33e1d5f30eSPhilippe Houdoin 34e1d5f30eSPhilippe Houdoin// PatchCheckBox is the check box that describes a connection 35e1d5f30eSPhilippe Houdoin// between a producer and a consumer. 36e1d5f30eSPhilippe Houdoinclass PatchCheckBox : public BCheckBox 37e1d5f30eSPhilippe Houdoin{ 38e1d5f30eSPhilippe Houdoinpublic: 39e1d5f30eSPhilippe Houdoin PatchCheckBox(BRect r, int32 producerID, int32 consumerID) 4042b7984aSPete Goodeve : 4142b7984aSPete Goodeve BCheckBox(r, "", "", new BMessage(MSG_CONNECT_REQUEST)), 4242b7984aSPete Goodeve fProducerID(producerID), 4342b7984aSPete Goodeve fConsumerID(consumerID) 4442b7984aSPete Goodeve {} 4542b7984aSPete Goodeve 4642b7984aSPete Goodeve int32 ProducerID() const 47e1d5f30eSPhilippe Houdoin { 4842b7984aSPete Goodeve return fProducerID; 4942b7984aSPete Goodeve } 5042b7984aSPete Goodeve int32 ConsumerID() const 5142b7984aSPete Goodeve { 5242b7984aSPete Goodeve return fConsumerID; 53e1d5f30eSPhilippe Houdoin } 54e1d5f30eSPhilippe Houdoin 55e1d5f30eSPhilippe Houdoin void DoConnect(); 56e1d5f30eSPhilippe Houdoin 57e1d5f30eSPhilippe Houdoinprivate: 5842b7984aSPete Goodeve int32 fProducerID; 5942b7984aSPete Goodeve int32 fConsumerID; 60e1d5f30eSPhilippe Houdoin}; 61e1d5f30eSPhilippe Houdoin 6242b7984aSPete Goodeve 63e1d5f30eSPhilippe HoudoinPatchRow::PatchRow(int32 producerID) 6442b7984aSPete Goodeve : 6542b7984aSPete Goodeve BView(BRect(0, 0, 0, 0), "PatchRow", B_FOLLOW_NONE, 6642b7984aSPete Goodeve B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED), 6742b7984aSPete Goodeve fProducerID(producerID), 6842b7984aSPete Goodeve fEventMeter(NULL) 69e1d5f30eSPhilippe Houdoin{ 7042b7984aSPete Goodeve fEventMeter = new MidiEventMeter(fProducerID); 71e1d5f30eSPhilippe Houdoin} 72e1d5f30eSPhilippe Houdoin 7342b7984aSPete Goodeve 74e1d5f30eSPhilippe HoudoinPatchRow::~PatchRow() 75e1d5f30eSPhilippe Houdoin{ 7642b7984aSPete Goodeve delete fEventMeter; 77e1d5f30eSPhilippe Houdoin} 78e1d5f30eSPhilippe Houdoin 7942b7984aSPete Goodeve 8042b7984aSPete Goodeveint32 8142b7984aSPete GoodevePatchRow::ID() const 82e1d5f30eSPhilippe Houdoin{ 8342b7984aSPete Goodeve return fProducerID; 84e1d5f30eSPhilippe Houdoin} 85e1d5f30eSPhilippe Houdoin 8642b7984aSPete Goodeve 8742b7984aSPete Goodevevoid 8842b7984aSPete GoodevePatchRow::Pulse() 89e1d5f30eSPhilippe Houdoin{ 9082fbbe21SPete Goodeve if (fEventMeter != NULL) 9142b7984aSPete Goodeve fEventMeter->Pulse(this); 92e1d5f30eSPhilippe Houdoin} 93e1d5f30eSPhilippe Houdoin 9442b7984aSPete Goodeve 9542b7984aSPete Goodevevoid 9642b7984aSPete GoodevePatchRow::Draw(BRect) 97e1d5f30eSPhilippe Houdoin{ 9882fbbe21SPete Goodeve if (fEventMeter != NULL) 9942b7984aSPete Goodeve fEventMeter->Draw(this); 100e1d5f30eSPhilippe Houdoin} 101e1d5f30eSPhilippe Houdoin 10242b7984aSPete Goodeve 10342b7984aSPete Goodevevoid 10442b7984aSPete GoodevePatchRow::AddColumn(int32 consumerID) 105e1d5f30eSPhilippe Houdoin{ 10642b7984aSPete Goodeve BRect rect; 107e1d5f30eSPhilippe Houdoin int32 numColumns = CountChildren(); 10842b7984aSPete Goodeve rect.left = numColumns * COLUMN_WIDTH + METER_PADDING + kBoxOffset.x; 10942b7984aSPete Goodeve rect.top = kBoxOffset.y; 11042b7984aSPete Goodeve rect.right = rect.left + 20; 11142b7984aSPete Goodeve rect.bottom = rect.top + 20; 112e1d5f30eSPhilippe Houdoin 11342b7984aSPete Goodeve PatchCheckBox* box = new PatchCheckBox(rect, fProducerID, consumerID); 114e1d5f30eSPhilippe Houdoin AddChild(box); 115e1d5f30eSPhilippe Houdoin box->SetTarget(this); 116e1d5f30eSPhilippe Houdoin} 117e1d5f30eSPhilippe Houdoin 11842b7984aSPete Goodeve 11942b7984aSPete Goodevevoid 12042b7984aSPete GoodevePatchRow::RemoveColumn(int32 consumerID) 121e1d5f30eSPhilippe Houdoin{ 122e1d5f30eSPhilippe Houdoin int32 numChildren = CountChildren(); 12342b7984aSPete Goodeve for (int32 i = 0; i < numChildren; i++) { 124e1d5f30eSPhilippe Houdoin PatchCheckBox* box = dynamic_cast<PatchCheckBox*>(ChildAt(i)); 12582fbbe21SPete Goodeve if (box != NULL && box->ConsumerID() == consumerID) { 126e1d5f30eSPhilippe Houdoin RemoveChild(box); 127e1d5f30eSPhilippe Houdoin delete box; 128e1d5f30eSPhilippe Houdoin while (i < numChildren) { 129e1d5f30eSPhilippe Houdoin box = dynamic_cast<PatchCheckBox*>(ChildAt(i++)); 13082fbbe21SPete Goodeve if (box != NULL) 131e1d5f30eSPhilippe Houdoin box->MoveBy(-COLUMN_WIDTH, 0); 132e1d5f30eSPhilippe Houdoin } 133e1d5f30eSPhilippe Houdoin break; 134e1d5f30eSPhilippe Houdoin } 135e1d5f30eSPhilippe Houdoin } 136e1d5f30eSPhilippe Houdoin} 137e1d5f30eSPhilippe Houdoin 13842b7984aSPete Goodeve 13942b7984aSPete Goodevevoid 14042b7984aSPete GoodevePatchRow::Connect(int32 consumerID) 141e1d5f30eSPhilippe Houdoin{ 142e1d5f30eSPhilippe Houdoin int32 numChildren = CountChildren(); 14342b7984aSPete Goodeve for (int32 i = 0; i < numChildren; i++) { 144e1d5f30eSPhilippe Houdoin PatchCheckBox* box = dynamic_cast<PatchCheckBox*>(ChildAt(i)); 14582fbbe21SPete Goodeve if (box != NULL && box->ConsumerID() == consumerID) 146e1d5f30eSPhilippe Houdoin box->SetValue(1); 147e1d5f30eSPhilippe Houdoin } 148e1d5f30eSPhilippe Houdoin} 149e1d5f30eSPhilippe Houdoin 15042b7984aSPete Goodeve 15142b7984aSPete Goodevevoid 15242b7984aSPete GoodevePatchRow::Disconnect(int32 consumerID) 153e1d5f30eSPhilippe Houdoin{ 154e1d5f30eSPhilippe Houdoin int32 numChildren = CountChildren(); 15542b7984aSPete Goodeve for (int32 i = 0; i < numChildren; i++) { 156e1d5f30eSPhilippe Houdoin PatchCheckBox* box = dynamic_cast<PatchCheckBox*>(ChildAt(i)); 15782fbbe21SPete Goodeve if (box != NULL && box->ConsumerID() == consumerID) 158e1d5f30eSPhilippe Houdoin box->SetValue(0); 159e1d5f30eSPhilippe Houdoin } 160e1d5f30eSPhilippe Houdoin} 161e1d5f30eSPhilippe Houdoin 16242b7984aSPete Goodeve 16342b7984aSPete Goodevevoid 16442b7984aSPete GoodevePatchRow::AttachedToWindow() 165e1d5f30eSPhilippe Houdoin{ 166e1d5f30eSPhilippe Houdoin Window()->SetPulseRate(200000); 167fa19dd44Slooncraz AdoptParentColors(); 168e1d5f30eSPhilippe Houdoin int32 numChildren = CountChildren(); 16942b7984aSPete Goodeve for (int32 i = 0; i < numChildren; i++) { 170e1d5f30eSPhilippe Houdoin PatchCheckBox* box = dynamic_cast<PatchCheckBox*>(ChildAt(i)); 17182fbbe21SPete Goodeve if (box != NULL) 172e1d5f30eSPhilippe Houdoin box->SetTarget(this); 173e1d5f30eSPhilippe Houdoin } 174e1d5f30eSPhilippe Houdoin} 175e1d5f30eSPhilippe Houdoin 17642b7984aSPete Goodeve 17742b7984aSPete Goodevevoid 17842b7984aSPete GoodevePatchRow::MessageReceived(BMessage* msg) 179e1d5f30eSPhilippe Houdoin{ 180e1d5f30eSPhilippe Houdoin switch (msg->what) { 181e1d5f30eSPhilippe Houdoin case MSG_CONNECT_REQUEST: 182e1d5f30eSPhilippe Houdoin { 183e1d5f30eSPhilippe Houdoin BControl* ctrl; 184e1d5f30eSPhilippe Houdoin if (msg->FindPointer("source", (void**) &ctrl) == B_OK) { 185e1d5f30eSPhilippe Houdoin PatchCheckBox* box = dynamic_cast<PatchCheckBox*>(ctrl); 18682fbbe21SPete Goodeve if (box != NULL) 187e1d5f30eSPhilippe Houdoin box->DoConnect(); 188e1d5f30eSPhilippe Houdoin } 189e1d5f30eSPhilippe Houdoin } 190e1d5f30eSPhilippe Houdoin break; 191e1d5f30eSPhilippe Houdoin default: 192e1d5f30eSPhilippe Houdoin BView::MessageReceived(msg); 193e1d5f30eSPhilippe Houdoin break; 194e1d5f30eSPhilippe Houdoin } 195e1d5f30eSPhilippe Houdoin} 196e1d5f30eSPhilippe Houdoin 19742b7984aSPete Goodeve 19842b7984aSPete Goodevevoid 19942b7984aSPete GoodevePatchCheckBox::DoConnect() 200e1d5f30eSPhilippe Houdoin{ 201e1d5f30eSPhilippe Houdoin int32 value = Value(); 202e1d5f30eSPhilippe Houdoin int32 inverseValue = (value + 1) % 2; 203e1d5f30eSPhilippe Houdoin 204e1d5f30eSPhilippe Houdoin BMidiRoster* roster = BMidiRoster::MidiRoster(); 20542b7984aSPete Goodeve if (roster == NULL) { 206e1d5f30eSPhilippe Houdoin SetValue(inverseValue); 207e1d5f30eSPhilippe Houdoin return; 208e1d5f30eSPhilippe Houdoin } 209e1d5f30eSPhilippe Houdoin 21042b7984aSPete Goodeve BMidiProducer* producer = roster->FindProducer(fProducerID); 21142b7984aSPete Goodeve BMidiConsumer* consumer = roster->FindConsumer(fConsumerID); 21282fbbe21SPete Goodeve if (producer != NULL && consumer != NULL) { 213e1d5f30eSPhilippe Houdoin status_t err; 21482fbbe21SPete Goodeve if (value != 0) 215e1d5f30eSPhilippe Houdoin err = producer->Connect(consumer); 21642b7984aSPete Goodeve else 217e1d5f30eSPhilippe Houdoin err = producer->Disconnect(consumer); 218e1d5f30eSPhilippe Houdoin 219e1d5f30eSPhilippe Houdoin if (err != B_OK) { 220e1d5f30eSPhilippe Houdoin SetValue(inverseValue); 221e1d5f30eSPhilippe Houdoin } 22242b7984aSPete Goodeve } else 223e1d5f30eSPhilippe Houdoin SetValue(inverseValue); 22442b7984aSPete Goodeve 22582fbbe21SPete Goodeve if (producer != NULL) 22682fbbe21SPete Goodeve producer->Release(); 22782fbbe21SPete Goodeve if (consumer != NULL) 22882fbbe21SPete Goodeve consumer->Release(); 229e1d5f30eSPhilippe Houdoin} 230