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.
18 #include <MidiRoster.h>
19 #include <MidiConsumer.h>
20 #include <MidiProducer.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
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
50 int32
ConsumerID() const
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
),
70 fEventMeter
= new MidiEventMeter(fProducerID
);
90 if (fEventMeter
!= NULL
)
91 fEventMeter
->Pulse(this);
98 if (fEventMeter
!= NULL
)
99 fEventMeter
->Draw(this);
104 PatchRow::AddColumn(int32 consumerID
)
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
);
115 box
->SetTarget(this);
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
) {
128 while (i
< numChildren
) {
129 box
= dynamic_cast<PatchCheckBox
*>(ChildAt(i
++));
131 box
->MoveBy(-COLUMN_WIDTH
, 0);
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
)
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
)
164 PatchRow::AttachedToWindow()
166 Window()->SetPulseRate(200000);
168 int32 numChildren
= CountChildren();
169 for (int32 i
= 0; i
< numChildren
; i
++) {
170 PatchCheckBox
* box
= dynamic_cast<PatchCheckBox
*>(ChildAt(i
));
172 box
->SetTarget(this);
178 PatchRow::MessageReceived(BMessage
* msg
)
181 case MSG_CONNECT_REQUEST
:
184 if (msg
->FindPointer("source", (void**) &ctrl
) == B_OK
) {
185 PatchCheckBox
* box
= dynamic_cast<PatchCheckBox
*>(ctrl
);
192 BView::MessageReceived(msg
);
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
);
210 BMidiProducer
* producer
= roster
->FindProducer(fProducerID
);
211 BMidiConsumer
* consumer
= roster
->FindConsumer(fConsumerID
);
212 if (producer
!= NULL
&& consumer
!= NULL
) {
215 err
= producer
->Connect(consumer
);
217 err
= producer
->Disconnect(consumer
);
220 SetValue(inverseValue
);
223 SetValue(inverseValue
);
225 if (producer
!= NULL
)
227 if (consumer
!= NULL
)