BTRFS: Implement BTree::Path and change _Find.
[haiku.git] / src / apps / patchbay / PatchRow.cpp
blob193646bf87b7028b201a0814f564a9a44a0e605c
1 /* PatchRow.cpp
2 * ------------
4 * Copyright 2013, Haiku, Inc. All rights reserved.
5 * Distributed under the terms of the MIT License.
7 * Revisions by Pete Goodeve
9 * Copyright 1999, Be Incorporated. All Rights Reserved.
10 * This file may be used under the terms of the Be Sample Code License.
13 #include "PatchRow.h"
15 #include <stdio.h>
16 #include <CheckBox.h>
17 #include <Debug.h>
18 #include <MidiRoster.h>
19 #include <MidiConsumer.h>
20 #include <MidiProducer.h>
21 #include <Window.h>
23 #include "MidiEventMeter.h"
25 extern const float ROW_LEFT = 50.0f;
26 extern const float ROW_TOP = 50.0f;
27 extern const float ROW_HEIGHT = 40.0f;
28 extern const float COLUMN_WIDTH = 40.0f;
29 extern const float METER_PADDING = 15.0f;
30 extern const uint32 MSG_CONNECT_REQUEST = 'mCRQ';
32 static const BPoint kBoxOffset(8, 7);
34 // PatchCheckBox is the check box that describes a connection
35 // between a producer and a consumer.
36 class PatchCheckBox : public BCheckBox
38 public:
39 PatchCheckBox(BRect r, int32 producerID, int32 consumerID)
41 BCheckBox(r, "", "", new BMessage(MSG_CONNECT_REQUEST)),
42 fProducerID(producerID),
43 fConsumerID(consumerID)
46 int32 ProducerID() const
48 return fProducerID;
50 int32 ConsumerID() const
52 return fConsumerID;
55 void DoConnect();
57 private:
58 int32 fProducerID;
59 int32 fConsumerID;
63 PatchRow::PatchRow(int32 producerID)
65 BView(BRect(0, 0, 0, 0), "PatchRow", B_FOLLOW_NONE,
66 B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED),
67 fProducerID(producerID),
68 fEventMeter(NULL)
70 fEventMeter = new MidiEventMeter(fProducerID);
74 PatchRow::~PatchRow()
76 delete fEventMeter;
80 int32
81 PatchRow::ID() const
83 return fProducerID;
87 void
88 PatchRow::Pulse()
90 if (fEventMeter != NULL)
91 fEventMeter->Pulse(this);
95 void
96 PatchRow::Draw(BRect)
98 if (fEventMeter != NULL)
99 fEventMeter->Draw(this);
103 void
104 PatchRow::AddColumn(int32 consumerID)
106 BRect rect;
107 int32 numColumns = CountChildren();
108 rect.left = numColumns * COLUMN_WIDTH + METER_PADDING + kBoxOffset.x;
109 rect.top = kBoxOffset.y;
110 rect.right = rect.left + 20;
111 rect.bottom = rect.top + 20;
113 PatchCheckBox* box = new PatchCheckBox(rect, fProducerID, consumerID);
114 AddChild(box);
115 box->SetTarget(this);
119 void
120 PatchRow::RemoveColumn(int32 consumerID)
122 int32 numChildren = CountChildren();
123 for (int32 i = 0; i < numChildren; i++) {
124 PatchCheckBox* box = dynamic_cast<PatchCheckBox*>(ChildAt(i));
125 if (box != NULL && box->ConsumerID() == consumerID) {
126 RemoveChild(box);
127 delete box;
128 while (i < numChildren) {
129 box = dynamic_cast<PatchCheckBox*>(ChildAt(i++));
130 if (box != NULL)
131 box->MoveBy(-COLUMN_WIDTH, 0);
133 break;
139 void
140 PatchRow::Connect(int32 consumerID)
142 int32 numChildren = CountChildren();
143 for (int32 i = 0; i < numChildren; i++) {
144 PatchCheckBox* box = dynamic_cast<PatchCheckBox*>(ChildAt(i));
145 if (box != NULL && box->ConsumerID() == consumerID)
146 box->SetValue(1);
151 void
152 PatchRow::Disconnect(int32 consumerID)
154 int32 numChildren = CountChildren();
155 for (int32 i = 0; i < numChildren; i++) {
156 PatchCheckBox* box = dynamic_cast<PatchCheckBox*>(ChildAt(i));
157 if (box != NULL && box->ConsumerID() == consumerID)
158 box->SetValue(0);
163 void
164 PatchRow::AttachedToWindow()
166 Window()->SetPulseRate(200000);
167 AdoptParentColors();
168 int32 numChildren = CountChildren();
169 for (int32 i = 0; i < numChildren; i++) {
170 PatchCheckBox* box = dynamic_cast<PatchCheckBox*>(ChildAt(i));
171 if (box != NULL)
172 box->SetTarget(this);
177 void
178 PatchRow::MessageReceived(BMessage* msg)
180 switch (msg->what) {
181 case MSG_CONNECT_REQUEST:
183 BControl* ctrl;
184 if (msg->FindPointer("source", (void**) &ctrl) == B_OK) {
185 PatchCheckBox* box = dynamic_cast<PatchCheckBox*>(ctrl);
186 if (box != NULL)
187 box->DoConnect();
190 break;
191 default:
192 BView::MessageReceived(msg);
193 break;
198 void
199 PatchCheckBox::DoConnect()
201 int32 value = Value();
202 int32 inverseValue = (value + 1) % 2;
204 BMidiRoster* roster = BMidiRoster::MidiRoster();
205 if (roster == NULL) {
206 SetValue(inverseValue);
207 return;
210 BMidiProducer* producer = roster->FindProducer(fProducerID);
211 BMidiConsumer* consumer = roster->FindConsumer(fConsumerID);
212 if (producer != NULL && consumer != NULL) {
213 status_t err;
214 if (value != 0)
215 err = producer->Connect(consumer);
216 else
217 err = producer->Disconnect(consumer);
219 if (err != B_OK) {
220 SetValue(inverseValue);
222 } else
223 SetValue(inverseValue);
225 if (producer != NULL)
226 producer->Release();
227 if (consumer != NULL)
228 consumer->Release();