reflexion 0.3.8.1 → 0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.doc/ext/reflex/control_change_event.cpp +101 -0
- data/.doc/ext/reflex/midi.cpp +16 -0
- data/.doc/ext/reflex/midi_event.cpp +124 -0
- data/.doc/ext/reflex/native.cpp +4 -0
- data/.doc/ext/reflex/view.cpp +41 -1
- data/.doc/ext/reflex/window.cpp +16 -0
- data/ChangeLog.md +7 -0
- data/VERSION +1 -1
- data/ext/reflex/control_change_event.cpp +108 -0
- data/ext/reflex/midi.cpp +21 -3
- data/ext/reflex/midi_event.cpp +132 -0
- data/ext/reflex/native.cpp +4 -0
- data/ext/reflex/view.cpp +49 -4
- data/ext/reflex/window.cpp +22 -4
- data/include/reflex/event.h +89 -0
- data/include/reflex/midi.h +4 -0
- data/include/reflex/ruby/event.h +22 -0
- data/include/reflex/ruby/midi.h +19 -0
- data/include/reflex/ruby/view.h +45 -0
- data/include/reflex/ruby/window.h +18 -0
- data/include/reflex/view.h +6 -2
- data/include/reflex/window.h +4 -0
- data/lib/reflex/midi_event.rb +68 -0
- data/lib/reflex/view.rb +2 -2
- data/lib/reflex.rb +1 -0
- data/reflex.gemspec +3 -3
- data/src/event.cpp +189 -0
- data/src/event.h +11 -0
- data/src/midi.cpp +67 -59
- data/src/view.cpp +38 -0
- data/src/view.h +9 -5
- data/src/window.cpp +81 -6
- data/src/window.h +1 -1
- data/test/test_capture_event.rb +8 -8
- data/test/test_midi_event.rb +93 -0
- data/test/test_view.rb +13 -13
- metadata +23 -14
data/src/event.cpp
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
#include "reflex/device.h"
|
6
6
|
#include "reflex/timer.h"
|
7
7
|
#include "reflex/shape.h"
|
8
|
+
#include "reflex/midi.h"
|
8
9
|
#include "reflex/exception.h"
|
9
10
|
#include "view.h"
|
10
11
|
#include "pointer.h"
|
@@ -868,6 +869,124 @@ namespace Reflex
|
|
868
869
|
}
|
869
870
|
|
870
871
|
|
872
|
+
struct MIDIEvent::Data
|
873
|
+
{
|
874
|
+
|
875
|
+
MIDI::Ref midi;
|
876
|
+
|
877
|
+
uchar bytes[3] = {0};
|
878
|
+
|
879
|
+
bool captured = false;
|
880
|
+
|
881
|
+
};// MIDIEvent
|
882
|
+
|
883
|
+
|
884
|
+
bool
|
885
|
+
MIDIEvent_to_note_event (NoteEvent* result, const MIDIEvent& event)
|
886
|
+
{
|
887
|
+
auto a = event.action();
|
888
|
+
if (a != MIDIEvent::NOTE_ON && a != MIDIEvent::NOTE_OFF)
|
889
|
+
return false;
|
890
|
+
|
891
|
+
*result = NoteEvent(
|
892
|
+
a == MIDIEvent::NOTE_ON ? NoteEvent::ON : NoteEvent::OFF,
|
893
|
+
event.channel(), event.data1(), event.data2() / 127.f, event.time());
|
894
|
+
return true;
|
895
|
+
}
|
896
|
+
|
897
|
+
bool
|
898
|
+
MIDIEvent_to_control_change_event (
|
899
|
+
ControlChangeEvent* result, const MIDIEvent& event)
|
900
|
+
{
|
901
|
+
if (event.action() != MIDIEvent::CONTROL_CHANGE)
|
902
|
+
return false;
|
903
|
+
|
904
|
+
*result = ControlChangeEvent(
|
905
|
+
event.channel(), event.data1(), event.data2() / 127.f, event.time());
|
906
|
+
return true;
|
907
|
+
}
|
908
|
+
|
909
|
+
void
|
910
|
+
MIDIEvent_set_captured (MIDIEvent* pthis, bool captured)
|
911
|
+
{
|
912
|
+
pthis->self->captured = captured;
|
913
|
+
}
|
914
|
+
|
915
|
+
|
916
|
+
MIDIEvent::MIDIEvent ()
|
917
|
+
{
|
918
|
+
}
|
919
|
+
|
920
|
+
MIDIEvent::MIDIEvent (MIDI* midi, const uchar* bytes, double time)
|
921
|
+
: Event(time)
|
922
|
+
{
|
923
|
+
self->midi = midi;
|
924
|
+
memcpy(self->bytes, bytes, sizeof(uchar) * 3);
|
925
|
+
}
|
926
|
+
|
927
|
+
MIDIEvent::MIDIEvent (const MIDIEvent* src)
|
928
|
+
: Event(src), self(new Data(*src->self))
|
929
|
+
{
|
930
|
+
}
|
931
|
+
|
932
|
+
MIDIEvent
|
933
|
+
MIDIEvent::dup () const
|
934
|
+
{
|
935
|
+
return MIDIEvent(this);
|
936
|
+
}
|
937
|
+
|
938
|
+
MIDI*
|
939
|
+
MIDIEvent::midi () const
|
940
|
+
{
|
941
|
+
return self->midi;
|
942
|
+
}
|
943
|
+
|
944
|
+
MIDIEvent::Action
|
945
|
+
MIDIEvent::action () const
|
946
|
+
{
|
947
|
+
switch (self->bytes[0] >> 4)
|
948
|
+
{
|
949
|
+
case 0x9: return NOTE_ON;
|
950
|
+
case 0x8: return NOTE_OFF;
|
951
|
+
case 0xA: return KEY_PRESSURE;
|
952
|
+
case 0xB: return CONTROL_CHANGE;
|
953
|
+
case 0xC: return PROGRAM_CHANGE;
|
954
|
+
case 0xD: return CHANNEL_PRESSURE;
|
955
|
+
case 0xE: return PITCH_BEND_CHANGE;
|
956
|
+
case 0xF: return SYSTEM;
|
957
|
+
default: return ACTION_NONE;
|
958
|
+
}
|
959
|
+
}
|
960
|
+
|
961
|
+
int
|
962
|
+
MIDIEvent::channel () const
|
963
|
+
{
|
964
|
+
auto a = action();
|
965
|
+
if (a == ACTION_NONE || a == SYSTEM)
|
966
|
+
return -1;
|
967
|
+
|
968
|
+
return self->bytes[0] & 0xF;
|
969
|
+
}
|
970
|
+
|
971
|
+
uchar
|
972
|
+
MIDIEvent::data1 () const
|
973
|
+
{
|
974
|
+
return self->bytes[1];
|
975
|
+
}
|
976
|
+
|
977
|
+
uchar
|
978
|
+
MIDIEvent::data2 () const
|
979
|
+
{
|
980
|
+
return self->bytes[2];
|
981
|
+
}
|
982
|
+
|
983
|
+
bool
|
984
|
+
MIDIEvent::is_captured () const
|
985
|
+
{
|
986
|
+
return self->captured;
|
987
|
+
}
|
988
|
+
|
989
|
+
|
871
990
|
struct NoteEvent::Data
|
872
991
|
{
|
873
992
|
|
@@ -954,6 +1073,76 @@ namespace Reflex
|
|
954
1073
|
}
|
955
1074
|
|
956
1075
|
|
1076
|
+
struct ControlChangeEvent::Data
|
1077
|
+
{
|
1078
|
+
|
1079
|
+
int channel = 0;
|
1080
|
+
|
1081
|
+
int controller = 0;
|
1082
|
+
|
1083
|
+
float value = 0;
|
1084
|
+
|
1085
|
+
bool captured = false;
|
1086
|
+
|
1087
|
+
};// ControlChangeEvent::Data
|
1088
|
+
|
1089
|
+
|
1090
|
+
void
|
1091
|
+
ControlChangeEvent_set_captured (ControlChangeEvent* pthis, bool captured)
|
1092
|
+
{
|
1093
|
+
pthis->self->captured = captured;
|
1094
|
+
}
|
1095
|
+
|
1096
|
+
|
1097
|
+
ControlChangeEvent::ControlChangeEvent ()
|
1098
|
+
{
|
1099
|
+
}
|
1100
|
+
|
1101
|
+
ControlChangeEvent::ControlChangeEvent (
|
1102
|
+
int channel, int controller, float value, double time)
|
1103
|
+
: Event(time)
|
1104
|
+
{
|
1105
|
+
self->channel = channel;
|
1106
|
+
self->controller = controller;
|
1107
|
+
self->value = value;
|
1108
|
+
}
|
1109
|
+
|
1110
|
+
ControlChangeEvent::ControlChangeEvent (const ControlChangeEvent* src)
|
1111
|
+
: Event(src), self(new Data(*src->self))
|
1112
|
+
{
|
1113
|
+
}
|
1114
|
+
|
1115
|
+
ControlChangeEvent
|
1116
|
+
ControlChangeEvent::dup () const
|
1117
|
+
{
|
1118
|
+
return ControlChangeEvent(this);
|
1119
|
+
}
|
1120
|
+
|
1121
|
+
int
|
1122
|
+
ControlChangeEvent::channel () const
|
1123
|
+
{
|
1124
|
+
return self->channel;
|
1125
|
+
}
|
1126
|
+
|
1127
|
+
int
|
1128
|
+
ControlChangeEvent::controller () const
|
1129
|
+
{
|
1130
|
+
return self->controller;
|
1131
|
+
}
|
1132
|
+
|
1133
|
+
float
|
1134
|
+
ControlChangeEvent::value () const
|
1135
|
+
{
|
1136
|
+
return self->value;
|
1137
|
+
}
|
1138
|
+
|
1139
|
+
bool
|
1140
|
+
ControlChangeEvent::is_captured () const
|
1141
|
+
{
|
1142
|
+
return self->captured;
|
1143
|
+
}
|
1144
|
+
|
1145
|
+
|
957
1146
|
struct CaptureEvent::Data
|
958
1147
|
{
|
959
1148
|
|
data/src/event.h
CHANGED
@@ -49,9 +49,20 @@ namespace Reflex
|
|
49
49
|
void WheelEvent_set_position (WheelEvent* pthis, const Point& position);
|
50
50
|
|
51
51
|
|
52
|
+
bool MIDIEvent_to_note_event (NoteEvent* result, const MIDIEvent& event);
|
53
|
+
|
54
|
+
bool MIDIEvent_to_control_change_event (
|
55
|
+
ControlChangeEvent* result, const MIDIEvent& event);
|
56
|
+
|
57
|
+
void MIDIEvent_set_captured (MIDIEvent* pthis, bool captured);
|
58
|
+
|
59
|
+
|
52
60
|
void NoteEvent_set_captured (NoteEvent* pthis, bool captured);
|
53
61
|
|
54
62
|
|
63
|
+
void ControlChangeEvent_set_captured (ControlChangeEvent* pthis, bool captured);
|
64
|
+
|
65
|
+
|
55
66
|
}// Reflex
|
56
67
|
|
57
68
|
|
data/src/midi.cpp
CHANGED
@@ -33,33 +33,7 @@ namespace Reflex
|
|
33
33
|
};// MIDI::Data
|
34
34
|
|
35
35
|
|
36
|
-
|
37
|
-
call_note_event (
|
38
|
-
MIDI* midi, bool on,
|
39
|
-
int channel, int note, float velocity, double time)
|
40
|
-
{
|
41
|
-
NoteEvent e(
|
42
|
-
on ? NoteEvent::ON : NoteEvent::OFF,
|
43
|
-
channel, note, velocity, time);
|
44
|
-
|
45
|
-
midi->on_note(&e);
|
46
|
-
if (e.is_blocked()) return;
|
47
|
-
|
48
|
-
switch ((int) e.action())
|
49
|
-
{
|
50
|
-
case NoteEvent::ON: midi->on_note_on(&e); break;
|
51
|
-
case NoteEvent::OFF: midi->on_note_off(&e); break;
|
52
|
-
}
|
53
|
-
if (e.is_blocked()) return;
|
54
|
-
|
55
|
-
Window* win = Window_get_active();
|
56
|
-
if (!win) return;
|
57
|
-
|
58
|
-
Window_call_note_event(win, &e);
|
59
|
-
}
|
60
|
-
|
61
|
-
|
62
|
-
struct MIDIEvent
|
36
|
+
struct RtMidiEvent
|
63
37
|
{
|
64
38
|
|
65
39
|
typedef std::vector<unsigned char> Message;
|
@@ -76,60 +50,84 @@ namespace Reflex
|
|
76
50
|
|
77
51
|
double time = 0;
|
78
52
|
|
79
|
-
|
53
|
+
RtMidiEvent ()
|
80
54
|
: error("")
|
81
55
|
{
|
82
56
|
}
|
83
57
|
|
84
|
-
|
58
|
+
RtMidiEvent (MIDI* midi, const Message& message, double time)
|
85
59
|
: type(MESSAGE), midi(midi), message(message), error(""), time(time)
|
86
60
|
{
|
87
61
|
}
|
88
62
|
|
89
|
-
|
63
|
+
RtMidiEvent (MIDI* midi, const RtMidiError& error)
|
90
64
|
: type(ERROR), midi(midi), error(error)
|
91
65
|
{
|
92
66
|
}
|
93
67
|
|
94
|
-
};//
|
68
|
+
};// RtMidiEvent
|
69
|
+
|
70
|
+
|
71
|
+
static void
|
72
|
+
call_midi_note_event (MIDI* midi, NoteEvent* event)
|
73
|
+
{
|
74
|
+
midi->on_note(event);
|
75
|
+
if (event->is_blocked())
|
76
|
+
return;
|
77
|
+
|
78
|
+
switch ((int) event->action())
|
79
|
+
{
|
80
|
+
case NoteEvent::ON: midi->on_note_on(event); break;
|
81
|
+
case NoteEvent::OFF: midi->on_note_off(event); break;
|
82
|
+
}
|
83
|
+
}
|
95
84
|
|
85
|
+
static void
|
86
|
+
call_midi_event (MIDI* midi, const MIDIEvent& event)
|
87
|
+
{
|
88
|
+
NoteEvent note_e;
|
89
|
+
if (MIDIEvent_to_note_event(¬e_e, event))
|
90
|
+
call_midi_note_event(midi, ¬e_e);
|
96
91
|
|
97
|
-
|
92
|
+
ControlChangeEvent cc_e;
|
93
|
+
if (MIDIEvent_to_control_change_event(&cc_e, event))
|
94
|
+
midi->on_control_change(&cc_e);
|
95
|
+
}
|
98
96
|
|
99
97
|
static void
|
100
|
-
|
98
|
+
call_events (MIDI* midi, const uchar* bytes, double time)
|
99
|
+
{
|
100
|
+
MIDIEvent event(midi, bytes, time);
|
101
|
+
|
102
|
+
midi->on_midi(&event);
|
103
|
+
if (event.is_blocked()) return;
|
104
|
+
|
105
|
+
call_midi_event(midi, event);
|
106
|
+
|
107
|
+
Window* win = Window_get_active();
|
108
|
+
if (!win) return;
|
109
|
+
|
110
|
+
Window_call_midi_event(win, &event);
|
111
|
+
}
|
112
|
+
|
113
|
+
static Queue<RtMidiEvent> queue;
|
114
|
+
|
115
|
+
static void
|
116
|
+
dispatch_midi_event (RtMidiEvent* event)
|
101
117
|
{
|
102
118
|
switch (event->type)
|
103
119
|
{
|
104
|
-
case
|
105
|
-
|
106
|
-
auto& bytes = event->message;
|
107
|
-
switch (bytes[0] >> 4)
|
108
|
-
{
|
109
|
-
case 0x9:
|
110
|
-
call_note_event(
|
111
|
-
event->midi, true,
|
112
|
-
bytes[0] & 0xf, bytes[1], bytes[2] / 127.f, event->time);
|
113
|
-
break;
|
114
|
-
|
115
|
-
case 0x8:
|
116
|
-
call_note_event(
|
117
|
-
event->midi, false,
|
118
|
-
bytes[0] & 0xf, bytes[1], bytes[2] / 127.f, event->time);
|
119
|
-
break;
|
120
|
-
}
|
120
|
+
case RtMidiEvent::MESSAGE:
|
121
|
+
call_events(event->midi, &event->message[0], event->time);
|
121
122
|
break;
|
122
|
-
}
|
123
123
|
|
124
|
-
case
|
125
|
-
{
|
124
|
+
case RtMidiEvent::ERROR:
|
126
125
|
system_error(
|
127
126
|
__FILE__, __LINE__,
|
128
127
|
Xot::stringf("MIDI: %s", event->error.what()).c_str());
|
129
128
|
break;
|
130
|
-
}
|
131
129
|
|
132
|
-
case
|
130
|
+
case RtMidiEvent::UNKNOWN:
|
133
131
|
invalid_state_error(__FILE__, __LINE__);
|
134
132
|
}
|
135
133
|
}
|
@@ -137,13 +135,13 @@ namespace Reflex
|
|
137
135
|
static void
|
138
136
|
process_midi_events ()
|
139
137
|
{
|
140
|
-
|
138
|
+
RtMidiEvent event;
|
141
139
|
while (queue.try_pop(&event))
|
142
140
|
dispatch_midi_event(&event);
|
143
141
|
}
|
144
142
|
|
145
143
|
static void
|
146
|
-
event_callback (double dt,
|
144
|
+
event_callback (double dt, RtMidiEvent::Message* message, void* data)
|
147
145
|
{
|
148
146
|
MIDI* midi = (MIDI*) data;
|
149
147
|
MIDI::Data* self = midi->self.get();
|
@@ -153,7 +151,7 @@ namespace Reflex
|
|
153
151
|
else
|
154
152
|
self->time += dt;
|
155
153
|
|
156
|
-
queue.push(
|
154
|
+
queue.push(RtMidiEvent(midi, *message, self->time));
|
157
155
|
}
|
158
156
|
|
159
157
|
static void
|
@@ -161,7 +159,7 @@ namespace Reflex
|
|
161
159
|
{
|
162
160
|
MIDI* midi = (MIDI*) data;
|
163
161
|
|
164
|
-
queue.push(
|
162
|
+
queue.push(RtMidiEvent(midi, RtMidiError(message, type)));
|
165
163
|
}
|
166
164
|
|
167
165
|
static MIDI_CreateFun midi_create_fun = NULL;
|
@@ -349,6 +347,11 @@ namespace Reflex
|
|
349
347
|
return self->name;
|
350
348
|
}
|
351
349
|
|
350
|
+
void
|
351
|
+
MIDI::on_midi (MIDIEvent* e)
|
352
|
+
{
|
353
|
+
}
|
354
|
+
|
352
355
|
void
|
353
356
|
MIDI::on_note (NoteEvent* e)
|
354
357
|
{
|
@@ -364,6 +367,11 @@ namespace Reflex
|
|
364
367
|
{
|
365
368
|
}
|
366
369
|
|
370
|
+
void
|
371
|
+
MIDI::on_control_change (ControlChangeEvent* e)
|
372
|
+
{
|
373
|
+
}
|
374
|
+
|
367
375
|
MIDI::operator bool () const
|
368
376
|
{
|
369
377
|
return self->input.isPortOpen();
|
data/src/view.cpp
CHANGED
@@ -1508,6 +1508,20 @@ namespace Reflex
|
|
1508
1508
|
view->on_wheel(&e);
|
1509
1509
|
}
|
1510
1510
|
|
1511
|
+
void
|
1512
|
+
View_call_midi_event (View* view, MIDIEvent* event)
|
1513
|
+
{
|
1514
|
+
if (!view)
|
1515
|
+
argument_error(__FILE__, __LINE__);
|
1516
|
+
if (!event)
|
1517
|
+
argument_error(__FILE__, __LINE__);
|
1518
|
+
|
1519
|
+
if (view->hidden()) return;
|
1520
|
+
|
1521
|
+
MIDIEvent e = event->dup();
|
1522
|
+
view->on_midi(&e);
|
1523
|
+
}
|
1524
|
+
|
1511
1525
|
void
|
1512
1526
|
View_call_note_event (View* view, NoteEvent* event)
|
1513
1527
|
{
|
@@ -1530,6 +1544,20 @@ namespace Reflex
|
|
1530
1544
|
}
|
1531
1545
|
}
|
1532
1546
|
|
1547
|
+
void
|
1548
|
+
View_call_control_change_event (View* view, ControlChangeEvent* event)
|
1549
|
+
{
|
1550
|
+
if (!view)
|
1551
|
+
argument_error(__FILE__, __LINE__);
|
1552
|
+
if (!event)
|
1553
|
+
argument_error(__FILE__, __LINE__);
|
1554
|
+
|
1555
|
+
if (view->hidden()) return;
|
1556
|
+
|
1557
|
+
ControlChangeEvent e = event->dup();
|
1558
|
+
view->on_control_change(&e);
|
1559
|
+
}
|
1560
|
+
|
1533
1561
|
void
|
1534
1562
|
View_call_contact_event (View* view, ContactEvent* event)
|
1535
1563
|
{
|
@@ -2805,6 +2833,11 @@ namespace Reflex
|
|
2805
2833
|
//scroll_by(e->dx, e->dy, e->dz);
|
2806
2834
|
}
|
2807
2835
|
|
2836
|
+
void
|
2837
|
+
View::on_midi (MIDIEvent* e)
|
2838
|
+
{
|
2839
|
+
}
|
2840
|
+
|
2808
2841
|
void
|
2809
2842
|
View::on_note (NoteEvent* e)
|
2810
2843
|
{
|
@@ -2820,6 +2853,11 @@ namespace Reflex
|
|
2820
2853
|
{
|
2821
2854
|
}
|
2822
2855
|
|
2856
|
+
void
|
2857
|
+
View::on_control_change (ControlChangeEvent* e)
|
2858
|
+
{
|
2859
|
+
}
|
2860
|
+
|
2823
2861
|
void
|
2824
2862
|
View::on_capture (CaptureEvent* e)
|
2825
2863
|
{
|
data/src/view.h
CHANGED
@@ -36,15 +36,19 @@ namespace Reflex
|
|
36
36
|
|
37
37
|
void View_update_shapes (View* view);
|
38
38
|
|
39
|
-
void View_call_key_event
|
39
|
+
void View_call_key_event (View* view, KeyEvent* event);
|
40
40
|
|
41
|
-
void View_call_pointer_event
|
41
|
+
void View_call_pointer_event (View* view, PointerEvent* event);
|
42
42
|
|
43
|
-
void View_call_wheel_event
|
43
|
+
void View_call_wheel_event (View* view, WheelEvent* event);
|
44
44
|
|
45
|
-
void
|
45
|
+
void View_call_midi_event (View* view, MIDIEvent* event);
|
46
46
|
|
47
|
-
void
|
47
|
+
void View_call_note_event (View* view, NoteEvent* event);
|
48
|
+
|
49
|
+
void View_call_control_change_event (View* view, ControlChangeEvent* event);
|
50
|
+
|
51
|
+
void View_call_contact_event (View* view, ContactEvent* event);
|
48
52
|
|
49
53
|
|
50
54
|
}// Reflex
|
data/src/window.cpp
CHANGED
@@ -262,8 +262,6 @@ namespace Reflex
|
|
262
262
|
KeyEvent e = event->dup();
|
263
263
|
KeyEvent_set_captured(&e, true);
|
264
264
|
View_call_key_event(const_cast<View*>(view.get()), &e);
|
265
|
-
|
266
|
-
if (e.is_blocked()) event->block();
|
267
265
|
}
|
268
266
|
|
269
267
|
if (!event->is_blocked())
|
@@ -607,7 +605,7 @@ namespace Reflex
|
|
607
605
|
View_call_wheel_event(window->root(), event);
|
608
606
|
}
|
609
607
|
|
610
|
-
void
|
608
|
+
static void
|
611
609
|
Window_call_note_event (Window* window, NoteEvent* event)
|
612
610
|
{
|
613
611
|
assert(window);
|
@@ -619,7 +617,7 @@ namespace Reflex
|
|
619
617
|
{
|
620
618
|
if (
|
621
619
|
!view->window() ||
|
622
|
-
!is_capturing(view.get(), targets, View::
|
620
|
+
!is_capturing(view.get(), targets, View::CAPTURE_MIDI))
|
623
621
|
{
|
624
622
|
continue;
|
625
623
|
}
|
@@ -627,8 +625,6 @@ namespace Reflex
|
|
627
625
|
NoteEvent e = event->dup();
|
628
626
|
NoteEvent_set_captured(&e, true);
|
629
627
|
View_call_note_event(const_cast<View*>(view.get()), &e);
|
630
|
-
|
631
|
-
if (e.is_blocked()) event->block();
|
632
628
|
}
|
633
629
|
|
634
630
|
if (!event->is_blocked())
|
@@ -646,6 +642,75 @@ namespace Reflex
|
|
646
642
|
|
647
643
|
if (!event->is_blocked() && window->self->focus)
|
648
644
|
View_call_note_event(window->self->focus.get(), event);
|
645
|
+
}
|
646
|
+
|
647
|
+
static void
|
648
|
+
Window_call_control_change_event (Window* window, ControlChangeEvent* event)
|
649
|
+
{
|
650
|
+
assert(window);
|
651
|
+
|
652
|
+
if (!event)
|
653
|
+
argument_error(__FILE__, __LINE__);
|
654
|
+
|
655
|
+
for (auto& [view, targets] : window->self->captures)
|
656
|
+
{
|
657
|
+
if (
|
658
|
+
!view->window() ||
|
659
|
+
!is_capturing(view.get(), targets, View::CAPTURE_MIDI))
|
660
|
+
{
|
661
|
+
continue;
|
662
|
+
}
|
663
|
+
|
664
|
+
ControlChangeEvent e = event->dup();
|
665
|
+
ControlChangeEvent_set_captured(&e, true);
|
666
|
+
View_call_control_change_event(const_cast<View*>(view.get()), &e);
|
667
|
+
}
|
668
|
+
|
669
|
+
if (!event->is_blocked())
|
670
|
+
window->on_control_change(event);
|
671
|
+
|
672
|
+
if (!event->is_blocked() && window->self->focus)
|
673
|
+
View_call_control_change_event(window->self->focus.get(), event);
|
674
|
+
}
|
675
|
+
|
676
|
+
void
|
677
|
+
Window_call_midi_event (Window* window, MIDIEvent* event)
|
678
|
+
{
|
679
|
+
if (!window) return;
|
680
|
+
|
681
|
+
if (!event)
|
682
|
+
argument_error(__FILE__, __LINE__);
|
683
|
+
|
684
|
+
for (auto& [view, targets] : window->self->captures)
|
685
|
+
{
|
686
|
+
if (
|
687
|
+
!view->window() ||
|
688
|
+
!is_capturing(view.get(), targets, View::CAPTURE_MIDI))
|
689
|
+
{
|
690
|
+
continue;
|
691
|
+
}
|
692
|
+
|
693
|
+
MIDIEvent e = event->dup();
|
694
|
+
MIDIEvent_set_captured(&e, true);
|
695
|
+
View_call_midi_event(const_cast<View*>(view.get()), &e);
|
696
|
+
}
|
697
|
+
|
698
|
+
if (!event->is_blocked())
|
699
|
+
window->on_midi(event);
|
700
|
+
|
701
|
+
if (!event->is_blocked() && window->self->focus)
|
702
|
+
View_call_midi_event(window->self->focus.get(), event);
|
703
|
+
|
704
|
+
if (!event->is_blocked())
|
705
|
+
{
|
706
|
+
NoteEvent note_e;
|
707
|
+
if (MIDIEvent_to_note_event(¬e_e, *event))
|
708
|
+
Window_call_note_event(window, ¬e_e);
|
709
|
+
|
710
|
+
ControlChangeEvent cc_e;
|
711
|
+
if (MIDIEvent_to_control_change_event(&cc_e, *event))
|
712
|
+
Window_call_control_change_event(window, &cc_e);
|
713
|
+
}
|
649
714
|
|
650
715
|
cleanup_captures(window);
|
651
716
|
}
|
@@ -941,6 +1006,11 @@ namespace Reflex
|
|
941
1006
|
{
|
942
1007
|
}
|
943
1008
|
|
1009
|
+
void
|
1010
|
+
Window::on_midi (MIDIEvent* e)
|
1011
|
+
{
|
1012
|
+
}
|
1013
|
+
|
944
1014
|
void
|
945
1015
|
Window::on_note (NoteEvent* e)
|
946
1016
|
{
|
@@ -956,6 +1026,11 @@ namespace Reflex
|
|
956
1026
|
{
|
957
1027
|
}
|
958
1028
|
|
1029
|
+
void
|
1030
|
+
Window::on_control_change (ControlChangeEvent* e)
|
1031
|
+
{
|
1032
|
+
}
|
1033
|
+
|
959
1034
|
Window::operator bool () const
|
960
1035
|
{
|
961
1036
|
return self && *self;
|
data/src/window.h
CHANGED
@@ -139,7 +139,7 @@ namespace Reflex
|
|
139
139
|
|
140
140
|
void Window_call_wheel_event (Window* window, WheelEvent* event);
|
141
141
|
|
142
|
-
void
|
142
|
+
void Window_call_midi_event (Window* window, MIDIEvent* event);
|
143
143
|
|
144
144
|
|
145
145
|
typedef View* (*Window_CreateRootViewFun) ();
|
data/test/test_capture_event.rb
CHANGED
@@ -26,34 +26,34 @@ class TestCaptureEvent < Test::Unit::TestCase
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def test_begin()
|
29
|
-
c = event [:key, :pointer, :
|
30
|
-
assert_equal [:key, :pointer, :
|
29
|
+
c = event [:key, :pointer, :midi], []
|
30
|
+
assert_equal [:key, :pointer, :midi], c.begin
|
31
31
|
assert_equal true, c.begin?(:key)
|
32
32
|
assert_equal true, c.begin?(:pointer)
|
33
|
-
assert_equal true, c.begin?(:
|
33
|
+
assert_equal true, c.begin?(:midi)
|
34
34
|
assert_equal true, c.begin?(:all)
|
35
35
|
|
36
36
|
c = event [:key], []
|
37
37
|
assert_equal [:key], c.begin
|
38
38
|
assert_equal true, c.begin?(:key)
|
39
39
|
assert_equal false, c.begin?(:pointer)
|
40
|
-
assert_equal false, c.begin?(:
|
40
|
+
assert_equal false, c.begin?(:midi)
|
41
41
|
assert_equal false, c.begin?(:all)
|
42
42
|
end
|
43
43
|
|
44
44
|
def test_end()
|
45
|
-
c = event [], [:key, :pointer, :
|
46
|
-
assert_equal [:key, :pointer, :
|
45
|
+
c = event [], [:key, :pointer, :midi]
|
46
|
+
assert_equal [:key, :pointer, :midi], c.end
|
47
47
|
assert_equal true, c.end?(:key)
|
48
48
|
assert_equal true, c.end?(:pointer)
|
49
|
-
assert_equal true, c.end?(:
|
49
|
+
assert_equal true, c.end?(:midi)
|
50
50
|
assert_equal true, c.end?(:all)
|
51
51
|
|
52
52
|
c = event [], [:key]
|
53
53
|
assert_equal [:key], c.end
|
54
54
|
assert_equal true, c.end?(:key)
|
55
55
|
assert_equal false, c.end?(:pointer)
|
56
|
-
assert_equal false, c.end?(:
|
56
|
+
assert_equal false, c.end?(:midi)
|
57
57
|
assert_equal false, c.end?(:all)
|
58
58
|
end
|
59
59
|
|