Import Be sample-code licensed MIDI PatchBay.
Single change from original: "using namespace std" was missing in PatchView.h. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34229 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
bf0f20ea81
commit
e1d5f30e87
@ -5,4 +5,5 @@ SubDir HAIKU_TOP src tests kits midi ;
|
||||
#SubInclude HAIKU_TOP src tests kits midi midi_player ;
|
||||
#SubInclude HAIKU_TOP src tests kits midi midi_player_replacement ;
|
||||
#SubInclude HAIKU_TOP src tests kits midi synth_file_reader ;
|
||||
SubInclude HAIKU_TOP src tests kits midi patchbay ;
|
||||
|
||||
|
30
src/tests/kits/midi/patchbay/CountEventConsumer.h
Normal file
30
src/tests/kits/midi/patchbay/CountEventConsumer.h
Normal file
@ -0,0 +1,30 @@
|
||||
// CountEventConsumer.h
|
||||
// --------------------
|
||||
// A simple MIDI consumer that counts incoming MIDI events.
|
||||
//
|
||||
// Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
// This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
#ifndef _CountEventConsumer_h
|
||||
#define _CountEventConsumer_h
|
||||
|
||||
#include <MidiConsumer.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
class CountEventConsumer : public BMidiLocalConsumer
|
||||
{
|
||||
public:
|
||||
CountEventConsumer(const char* name)
|
||||
: BMidiLocalConsumer(name), m_eventCount(0)
|
||||
{}
|
||||
void Reset() { m_eventCount = 0; }
|
||||
int32 CountEvents() { return m_eventCount; }
|
||||
|
||||
void Data(uchar*, size_t, bool, bigtime_t)
|
||||
{ atomic_add(&m_eventCount, 1); }
|
||||
|
||||
private:
|
||||
int32 m_eventCount;
|
||||
};
|
||||
|
||||
#endif /* _CountEventConsumer_h */
|
105
src/tests/kits/midi/patchbay/EndpointInfo.cpp
Normal file
105
src/tests/kits/midi/patchbay/EndpointInfo.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
// EndpointInfo.cpp
|
||||
// ----------------
|
||||
// Implements the EndpointInfo object.
|
||||
//
|
||||
// Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
// This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Debug.h>
|
||||
#include <Message.h>
|
||||
#include <MidiRoster.h>
|
||||
#include <MidiEndpoint.h>
|
||||
|
||||
#include "EndpointInfo.h"
|
||||
|
||||
const char* LARGE_ICON_NAME = "be:large_icon";
|
||||
const char* MINI_ICON_NAME = "be:mini_icon";
|
||||
const uint32 LARGE_ICON_TYPE = 'ICON';
|
||||
const uint32 MINI_ICON_TYPE = 'MICN';
|
||||
extern const uint8 LARGE_ICON_SIZE = 32;
|
||||
extern const uint8 MINI_ICON_SIZE = 16;
|
||||
extern const icon_size DISPLAY_ICON_SIZE = B_LARGE_ICON;
|
||||
extern const color_space ICON_COLOR_SPACE = B_CMAP8;
|
||||
|
||||
static BBitmap* CreateIcon(const BMessage* msg, icon_size which);
|
||||
|
||||
EndpointInfo::EndpointInfo()
|
||||
: m_id(-1), m_icon(NULL)
|
||||
{}
|
||||
|
||||
EndpointInfo::EndpointInfo(int32 id)
|
||||
: m_id(id), m_icon(NULL)
|
||||
{
|
||||
BMidiRoster* roster = BMidiRoster::MidiRoster();
|
||||
if (roster) {
|
||||
BMidiEndpoint* endpoint = roster->FindEndpoint(id);
|
||||
if (endpoint) {
|
||||
printf("endpoint %ld = %p\n", id, endpoint);
|
||||
BMessage msg;
|
||||
if (endpoint->GetProperties(&msg) == B_OK) {
|
||||
m_icon = CreateIcon(&msg, DISPLAY_ICON_SIZE);
|
||||
}
|
||||
endpoint->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EndpointInfo::EndpointInfo(const EndpointInfo& info)
|
||||
: m_id(info.m_id)
|
||||
{
|
||||
m_icon = (info.m_icon) ? new BBitmap(info.m_icon) : NULL;
|
||||
}
|
||||
|
||||
EndpointInfo& EndpointInfo::operator=(const EndpointInfo& info)
|
||||
{
|
||||
if (&info != this) {
|
||||
m_id = info.m_id;
|
||||
delete m_icon;
|
||||
m_icon = (info.m_icon) ? new BBitmap(info.m_icon) : NULL;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
EndpointInfo::~EndpointInfo()
|
||||
{
|
||||
delete m_icon;
|
||||
}
|
||||
|
||||
void EndpointInfo::UpdateProperties(const BMessage* props)
|
||||
{
|
||||
delete m_icon;
|
||||
m_icon = CreateIcon(props, DISPLAY_ICON_SIZE);
|
||||
}
|
||||
|
||||
static BBitmap* CreateIcon(const BMessage* msg, icon_size which)
|
||||
{
|
||||
float iconSize;
|
||||
uint32 iconType;
|
||||
const char* iconName;
|
||||
|
||||
if (which == B_LARGE_ICON) {
|
||||
iconSize = LARGE_ICON_SIZE;
|
||||
iconType = LARGE_ICON_TYPE;
|
||||
iconName = LARGE_ICON_NAME;
|
||||
} else if (which == B_MINI_ICON) {
|
||||
iconSize = MINI_ICON_SIZE;
|
||||
iconType = MINI_ICON_TYPE;
|
||||
iconName = MINI_ICON_NAME;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const void* data;
|
||||
ssize_t size;
|
||||
BBitmap* bitmap = NULL;
|
||||
|
||||
if (msg->FindData(iconName, iconType, &data, &size) == B_OK)
|
||||
{
|
||||
BRect r(0, 0, iconSize-1, iconSize-1);
|
||||
bitmap = new BBitmap(r, ICON_COLOR_SPACE);
|
||||
ASSERT((bitmap->BitsLength() == size));
|
||||
memcpy(bitmap->Bits(), data, size);
|
||||
}
|
||||
return bitmap;
|
||||
}
|
40
src/tests/kits/midi/patchbay/EndpointInfo.h
Normal file
40
src/tests/kits/midi/patchbay/EndpointInfo.h
Normal file
@ -0,0 +1,40 @@
|
||||
// EndpointInfo.h
|
||||
// --------------
|
||||
// A simple structure that describes a MIDI object.
|
||||
// Currently, it only contains icon data associated with the object.
|
||||
//
|
||||
// Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
// This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
#ifndef _EndpointInfo_h
|
||||
#define _EndpointInfo_h
|
||||
|
||||
#include <Mime.h> /* for icon_size */
|
||||
#include <GraphicsDefs.h> /* for color_space */
|
||||
|
||||
class BMidiEndpoint;
|
||||
|
||||
extern const uint8 LARGE_ICON_SIZE;
|
||||
extern const uint8 MINI_ICON_SIZE;
|
||||
extern const icon_size DISPLAY_ICON_SIZE;
|
||||
extern const color_space ICON_COLOR_SPACE;
|
||||
|
||||
class EndpointInfo
|
||||
{
|
||||
public:
|
||||
EndpointInfo();
|
||||
EndpointInfo(int32 id);
|
||||
EndpointInfo(const EndpointInfo& info);
|
||||
EndpointInfo& operator=(const EndpointInfo& info);
|
||||
~EndpointInfo();
|
||||
|
||||
int32 ID() const { return m_id; }
|
||||
const BBitmap* Icon() const { return m_icon; }
|
||||
void UpdateProperties(const BMessage* props);
|
||||
|
||||
private:
|
||||
int32 m_id;
|
||||
BBitmap* m_icon;
|
||||
};
|
||||
|
||||
#endif /* _EndpointInfo_h */
|
17
src/tests/kits/midi/patchbay/Jamfile
Normal file
17
src/tests/kits/midi/patchbay/Jamfile
Normal file
@ -0,0 +1,17 @@
|
||||
SubDir HAIKU_TOP src tests kits midi patchbay ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
SimpleTest PatchBay
|
||||
:
|
||||
PatchApp.cpp
|
||||
PatchWin.cpp
|
||||
PatchView.cpp
|
||||
PatchRow.cpp
|
||||
EndpointInfo.cpp
|
||||
MidiEventMeter.cpp
|
||||
TToolTip.cpp
|
||||
:
|
||||
midi midi2 be $(TARGET_LIBSTDC++)
|
||||
;
|
||||
|
122
src/tests/kits/midi/patchbay/MidiEventMeter.cpp
Normal file
122
src/tests/kits/midi/patchbay/MidiEventMeter.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
// MidiEventMeter.cpp
|
||||
// ------------------
|
||||
// Implements the MidiEventMeter class.
|
||||
//
|
||||
// Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
// This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <MidiRoster.h>
|
||||
#include <MidiProducer.h>
|
||||
#include <MidiConsumer.h>
|
||||
#include <View.h>
|
||||
#include "CountEventConsumer.h"
|
||||
#include "MidiEventMeter.h"
|
||||
|
||||
static const BRect METER_BOUNDS(0,0,7,31);
|
||||
|
||||
// If we get this number of events per pulse or greater, we will
|
||||
// max out the event meter.
|
||||
// Value was determined empirically based on my banging on a MIDI
|
||||
// keyboard controller with a pulse of 200ms.
|
||||
static const int32 METER_SCALE = 10;
|
||||
|
||||
MidiEventMeter::MidiEventMeter(int32 producerID)
|
||||
: m_counter(NULL), m_meterLevel(0)
|
||||
{
|
||||
BMidiRoster* roster = BMidiRoster::MidiRoster();
|
||||
if (roster) {
|
||||
BMidiProducer* producer = roster->FindProducer(producerID);
|
||||
if (producer) {
|
||||
BString name;
|
||||
name << producer->Name() << " Event Meter";
|
||||
m_counter = new CountEventConsumer(name.String());
|
||||
producer->Connect(m_counter);
|
||||
producer->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MidiEventMeter::~MidiEventMeter()
|
||||
{
|
||||
if (m_counter) m_counter->Release();
|
||||
}
|
||||
|
||||
void MidiEventMeter::Pulse(BView* view)
|
||||
{
|
||||
int32 newLevel = m_meterLevel;
|
||||
if (m_counter) {
|
||||
newLevel = CalcMeterLevel(m_counter->CountEvents());
|
||||
m_counter->Reset();
|
||||
}
|
||||
if (newLevel != m_meterLevel) {
|
||||
m_meterLevel = newLevel;
|
||||
view->Invalidate(BRect(METER_BOUNDS).InsetBySelf(1,1));
|
||||
}
|
||||
}
|
||||
|
||||
BRect MidiEventMeter::Bounds() const
|
||||
{
|
||||
return METER_BOUNDS;
|
||||
}
|
||||
|
||||
void MidiEventMeter::Draw(BView* view)
|
||||
{
|
||||
const rgb_color METER_BLACK = { 0, 0, 0, 255 };
|
||||
const rgb_color METER_GREY = { 180, 180, 180, 255 };
|
||||
const rgb_color METER_GREEN = { 0, 255, 0, 255 };
|
||||
|
||||
view->PushState();
|
||||
|
||||
// draw the frame
|
||||
BPoint lt = METER_BOUNDS.LeftTop();
|
||||
BPoint rb = METER_BOUNDS.RightBottom();
|
||||
view->BeginLineArray(4);
|
||||
view->AddLine(BPoint(lt.x, lt.y), BPoint(rb.x - 1, lt.y), METER_BLACK);
|
||||
view->AddLine(BPoint(rb.x, lt.y), BPoint(rb.x, rb.y - 1), METER_BLACK);
|
||||
view->AddLine(BPoint(rb.x, rb.y), BPoint(lt.x + 1, rb.y), METER_BLACK);
|
||||
view->AddLine(BPoint(lt.x, rb.y), BPoint(lt.x, lt.y + 1), METER_BLACK);
|
||||
view->EndLineArray();
|
||||
|
||||
// draw the cells
|
||||
BRect cell = METER_BOUNDS;
|
||||
cell.InsetBy(1,1);
|
||||
cell.bottom = cell.top + (cell.Height() + 1) / 5;
|
||||
cell.bottom--;
|
||||
|
||||
const float kTintArray[] = { B_DARKEN_4_TINT, B_DARKEN_3_TINT, B_DARKEN_2_TINT, B_DARKEN_1_TINT, B_NO_TINT };
|
||||
|
||||
for (int32 i=4; i>=0; i--)
|
||||
{
|
||||
rgb_color color;
|
||||
if (m_meterLevel > i) {
|
||||
color = tint_color(METER_GREEN, kTintArray[i]);
|
||||
} else {
|
||||
color = METER_GREY;
|
||||
}
|
||||
view->SetHighColor(color);
|
||||
view->FillRect(cell);
|
||||
cell.OffsetBy(0, cell.Height() + 1);
|
||||
}
|
||||
|
||||
view->PopState();
|
||||
}
|
||||
|
||||
int32 MidiEventMeter::CalcMeterLevel(int32 eventCount) const
|
||||
{
|
||||
// we use an approximately logarithmic scale for determing the actual
|
||||
// drawn meter level, so that low-density event streams show up well.
|
||||
if (eventCount == 0) {
|
||||
return 0;
|
||||
} else if (eventCount < (int32)(.5*METER_SCALE)) {
|
||||
return 1;
|
||||
} else if (eventCount < (int32)(.75*METER_SCALE)) {
|
||||
return 2;
|
||||
} else if (eventCount < (int32)(.9*METER_SCALE)) {
|
||||
return 3;
|
||||
} else if (eventCount < METER_SCALE) {
|
||||
return 4;
|
||||
} else {
|
||||
return 5;
|
||||
}
|
||||
}
|
36
src/tests/kits/midi/patchbay/MidiEventMeter.h
Normal file
36
src/tests/kits/midi/patchbay/MidiEventMeter.h
Normal file
@ -0,0 +1,36 @@
|
||||
// MidiEventMeter.h
|
||||
// ----------------
|
||||
// A UI widget that measures the amount of MIDI data generated by a
|
||||
// consumer.
|
||||
//
|
||||
// Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
// This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
#ifndef _MidiEventMeter_h
|
||||
#define _MidiEventMeter_h
|
||||
|
||||
#include <Point.h>
|
||||
#include <Rect.h>
|
||||
|
||||
class BMidiProducer;
|
||||
class CountEventConsumer;
|
||||
class BView;
|
||||
|
||||
class MidiEventMeter
|
||||
{
|
||||
public:
|
||||
MidiEventMeter(int32 producerID);
|
||||
~MidiEventMeter();
|
||||
|
||||
void Pulse(BView* view);
|
||||
BRect Bounds() const;
|
||||
void Draw(BView* view);
|
||||
|
||||
private:
|
||||
int32 CalcMeterLevel(int32 eventCount) const;
|
||||
|
||||
CountEventConsumer* m_counter;
|
||||
int32 m_meterLevel;
|
||||
};
|
||||
|
||||
#endif /* _MidiMeterWidget_h */
|
44
src/tests/kits/midi/patchbay/PatchApp.cpp
Normal file
44
src/tests/kits/midi/patchbay/PatchApp.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
// PatchApp.cpp
|
||||
// ------------
|
||||
// Implements the PatchBay application class and main().
|
||||
//
|
||||
// Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
// This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
#include <Roster.h>
|
||||
#include "PatchApp.h"
|
||||
#include "PatchWin.h"
|
||||
#include "TToolTip.h"
|
||||
|
||||
PatchApp::PatchApp()
|
||||
: BApplication("application/x-vnd.Be-DTS.PatchBay"), m_toolTip(NULL)
|
||||
{
|
||||
m_toolTip = new TToolTip;
|
||||
}
|
||||
|
||||
void PatchApp::ReadyToRun()
|
||||
{
|
||||
new PatchWin;
|
||||
}
|
||||
|
||||
void PatchApp::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case B_SOME_APP_ACTIVATED:
|
||||
case eToolTipStart:
|
||||
case eToolTipStop:
|
||||
if (m_toolTip) m_toolTip->PostMessage(msg);
|
||||
break;
|
||||
default:
|
||||
BApplication::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
PatchApp app;
|
||||
app.Run();
|
||||
return 0;
|
||||
}
|
||||
|
26
src/tests/kits/midi/patchbay/PatchApp.h
Normal file
26
src/tests/kits/midi/patchbay/PatchApp.h
Normal file
@ -0,0 +1,26 @@
|
||||
// PatchApp.h
|
||||
// ----------
|
||||
// The PatchBay application class.
|
||||
//
|
||||
// Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
// This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
#ifndef _PatchApp_h
|
||||
#define _PatchApp_h
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
class TToolTip;
|
||||
|
||||
class PatchApp : public BApplication
|
||||
{
|
||||
public:
|
||||
PatchApp();
|
||||
void ReadyToRun();
|
||||
void MessageReceived(BMessage* msg);
|
||||
|
||||
private:
|
||||
TToolTip* m_toolTip;
|
||||
};
|
||||
|
||||
#endif /* _PatchApp_h */
|
BIN
src/tests/kits/midi/patchbay/PatchBay.rsrc
Normal file
BIN
src/tests/kits/midi/patchbay/PatchBay.rsrc
Normal file
Binary file not shown.
194
src/tests/kits/midi/patchbay/PatchRow.cpp
Normal file
194
src/tests/kits/midi/patchbay/PatchRow.cpp
Normal file
@ -0,0 +1,194 @@
|
||||
// PatchRow.cpp
|
||||
// ------------
|
||||
// Implements the PatchRow class.
|
||||
//
|
||||
// Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
// This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <CheckBox.h>
|
||||
#include <Debug.h>
|
||||
#include <MidiRoster.h>
|
||||
#include <MidiConsumer.h>
|
||||
#include <MidiProducer.h>
|
||||
#include <Window.h>
|
||||
#include "MidiEventMeter.h"
|
||||
#include "PatchRow.h"
|
||||
|
||||
extern const float ROW_LEFT = 50.0f;
|
||||
extern const float ROW_TOP = 50.0f;
|
||||
extern const float ROW_HEIGHT = 40.0f;
|
||||
extern const float COLUMN_WIDTH = 40.0f;
|
||||
extern const float METER_PADDING = 15.0f;
|
||||
extern const uint32 MSG_CONNECT_REQUEST = 'mCRQ';
|
||||
|
||||
static const BPoint kBoxOffset(8,7);
|
||||
|
||||
// PatchCheckBox is the check box that describes a connection
|
||||
// between a producer and a consumer.
|
||||
class PatchCheckBox : public BCheckBox
|
||||
{
|
||||
public:
|
||||
PatchCheckBox(BRect r, int32 producerID, int32 consumerID)
|
||||
: BCheckBox(r, "", "", new BMessage(MSG_CONNECT_REQUEST))
|
||||
{
|
||||
m_producerID = producerID;
|
||||
m_consumerID = consumerID;
|
||||
}
|
||||
|
||||
int32 ProducerID() const { return m_producerID; }
|
||||
int32 ConsumerID() const { return m_consumerID; }
|
||||
|
||||
void DoConnect();
|
||||
|
||||
private:
|
||||
int32 m_producerID;
|
||||
int32 m_consumerID;
|
||||
};
|
||||
|
||||
PatchRow::PatchRow(int32 producerID)
|
||||
: BView(BRect(0,0,0,0), "PatchRow", B_FOLLOW_NONE,
|
||||
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED),
|
||||
m_producerID(producerID), m_eventMeter(NULL)
|
||||
{
|
||||
m_eventMeter = new MidiEventMeter(m_producerID);
|
||||
}
|
||||
|
||||
PatchRow::~PatchRow()
|
||||
{
|
||||
delete m_eventMeter;
|
||||
}
|
||||
|
||||
int32 PatchRow::ID() const
|
||||
{
|
||||
return m_producerID;
|
||||
}
|
||||
|
||||
void PatchRow::Pulse()
|
||||
{
|
||||
if (m_eventMeter) m_eventMeter->Pulse(this);
|
||||
}
|
||||
|
||||
void PatchRow::Draw(BRect)
|
||||
{
|
||||
if (m_eventMeter) m_eventMeter->Draw(this);
|
||||
}
|
||||
|
||||
void PatchRow::AddColumn(int32 consumerID)
|
||||
{
|
||||
BRect r;
|
||||
int32 numColumns = CountChildren();
|
||||
r.left = numColumns*COLUMN_WIDTH + METER_PADDING + kBoxOffset.x;
|
||||
r.top = kBoxOffset.y;
|
||||
r.right = r.left + 20;
|
||||
r.bottom = r.top + 20;
|
||||
|
||||
PatchCheckBox* box = new PatchCheckBox(r, m_producerID, consumerID);
|
||||
AddChild(box);
|
||||
box->SetTarget(this);
|
||||
}
|
||||
|
||||
void PatchRow::RemoveColumn(int32 consumerID)
|
||||
{
|
||||
int32 numChildren = CountChildren();
|
||||
for (int32 i=0; i<numChildren; i++) {
|
||||
PatchCheckBox* box = dynamic_cast<PatchCheckBox*>(ChildAt(i));
|
||||
if (box && box->ConsumerID() == consumerID) {
|
||||
RemoveChild(box);
|
||||
delete box;
|
||||
while (i < numChildren) {
|
||||
box = dynamic_cast<PatchCheckBox*>(ChildAt(i++));
|
||||
if (box) {
|
||||
box->MoveBy(-COLUMN_WIDTH, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PatchRow::Connect(int32 consumerID)
|
||||
{
|
||||
int32 numChildren = CountChildren();
|
||||
for (int32 i=0; i<numChildren; i++) {
|
||||
PatchCheckBox* box = dynamic_cast<PatchCheckBox*>(ChildAt(i));
|
||||
if (box && box->ConsumerID() == consumerID) {
|
||||
box->SetValue(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PatchRow::Disconnect(int32 consumerID)
|
||||
{
|
||||
int32 numChildren = CountChildren();
|
||||
for (int32 i=0; i<numChildren; i++) {
|
||||
PatchCheckBox* box = dynamic_cast<PatchCheckBox*>(ChildAt(i));
|
||||
if (box && box->ConsumerID() == consumerID) {
|
||||
box->SetValue(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PatchRow::AttachedToWindow()
|
||||
{
|
||||
Window()->SetPulseRate(200000);
|
||||
SetViewColor(Parent()->ViewColor());
|
||||
int32 numChildren = CountChildren();
|
||||
for (int32 i=0; i<numChildren; i++) {
|
||||
PatchCheckBox* box = dynamic_cast<PatchCheckBox*>(ChildAt(i));
|
||||
if (box) {
|
||||
box->SetTarget(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PatchRow::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case MSG_CONNECT_REQUEST:
|
||||
{
|
||||
BControl* ctrl;
|
||||
if (msg->FindPointer("source", (void**) &ctrl) == B_OK) {
|
||||
PatchCheckBox* box = dynamic_cast<PatchCheckBox*>(ctrl);
|
||||
if (box) {
|
||||
box->DoConnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BView::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PatchCheckBox::DoConnect()
|
||||
{
|
||||
int32 value = Value();
|
||||
int32 inverseValue = (value + 1) % 2;
|
||||
|
||||
BMidiRoster* roster = BMidiRoster::MidiRoster();
|
||||
if (! roster) {
|
||||
SetValue(inverseValue);
|
||||
return;
|
||||
}
|
||||
|
||||
BMidiProducer* producer = roster->FindProducer(m_producerID);
|
||||
BMidiConsumer* consumer = roster->FindConsumer(m_consumerID);
|
||||
if (producer && consumer) {
|
||||
status_t err;
|
||||
if (value) {
|
||||
err = producer->Connect(consumer);
|
||||
} else {
|
||||
err = producer->Disconnect(consumer);
|
||||
}
|
||||
|
||||
if (err != B_OK) {
|
||||
SetValue(inverseValue);
|
||||
}
|
||||
} else {
|
||||
SetValue(inverseValue);
|
||||
}
|
||||
if (producer) producer->Release();
|
||||
if (consumer) consumer->Release();
|
||||
}
|
38
src/tests/kits/midi/patchbay/PatchRow.h
Normal file
38
src/tests/kits/midi/patchbay/PatchRow.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef _PatchRow_h
|
||||
#define _PatchRow_h
|
||||
|
||||
#include <View.h>
|
||||
|
||||
extern const float ROW_LEFT;
|
||||
extern const float ROW_TOP;
|
||||
extern const float ROW_HEIGHT;
|
||||
extern const float COLUMN_WIDTH;
|
||||
extern const float METER_PADDING;
|
||||
extern const uint32 MSG_CONNECT_REQUEST;
|
||||
|
||||
class MidiEventMeter;
|
||||
|
||||
class PatchRow : public BView
|
||||
{
|
||||
public:
|
||||
PatchRow(int32 producerID);
|
||||
~PatchRow();
|
||||
|
||||
int32 ID() const;
|
||||
|
||||
void AttachedToWindow();
|
||||
void MessageReceived(BMessage* msg);
|
||||
void Pulse();
|
||||
void Draw(BRect updateRect);
|
||||
|
||||
void AddColumn(int32 consumerID);
|
||||
void RemoveColumn(int32 consumerID);
|
||||
void Connect(int32 consumerID);
|
||||
void Disconnect(int32 consumerID);
|
||||
|
||||
private:
|
||||
int32 m_producerID;
|
||||
MidiEventMeter* m_eventMeter;
|
||||
};
|
||||
|
||||
#endif /* _PatchRow_h */
|
462
src/tests/kits/midi/patchbay/PatchView.cpp
Normal file
462
src/tests/kits/midi/patchbay/PatchView.cpp
Normal file
@ -0,0 +1,462 @@
|
||||
// PatchView.cpp
|
||||
// -------------
|
||||
// Implements the main PatchBay view class.
|
||||
//
|
||||
// Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
// This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
#include <Application.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Debug.h>
|
||||
#include <InterfaceDefs.h>
|
||||
#include <Message.h>
|
||||
#include <Messenger.h>
|
||||
#include <MidiRoster.h>
|
||||
#include <Window.h>
|
||||
#include "EndpointInfo.h"
|
||||
#include "PatchView.h"
|
||||
#include "PatchRow.h"
|
||||
#include "TToolTip.h"
|
||||
#include "UnknownDeviceIcons.h"
|
||||
|
||||
PatchView::PatchView(BRect r)
|
||||
: BView(r, "PatchView", B_FOLLOW_ALL, B_WILL_DRAW),
|
||||
m_unknownDeviceIcon(NULL), m_trackIndex(-1), m_trackType(TRACK_COLUMN)
|
||||
{
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
|
||||
uint8 iconSize;
|
||||
const uint8* iconData;
|
||||
|
||||
if (DISPLAY_ICON_SIZE == B_LARGE_ICON) {
|
||||
iconSize = LARGE_ICON_SIZE;
|
||||
iconData = UnknownDevice::kLargeIconBits;
|
||||
} else {
|
||||
iconSize = MINI_ICON_SIZE;
|
||||
iconData = UnknownDevice::kMiniIconBits;
|
||||
}
|
||||
|
||||
BRect iconFrame(0, 0, iconSize-1, iconSize-1);
|
||||
m_unknownDeviceIcon = new BBitmap(iconFrame, ICON_COLOR_SPACE);
|
||||
memcpy(m_unknownDeviceIcon->Bits(), iconData, m_unknownDeviceIcon->BitsLength());
|
||||
}
|
||||
|
||||
PatchView::~PatchView()
|
||||
{
|
||||
delete m_unknownDeviceIcon;
|
||||
}
|
||||
|
||||
void PatchView::AttachedToWindow()
|
||||
{
|
||||
BMidiRoster* roster = BMidiRoster::MidiRoster();
|
||||
if (! roster) {
|
||||
PRINT(("Couldn't get MIDI roster\n"));
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
return;
|
||||
}
|
||||
|
||||
BMessenger msgr(this);
|
||||
roster->StartWatching(&msgr);
|
||||
}
|
||||
|
||||
void PatchView::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case B_MIDI_EVENT:
|
||||
HandleMidiEvent(msg);
|
||||
break;
|
||||
default:
|
||||
BView::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PatchView::MouseMoved(BPoint pt, uint32 transit, const BMessage* /* dragMsg */)
|
||||
{
|
||||
if (transit == B_EXITED_VIEW || transit == B_OUTSIDE_VIEW) {
|
||||
StopTipTracking();
|
||||
return;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
int32 size = m_consumers.size();
|
||||
for (int32 i=0; (! found) && i<size; i++) {
|
||||
BRect r = ColumnIconFrameAt(i);
|
||||
if (r.Contains(pt)) {
|
||||
StartTipTracking(pt, r, i, TRACK_COLUMN);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
size = m_producers.size();
|
||||
for (int32 i=0; (! found) && i<size; i++) {
|
||||
BRect r = RowIconFrameAt(i);
|
||||
if (r.Contains(pt)) {
|
||||
StartTipTracking(pt, r, i, TRACK_ROW);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PatchView::StopTipTracking()
|
||||
{
|
||||
m_trackIndex = -1;
|
||||
m_trackType = TRACK_COLUMN;
|
||||
StopTip();
|
||||
}
|
||||
|
||||
void PatchView::StartTipTracking(BPoint pt, BRect rect, int32 index, track_type type)
|
||||
{
|
||||
if (index == m_trackIndex && type == m_trackType)
|
||||
return;
|
||||
|
||||
StopTip();
|
||||
m_trackIndex = index;
|
||||
m_trackType = type;
|
||||
|
||||
endpoint_itor begin, end;
|
||||
if (type == TRACK_COLUMN) {
|
||||
begin = m_consumers.begin();
|
||||
end = m_consumers.end();
|
||||
} else {
|
||||
begin = m_producers.begin();
|
||||
end = m_producers.end();
|
||||
}
|
||||
|
||||
endpoint_itor i;
|
||||
for (i = begin; i != end; i++, index--)
|
||||
if (index <= 0) break;
|
||||
|
||||
if (i == end)
|
||||
return;
|
||||
|
||||
BMidiRoster* roster = BMidiRoster::MidiRoster();
|
||||
if (! roster)
|
||||
return;
|
||||
BMidiEndpoint* obj = roster->FindEndpoint(i->ID());
|
||||
if (! obj)
|
||||
return;
|
||||
|
||||
BString str;
|
||||
str << "<" << obj->ID() << ">: " << obj->Name();
|
||||
obj->Release();
|
||||
StartTip(pt, rect, str.String());
|
||||
}
|
||||
|
||||
void PatchView::StartTip(BPoint pt, BRect rect, const char* str)
|
||||
{
|
||||
BMessage msg(eToolTipStart);
|
||||
msg.AddPoint("start", ConvertToScreen(pt));
|
||||
msg.AddRect("bounds", ConvertToScreen(rect));
|
||||
msg.AddString("string", str);
|
||||
be_app->PostMessage(&msg);
|
||||
}
|
||||
|
||||
void PatchView::StopTip()
|
||||
{
|
||||
be_app->PostMessage(eToolTipStop);
|
||||
}
|
||||
|
||||
void PatchView::Draw(BRect /* updateRect */)
|
||||
{
|
||||
// draw producer icons
|
||||
SetDrawingMode(B_OP_OVER);
|
||||
int32 index = 0;
|
||||
for (list<EndpointInfo>::const_iterator i = m_producers.begin(); i != m_producers.end(); i++) {
|
||||
const BBitmap* bitmap = (i->Icon()) ? i->Icon() : m_unknownDeviceIcon;
|
||||
DrawBitmapAsync(bitmap, RowIconFrameAt(index++).LeftTop());
|
||||
}
|
||||
|
||||
// draw consumer icons
|
||||
index = 0;
|
||||
for (list<EndpointInfo>::const_iterator i = m_consumers.begin(); i != m_consumers.end(); i++) {
|
||||
const BBitmap* bitmap = (i->Icon()) ? i->Icon() : m_unknownDeviceIcon;
|
||||
DrawBitmapAsync(bitmap, ColumnIconFrameAt(index++).LeftTop());
|
||||
}
|
||||
}
|
||||
|
||||
BRect PatchView::ColumnIconFrameAt(int32 index) const
|
||||
{
|
||||
BRect r;
|
||||
r.left = ROW_LEFT + METER_PADDING + index*COLUMN_WIDTH;
|
||||
r.top = 10;
|
||||
r.right = r.left + 31;
|
||||
r.bottom = r.top + 31;
|
||||
return r;
|
||||
}
|
||||
|
||||
BRect PatchView::RowIconFrameAt(int32 index) const
|
||||
{
|
||||
BRect r;
|
||||
r.left = 10;
|
||||
r.top = ROW_TOP + index*ROW_HEIGHT;
|
||||
r.right = r.left + 31;
|
||||
r.bottom = r.top + 31;
|
||||
return r;
|
||||
}
|
||||
|
||||
void PatchView::HandleMidiEvent(BMessage* msg)
|
||||
{
|
||||
SET_DEBUG_ENABLED(true);
|
||||
|
||||
int32 op;
|
||||
if (msg->FindInt32("be:op", &op) != B_OK) {
|
||||
PRINT(("PatchView::HandleMidiEvent: \"op\" field not found\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case B_MIDI_REGISTERED:
|
||||
{
|
||||
int32 id;
|
||||
if (msg->FindInt32("be:id", &id) != B_OK) {
|
||||
PRINT(("PatchView::HandleMidiEvent: \"be:id\" field not found in B_MIDI_REGISTERED event\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
const char* type;
|
||||
if (msg->FindString("be:type", &type) != B_OK) {
|
||||
PRINT(("PatchView::HandleMidiEvent: \"be:type\" field not found in B_MIDI_REGISTERED event\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
PRINT(("MIDI Roster Event B_MIDI_REGISTERED: id=%ld, type=%s\n", id, type));
|
||||
if (! strcmp(type, "producer")) {
|
||||
AddProducer(id);
|
||||
} else if (! strcmp(type, "consumer")) {
|
||||
AddConsumer(id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case B_MIDI_UNREGISTERED:
|
||||
{
|
||||
int32 id;
|
||||
if (msg->FindInt32("be:id", &id) != B_OK) {
|
||||
PRINT(("PatchView::HandleMidiEvent: \"be:id\" field not found in B_MIDI_UNREGISTERED\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
const char* type;
|
||||
if (msg->FindString("be:type", &type) != B_OK) {
|
||||
PRINT(("PatchView::HandleMidiEvent: \"be:type\" field not found in B_MIDI_UNREGISTERED\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
PRINT(("MIDI Roster Event B_MIDI_UNREGISTERED: id=%ld, type=%s\n", id, type));
|
||||
if (! strcmp(type, "producer")) {
|
||||
RemoveProducer(id);
|
||||
} else if (! strcmp(type, "consumer")) {
|
||||
RemoveConsumer(id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case B_MIDI_CHANGED_PROPERTIES:
|
||||
{
|
||||
int32 id;
|
||||
if (msg->FindInt32("be:id", &id) != B_OK) {
|
||||
PRINT(("PatchView::HandleMidiEvent: \"be:id\" field not found in B_MIDI_CHANGED_PROPERTIES\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
const char* type;
|
||||
if (msg->FindString("be:type", &type) != B_OK) {
|
||||
PRINT(("PatchView::HandleMidiEvent: \"be:type\" field not found in B_MIDI_CHANGED_PROPERTIES\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
BMessage props;
|
||||
if (msg->FindMessage("be:properties", &props) != B_OK) {
|
||||
PRINT(("PatchView::HandleMidiEvent: \"be:properties\" field not found in B_MIDI_CHANGED_PROPERTIES\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
PRINT(("MIDI Roster Event B_MIDI_CHANGED_PROPERTIES: id=%ld, type=%s\n", id, type));
|
||||
if (! strcmp(type, "producer")) {
|
||||
UpdateProducerProps(id, &props);
|
||||
} else if (! strcmp(type, "consumer")) {
|
||||
UpdateConsumerProps(id, &props);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case B_MIDI_CHANGED_NAME:
|
||||
case B_MIDI_CHANGED_LATENCY:
|
||||
// we don't care about these
|
||||
break;
|
||||
case B_MIDI_CONNECTED:
|
||||
{
|
||||
int32 prod;
|
||||
if (msg->FindInt32("be:producer", &prod) != B_OK) {
|
||||
PRINT(("PatchView::HandleMidiEvent: \"be:producer\" field not found in B_MIDI_CONNECTED\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
int32 cons;
|
||||
if (msg->FindInt32("be:consumer", &cons) != B_OK) {
|
||||
PRINT(("PatchView::HandleMidiEvent: \"be:consumer\" field not found in B_MIDI_CONNECTED\n"));
|
||||
break;
|
||||
}
|
||||
PRINT(("MIDI Roster Event B_MIDI_CONNECTED: producer=%ld, consumer=%ld\n", prod, cons));
|
||||
Connect(prod, cons);
|
||||
}
|
||||
break;
|
||||
case B_MIDI_DISCONNECTED:
|
||||
{
|
||||
int32 prod;
|
||||
if (msg->FindInt32("be:producer", &prod) != B_OK) {
|
||||
PRINT(("PatchView::HandleMidiEvent: \"be:producer\" field not found in B_MIDI_DISCONNECTED\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
int32 cons;
|
||||
if (msg->FindInt32("be:consumer", &cons) != B_OK) {
|
||||
PRINT(("PatchView::HandleMidiEvent: \"be:consumer\" field not found in B_MIDI_DISCONNECTED\n"));
|
||||
break;
|
||||
}
|
||||
PRINT(("MIDI Roster Event B_MIDI_DISCONNECTED: producer=%ld, consumer=%ld\n", prod, cons));
|
||||
Disconnect(prod, cons);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PRINT(("PatchView::HandleMidiEvent: unknown opcode %ld\n", op));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PatchView::AddProducer(int32 id)
|
||||
{
|
||||
EndpointInfo info(id);
|
||||
m_producers.push_back(info);
|
||||
|
||||
Window()->BeginViewTransaction();
|
||||
PatchRow* row = new PatchRow(id);
|
||||
m_patchRows.push_back(row);
|
||||
BPoint p1 = CalcRowOrigin(m_patchRows.size() - 1);
|
||||
BPoint p2 = CalcRowSize();
|
||||
row->MoveTo(p1);
|
||||
row->ResizeTo(p2.x, p2.y);
|
||||
for (list<EndpointInfo>::const_iterator i = m_consumers.begin(); i != m_consumers.end(); i++) {
|
||||
row->AddColumn(i->ID());
|
||||
}
|
||||
AddChild(row);
|
||||
Invalidate();
|
||||
Window()->EndViewTransaction();
|
||||
}
|
||||
|
||||
void PatchView::AddConsumer(int32 id)
|
||||
{
|
||||
EndpointInfo info(id);
|
||||
m_consumers.push_back(info);
|
||||
|
||||
Window()->BeginViewTransaction();
|
||||
BPoint newSize = CalcRowSize();
|
||||
for (row_itor i = m_patchRows.begin(); i != m_patchRows.end(); i++) {
|
||||
(*i)->AddColumn(id);
|
||||
(*i)->ResizeTo(newSize.x, newSize.y - 1);
|
||||
}
|
||||
Invalidate();
|
||||
Window()->EndViewTransaction();
|
||||
}
|
||||
|
||||
void PatchView::RemoveProducer(int32 id)
|
||||
{
|
||||
for (endpoint_itor i = m_producers.begin(); i != m_producers.end(); i++) {
|
||||
if (i->ID() == id) {
|
||||
m_producers.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Window()->BeginViewTransaction();
|
||||
for (row_itor i = m_patchRows.begin(); i != m_patchRows.end(); i++) {
|
||||
if ((*i)->ID() == id) {
|
||||
PatchRow* row = *i;
|
||||
i = m_patchRows.erase(i);
|
||||
RemoveChild(row);
|
||||
delete row;
|
||||
float moveBy = -1*CalcRowSize().y;
|
||||
while (i != m_patchRows.end()) {
|
||||
(*i++)->MoveBy(0, moveBy);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
Invalidate();
|
||||
Window()->EndViewTransaction();
|
||||
}
|
||||
|
||||
void PatchView::RemoveConsumer(int32 id)
|
||||
{
|
||||
Window()->BeginViewTransaction();
|
||||
for (endpoint_itor i = m_consumers.begin(); i != m_consumers.end(); i++) {
|
||||
if (i->ID() == id) {
|
||||
m_consumers.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BPoint newSize = CalcRowSize();
|
||||
for (row_itor i = m_patchRows.begin(); i != m_patchRows.end(); i++) {
|
||||
(*i)->RemoveColumn(id);
|
||||
(*i)->ResizeTo(newSize.x, newSize.y - 1);
|
||||
}
|
||||
Invalidate();
|
||||
Window()->EndViewTransaction();
|
||||
}
|
||||
|
||||
void PatchView::UpdateProducerProps(int32 id, const BMessage* props)
|
||||
{
|
||||
for (endpoint_itor i = m_producers.begin(); i != m_producers.end(); i++) {
|
||||
if (i->ID() == id) {
|
||||
i->UpdateProperties(props);
|
||||
Invalidate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PatchView::UpdateConsumerProps(int32 id, const BMessage* props)
|
||||
{
|
||||
for (endpoint_itor i = m_consumers.begin(); i != m_consumers.end(); i++) {
|
||||
if (i->ID() == id) {
|
||||
i->UpdateProperties(props);
|
||||
Invalidate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PatchView::Connect(int32 prod, int32 cons)
|
||||
{
|
||||
for (row_itor i = m_patchRows.begin(); i != m_patchRows.end(); i++) {
|
||||
if ((*i)->ID() == prod) {
|
||||
(*i)->Connect(cons);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PatchView::Disconnect(int32 prod, int32 cons)
|
||||
{
|
||||
for (row_itor i = m_patchRows.begin(); i != m_patchRows.end(); i++) {
|
||||
if ((*i)->ID() == prod) {
|
||||
(*i)->Disconnect(cons);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BPoint PatchView::CalcRowOrigin(int32 rowIndex) const
|
||||
{
|
||||
BPoint pt;
|
||||
pt.x = ROW_LEFT;
|
||||
pt.y = ROW_TOP + rowIndex*ROW_HEIGHT;
|
||||
return pt;
|
||||
}
|
||||
|
||||
BPoint PatchView::CalcRowSize() const
|
||||
{
|
||||
BPoint pt;
|
||||
pt.x = METER_PADDING + m_consumers.size()*COLUMN_WIDTH;
|
||||
pt.y = ROW_HEIGHT - 1;
|
||||
return pt;
|
||||
}
|
75
src/tests/kits/midi/patchbay/PatchView.h
Normal file
75
src/tests/kits/midi/patchbay/PatchView.h
Normal file
@ -0,0 +1,75 @@
|
||||
// PatchView.h
|
||||
// -----------
|
||||
// The main PatchBay view contains a row of icons along the top and
|
||||
// left sides representing available consumers and producers, and
|
||||
// a set of PatchRows which build the matrix of connections.
|
||||
//
|
||||
// Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
// This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
#ifndef _PatchView_h
|
||||
#define _PatchView_h
|
||||
|
||||
#include <Rect.h>
|
||||
#include <View.h>
|
||||
#include <list>
|
||||
#include "EndpointInfo.h"
|
||||
|
||||
class PatchRow;
|
||||
class BBitmap;
|
||||
class TToolTip;
|
||||
|
||||
using namespace std;
|
||||
|
||||
class PatchView : public BView
|
||||
{
|
||||
public:
|
||||
PatchView(BRect r);
|
||||
~PatchView();
|
||||
|
||||
void AttachedToWindow();
|
||||
void MessageReceived(BMessage* msg);
|
||||
void Draw(BRect updateRect);
|
||||
void MouseMoved(BPoint point, uint32 transit, const BMessage* dragMsg);
|
||||
|
||||
private:
|
||||
typedef enum {
|
||||
TRACK_COLUMN,
|
||||
TRACK_ROW
|
||||
} track_type;
|
||||
|
||||
BRect ColumnIconFrameAt(int32 index) const;
|
||||
BRect RowIconFrameAt(int32 index) const;
|
||||
void StartTipTracking(BPoint pt, BRect rect, int32 index, track_type type=TRACK_COLUMN);
|
||||
void StopTipTracking();
|
||||
void StartTip(BPoint pt, BRect rect, const char* str);
|
||||
void StopTip();
|
||||
|
||||
void AddProducer(int32 id);
|
||||
void AddConsumer(int32 id);
|
||||
void RemoveProducer(int32 id);
|
||||
void RemoveConsumer(int32 id);
|
||||
void UpdateProducerProps(int32 id, const BMessage* props);
|
||||
void UpdateConsumerProps(int32 id, const BMessage* props);
|
||||
void Connect(int32 prod, int32 cons);
|
||||
void Disconnect(int32 prod, int32 cons);
|
||||
|
||||
void HandleMidiEvent(BMessage* msg);
|
||||
|
||||
BPoint CalcRowOrigin(int32 rowIndex) const;
|
||||
BPoint CalcRowSize() const;
|
||||
|
||||
typedef list<EndpointInfo>::iterator endpoint_itor;
|
||||
typedef list<EndpointInfo>::const_iterator const_endpoint_itor;
|
||||
typedef list<PatchRow*>::iterator row_itor;
|
||||
|
||||
list<EndpointInfo> m_producers;
|
||||
list<EndpointInfo> m_consumers;
|
||||
list<PatchRow*> m_patchRows;
|
||||
BBitmap* m_unknownDeviceIcon;
|
||||
int32 m_trackIndex;
|
||||
track_type m_trackType;
|
||||
TToolTip* m_toolTip;
|
||||
};
|
||||
|
||||
#endif /* _PatchView_h */
|
26
src/tests/kits/midi/patchbay/PatchWin.cpp
Normal file
26
src/tests/kits/midi/patchbay/PatchWin.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
// PatchWin.cpp
|
||||
// ------------
|
||||
// Implements the main PatchBay window class.
|
||||
//
|
||||
// Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
// This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
#include <Application.h>
|
||||
#include "PatchWin.h"
|
||||
#include "PatchView.h"
|
||||
|
||||
PatchWin::PatchWin()
|
||||
: BWindow(BRect(50,50,450,450), "Patch Bay", B_TITLED_WINDOW, 0)
|
||||
{
|
||||
BRect r = Bounds();
|
||||
m_patchView = new PatchView(r);
|
||||
AddChild(m_patchView);
|
||||
Show();
|
||||
}
|
||||
|
||||
bool PatchWin::QuitRequested()
|
||||
{
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
return true;
|
||||
}
|
||||
|
24
src/tests/kits/midi/patchbay/PatchWin.h
Normal file
24
src/tests/kits/midi/patchbay/PatchWin.h
Normal file
@ -0,0 +1,24 @@
|
||||
// PatchWin.h
|
||||
// ----------
|
||||
// The main PatchBay window class.
|
||||
//
|
||||
// Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
// This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
#ifndef _PatchWin_h
|
||||
#define _PatchWin_h
|
||||
|
||||
#include <Window.h>
|
||||
|
||||
class PatchView;
|
||||
|
||||
class PatchWin : public BWindow
|
||||
{
|
||||
public:
|
||||
PatchWin();
|
||||
bool QuitRequested();
|
||||
private:
|
||||
PatchView* m_patchView;
|
||||
};
|
||||
|
||||
#endif /* _PatchWin_h */
|
357
src/tests/kits/midi/patchbay/TToolTip.cpp
Normal file
357
src/tests/kits/midi/patchbay/TToolTip.cpp
Normal file
@ -0,0 +1,357 @@
|
||||
//--------------------------------------------------------------------
|
||||
//
|
||||
// TToolTip.cpp
|
||||
//
|
||||
// Written by: Robert Polic
|
||||
//
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#include <Screen.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Application.h>
|
||||
#include <Roster.h>
|
||||
|
||||
#include "TToolTip.h"
|
||||
|
||||
#define kHOR_MARGIN 4 // hor. gap between frame and tip
|
||||
#define kVER_MARGIN 3 // ver. gap between frame and tip
|
||||
#define kTIP_HOR_OFFSET 10 // tip position right of cursor
|
||||
#define kTIP_VER_OFFSET 16 // tip position below cursor
|
||||
#define kSLOP 4 // mouse slop before tip hides
|
||||
|
||||
#define kTOOL_TIP_DELAY_TIME 500000 // default delay time before tip shows (.5 secs.)
|
||||
#define kTOOL_TIP_HOLD_TIME 3000000 // default hold time of time (3 secs.)
|
||||
|
||||
#define kDRAW_WINDOW_FRAME
|
||||
|
||||
const rgb_color kVIEW_COLOR = {255, 203, 0, 255}; // view background color (light yellow)
|
||||
const rgb_color kLIGHT_VIEW_COLOR = {255, 255, 80, 255}; // top left frame highlight
|
||||
const rgb_color kDARK_VIEW_COLOR = {175, 123, 0, 255}; // bottom right frame highlight
|
||||
const rgb_color kTEXT_COLOR = {0, 0, 0, 255}; // text color (black)
|
||||
|
||||
|
||||
//====================================================================
|
||||
|
||||
TToolTip::TToolTip(tool_tip_settings *settings)
|
||||
:BWindow(BRect(0, 0, 10, 10), "tool_tip", B_NO_BORDER_WINDOW_LOOK,
|
||||
B_FLOATING_ALL_WINDOW_FEEL, B_AVOID_FRONT)
|
||||
{
|
||||
// setup the tooltip view
|
||||
AddChild(fView = new TToolTipView(settings));
|
||||
// start the message loop thread
|
||||
Run();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
void TToolTip::MessageReceived(BMessage *msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
// forward interesting messages to the view
|
||||
case B_SOME_APP_ACTIVATED:
|
||||
case eToolTipStart:
|
||||
case eToolTipStop:
|
||||
PostMessage(msg, fView);
|
||||
break;
|
||||
default:
|
||||
BWindow::MessageReceived(msg);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
void TToolTip::GetSettings(tool_tip_settings *settings)
|
||||
{
|
||||
fView->GetSettings(settings);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
void TToolTip::SetSettings(tool_tip_settings *settings)
|
||||
{
|
||||
fView->SetSettings(settings);
|
||||
}
|
||||
|
||||
|
||||
//====================================================================
|
||||
|
||||
TToolTipView::TToolTipView(tool_tip_settings *settings)
|
||||
:BView(BRect(0, 0, 10, 10), "tool_tip", B_FOLLOW_ALL, B_WILL_DRAW)
|
||||
{
|
||||
// initialize tooltip settings
|
||||
if (settings)
|
||||
// we should probably sanity-check user defined settings (but we won't)
|
||||
fTip.settings = *settings;
|
||||
else {
|
||||
// use defaults if no settings are passed
|
||||
fTip.settings.enabled = true;
|
||||
fTip.settings.one_time_only = false;
|
||||
fTip.settings.delay = kTOOL_TIP_DELAY_TIME;
|
||||
fTip.settings.hold = kTOOL_TIP_HOLD_TIME;
|
||||
fTip.settings.font = be_plain_font;
|
||||
}
|
||||
|
||||
// initialize the tip
|
||||
fString = (char *)malloc(1);
|
||||
fString[0] = 0;
|
||||
|
||||
// initialize the view
|
||||
SetFont(&fTip.settings.font);
|
||||
SetViewColor(kVIEW_COLOR);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
TToolTipView::~TToolTipView()
|
||||
{
|
||||
status_t status;
|
||||
|
||||
// kill tool_tip thread
|
||||
fTip.quit = true;
|
||||
wait_for_thread(fThread, &status);
|
||||
|
||||
// free tip
|
||||
free(fString);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
void TToolTipView::AllAttached()
|
||||
{
|
||||
// initialize internal settings
|
||||
fTip.app_active = true;
|
||||
fTip.quit = false;
|
||||
fTip.stopped = true;
|
||||
|
||||
fTip.tool_tip_view = this;
|
||||
fTip.tool_tip_window = Window();
|
||||
|
||||
// start tool_tip thread
|
||||
resume_thread(fThread = spawn_thread((status_t (*)(void *)) ToolTipThread,
|
||||
"tip_thread", B_DISPLAY_PRIORITY, &fTip));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
void TToolTipView::Draw(BRect /* where */)
|
||||
{
|
||||
char *src_strings[1];
|
||||
char *tmp_string;
|
||||
char *truncated_strings[1];
|
||||
BFont font;
|
||||
BRect r = Bounds();
|
||||
font_height finfo;
|
||||
|
||||
// draw border around window
|
||||
#ifdef kDRAW_WINDOW_FRAME
|
||||
SetHighColor(0, 0, 0, 255);
|
||||
StrokeRect(r);
|
||||
r.InsetBy(1, 1);
|
||||
#endif
|
||||
SetHighColor(kLIGHT_VIEW_COLOR);
|
||||
StrokeLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top));
|
||||
StrokeLine(BPoint(r.left + 1, r.top), BPoint(r.right - 1, r.top));
|
||||
SetHighColor(kDARK_VIEW_COLOR);
|
||||
StrokeLine(BPoint(r.right, r.top), BPoint(r.right, r.bottom));
|
||||
StrokeLine(BPoint(r.right - 1, r.bottom), BPoint(r.left + 1, r.bottom));
|
||||
|
||||
// set pen position
|
||||
GetFont(&font);
|
||||
font.GetHeight(&finfo);
|
||||
MovePenTo(kHOR_MARGIN + 1, kVER_MARGIN + finfo.ascent);
|
||||
|
||||
// truncate string if needed
|
||||
src_strings[0] = fString;
|
||||
tmp_string = (char *)malloc(strlen(fString) + 16);
|
||||
truncated_strings[0] = tmp_string;
|
||||
font.GetTruncatedStrings((const char **)src_strings, 1, B_TRUNCATE_END,
|
||||
Bounds().Width() - (2 * kHOR_MARGIN) + 1, truncated_strings);
|
||||
|
||||
// draw string
|
||||
SetLowColor(kVIEW_COLOR);
|
||||
SetHighColor(kTEXT_COLOR);
|
||||
DrawString(tmp_string);
|
||||
free(tmp_string);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
void TToolTipView::MessageReceived(BMessage *msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case B_SOME_APP_ACTIVATED:
|
||||
msg->FindBool("active", &fTip.app_active);
|
||||
break;
|
||||
|
||||
case eToolTipStart:
|
||||
{
|
||||
const char *str;
|
||||
|
||||
// extract parameters
|
||||
msg->FindPoint("start", &fTip.start);
|
||||
msg->FindRect("bounds", &fTip.bounds);
|
||||
msg->FindString("string", &str);
|
||||
free(fString);
|
||||
fString = (char *)malloc(strlen(str) + 1);
|
||||
strcpy(fString, str);
|
||||
|
||||
// force window to fit new parameters
|
||||
AdjustWindow();
|
||||
|
||||
// flag thread to reset
|
||||
fTip.reset = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case eToolTipStop:
|
||||
// flag thread to stop
|
||||
fTip.stop = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
void TToolTipView::GetSettings(tool_tip_settings *settings)
|
||||
{
|
||||
// return current settings
|
||||
*settings = fTip.settings;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
void TToolTipView::SetSettings(tool_tip_settings *settings)
|
||||
{
|
||||
bool invalidate = fTip.settings.font != settings->font;
|
||||
|
||||
// we should probably sanity-check user defined settings (but we won't)
|
||||
fTip.settings = *settings;
|
||||
|
||||
// if the font changed, adjust window to fit
|
||||
if (invalidate) {
|
||||
Window()->Lock();
|
||||
SetFont(&fTip.settings.font);
|
||||
AdjustWindow();
|
||||
Window()->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
void TToolTipView::AdjustWindow()
|
||||
{
|
||||
float width;
|
||||
float height;
|
||||
float x;
|
||||
float y;
|
||||
BScreen s(B_MAIN_SCREEN_ID);
|
||||
BRect screen = s.Frame();
|
||||
BWindow *wind = Window();
|
||||
font_height finfo;
|
||||
|
||||
screen.InsetBy(2, 2); // we want a 2-pixel clearance
|
||||
fTip.settings.font.GetHeight(&finfo);
|
||||
width = fTip.settings.font.StringWidth(fString) + (kHOR_MARGIN * 2); // string width
|
||||
height = (finfo.ascent + finfo.descent + finfo.leading) + (kVER_MARGIN * 2); // string height
|
||||
|
||||
// calculate new position and size of window
|
||||
x = fTip.start.x + kTIP_HOR_OFFSET;
|
||||
if ((x + width) > screen.right)
|
||||
x = screen.right - width;
|
||||
y = fTip.start.y + kTIP_VER_OFFSET;
|
||||
if ((y + height) > screen.bottom) {
|
||||
y = screen.bottom - height;
|
||||
if ((fTip.start.y >= (y - kSLOP)) && (fTip.start.y <= (y + height)))
|
||||
y = fTip.start.y - kTIP_VER_OFFSET - height;
|
||||
}
|
||||
if (x < screen.left) {
|
||||
width -= screen.left - x;
|
||||
x = screen.left;
|
||||
}
|
||||
if (y < screen.top) {
|
||||
height -= screen.top - y;
|
||||
y = screen.top;
|
||||
}
|
||||
|
||||
wind->MoveTo((int)x, (int)y);
|
||||
wind->ResizeTo((int)width, (int)height);
|
||||
|
||||
// force an update
|
||||
Invalidate(Bounds());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
status_t TToolTipView::ToolTipThread(tool_tip *tip)
|
||||
{
|
||||
uint32 buttons;
|
||||
BPoint where;
|
||||
BScreen s(B_MAIN_SCREEN_ID);
|
||||
BRect screen = s.Frame();
|
||||
|
||||
screen.InsetBy(2, 2);
|
||||
while (!tip->quit) {
|
||||
if (tip->tool_tip_window->LockWithTimeout(0) == B_NO_ERROR) {
|
||||
tip->tool_tip_view->GetMouse(&where, &buttons);
|
||||
tip->tool_tip_view->ConvertToScreen(&where);
|
||||
|
||||
tip->stopped = tip->stop;
|
||||
if (tip->reset) {
|
||||
if (tip->showing)
|
||||
tip->tool_tip_window->Hide();
|
||||
tip->stop = false;
|
||||
tip->stopped = false;
|
||||
tip->reset = false;
|
||||
tip->shown = false;
|
||||
tip->showing = false;
|
||||
tip->start_time = system_time() + tip->settings.delay;
|
||||
}
|
||||
else if (tip->showing) {
|
||||
if ((tip->stop) ||
|
||||
(!tip->settings.enabled) ||
|
||||
(!tip->app_active) ||
|
||||
(!tip->bounds.Contains(where)) ||
|
||||
(tip->expire_time < system_time()) ||
|
||||
(abs((int)tip->start.x - (int)where.x) > kSLOP) ||
|
||||
(abs((int)tip->start.y - (int)where.y) > kSLOP) ||
|
||||
(buttons)) {
|
||||
tip->tool_tip_window->Hide();
|
||||
tip->shown = tip->settings.one_time_only;
|
||||
tip->showing = false;
|
||||
tip->tip_timed_out = (tip->expire_time < system_time());
|
||||
tip->start_time = system_time() + tip->settings.delay;
|
||||
}
|
||||
}
|
||||
else if ((tip->settings.enabled) &&
|
||||
(!tip->stopped) &&
|
||||
(tip->app_active) &&
|
||||
(!tip->shown) &&
|
||||
(!tip->tip_timed_out) &&
|
||||
(!buttons) &&
|
||||
(tip->bounds.Contains(where)) &&
|
||||
(tip->start_time < system_time())) {
|
||||
tip->start = where;
|
||||
tip->tool_tip_view->AdjustWindow();
|
||||
tip->tool_tip_window->Show();
|
||||
tip->tool_tip_window->Activate(false);
|
||||
tip->showing = true;
|
||||
tip->expire_time = system_time() + tip->settings.hold;
|
||||
tip->start = where;
|
||||
}
|
||||
else if ((abs((int)tip->start.x - (int)where.x) > kSLOP) ||
|
||||
(abs((int)tip->start.y - (int)where.y) > kSLOP)) {
|
||||
tip->start = where;
|
||||
tip->start_time = system_time() + tip->settings.delay;
|
||||
tip->tip_timed_out = false;
|
||||
}
|
||||
if (buttons)
|
||||
tip->start_time = system_time() + tip->settings.delay;
|
||||
tip->tool_tip_window->Unlock();
|
||||
}
|
||||
snooze(50000);
|
||||
}
|
||||
return B_NO_ERROR;
|
||||
}
|
86
src/tests/kits/midi/patchbay/TToolTip.h
Normal file
86
src/tests/kits/midi/patchbay/TToolTip.h
Normal file
@ -0,0 +1,86 @@
|
||||
//--------------------------------------------------------------------
|
||||
//
|
||||
// TToolTip.h
|
||||
//
|
||||
// Written by: Robert Polic
|
||||
//
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#ifndef T_TOOL_TIPS_H
|
||||
#define T_TOOL_TIPS_H
|
||||
|
||||
#include <Font.h>
|
||||
#include <Window.h>
|
||||
#include <View.h>
|
||||
|
||||
enum TOOL_TIP_MESSAGES {eToolTipStart = 'ttGo',
|
||||
eToolTipStop = 'ttSp'};
|
||||
|
||||
// ui settings
|
||||
struct tool_tip_settings {
|
||||
bool enabled; // flag whether tips are enables or not
|
||||
bool one_time_only; // flag to only display the tip once per time in view
|
||||
bigtime_t delay; // delay before tip is shown in microseconds
|
||||
bigtime_t hold; // amount of time tip is displayed in microseconds
|
||||
BFont font; // font tip is drawn in
|
||||
};
|
||||
|
||||
// internal settings
|
||||
struct tool_tip {
|
||||
bool app_active;
|
||||
bool quit;
|
||||
bool stop;
|
||||
bool stopped;
|
||||
bool reset;
|
||||
bool shown;
|
||||
bool showing;
|
||||
bool tip_timed_out;
|
||||
BPoint start;
|
||||
BRect bounds;
|
||||
class TToolTipView *tool_tip_view;
|
||||
BWindow *tool_tip_window;
|
||||
bigtime_t start_time;
|
||||
bigtime_t expire_time;
|
||||
tool_tip_settings settings;
|
||||
};
|
||||
|
||||
|
||||
//====================================================================
|
||||
|
||||
class TToolTip : public BWindow {
|
||||
|
||||
public:
|
||||
TToolTip(tool_tip_settings *settings = NULL);
|
||||
virtual void MessageReceived(BMessage*);
|
||||
|
||||
void GetSettings(tool_tip_settings*);
|
||||
void SetSettings(tool_tip_settings*);
|
||||
|
||||
private:
|
||||
class TToolTipView *fView;
|
||||
};
|
||||
|
||||
|
||||
//====================================================================
|
||||
|
||||
class TToolTipView : public BView {
|
||||
|
||||
public:
|
||||
TToolTipView(tool_tip_settings *settings = NULL);
|
||||
~TToolTipView();
|
||||
virtual void AllAttached();
|
||||
virtual void Draw(BRect);
|
||||
virtual void MessageReceived(BMessage*);
|
||||
|
||||
void GetSettings(tool_tip_settings*);
|
||||
void SetSettings(tool_tip_settings*);
|
||||
|
||||
private:
|
||||
void AdjustWindow();
|
||||
static status_t ToolTipThread(tool_tip*);
|
||||
|
||||
char *fString;
|
||||
thread_id fThread;
|
||||
tool_tip fTip;
|
||||
};
|
||||
#endif
|
106
src/tests/kits/midi/patchbay/UnknownDeviceIcons.h
Normal file
106
src/tests/kits/midi/patchbay/UnknownDeviceIcons.h
Normal file
@ -0,0 +1,106 @@
|
||||
// UnknownDeviceIcons.h
|
||||
// --------------------
|
||||
// The icons to be used in case a device doesn't supply its icons.
|
||||
// In the future, this could be better selected if the device supported
|
||||
// other descriptive property fields.
|
||||
//
|
||||
// Large and mini versions are available. PatchBay currently uses the
|
||||
// large version.
|
||||
//
|
||||
// Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
// This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
#ifndef _UnknownDeviceIcons_h
|
||||
#define _UnknownDeviceIcons_h
|
||||
|
||||
namespace UnknownDevice {
|
||||
|
||||
const unsigned char kLargeIconBits [] = {
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
|
||||
0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0xff,
|
||||
0xff,0xff,0xff,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x0c,0x0c,
|
||||
0xff,0xff,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x08,0x08,0x0c,
|
||||
0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
|
||||
0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x0d,0x04,0x00,0x00,0x04,
|
||||
0x0d,0x1b,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x16,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x12,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x16,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x0d,0x00,0x00,0x00,0x0d,0x1b,0x3f,0x16,
|
||||
0x04,0x00,0x00,0x09,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x04,0x00,0x00,0x0d,0x3f,0x3f,0x3f,0x3f,
|
||||
0x16,0x00,0x00,0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,0x00,0x1b,0x3f,0x3f,0x3f,0x3f,
|
||||
0x1b,0x00,0x00,0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x1b,
|
||||
0x04,0x00,0x00,0x04,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x0d,0x00,
|
||||
0x00,0x00,0x00,0x16,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x1b,0x00,0x00,0x00,
|
||||
0x00,0x0d,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x04,0x00,0x00,0x09,
|
||||
0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,0x00,0x3f,
|
||||
0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
|
||||
0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
|
||||
0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,0x00,0x00,
|
||||
0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,0x00,0x00,
|
||||
0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,0x00,0x00,
|
||||
0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0x08,0xff,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,0x00,0x00,
|
||||
0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x04,0xff,0xff,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
|
||||
0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0xff,0xff,0xff,
|
||||
0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
|
||||
};
|
||||
|
||||
const unsigned char kMiniIconBits [] = {
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0xff,
|
||||
0xff,0xff,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x0c,0x0c,
|
||||
0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x16,0x00,0x00,0x00,0x1b,0x3f,0x3f,0x3f,0x3f,0x00,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x00,0x16,0x3f,0x1b,0x00,0x3f,0x3f,0x3f,0x3f,0x00,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x1b,0x00,0x3f,0x3f,0x3f,0x3f,0x00,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x09,0x00,0x1b,0x3f,0x3f,0x3f,0x3f,0x00,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x1b,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x08,0x0c,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x08,0xff,
|
||||
0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0xff,0xff,
|
||||
0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* _UnknownDeviceIcons_h */
|
Loading…
x
Reference in New Issue
Block a user