-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathExample.cpp
More file actions
186 lines (162 loc) · 8.16 KB
/
Copy pathExample.cpp
File metadata and controls
186 lines (162 loc) · 8.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include "Example.h"
#include "UI/UI.h" // Include the UI Framework
// Run once
void ExampleAPP::Setup(const vector<string>& args) {
MLOGI("Example", "Example Started");
}
// Run in a loop after Setup()
void ExampleAPP::Loop() {
// Set up key event handler
InputEvent inputEvent;
while (MatrixOS::Input::Get(&inputEvent))
{
if (inputEvent.inputClass != InputClass::Keypad) continue;
InputEventHandler(inputEvent);
} // Handle them
struct MidiPacket midiPacket; // Variable for the latest midi packet to be stored at
while (MatrixOS::MIDI::Get(&midiPacket)) // While there is still midi packet in the queue
{
MidiEventHandler(midiPacket);
} // Handle them
}
// Handle the key event from the OS
void ExampleAPP::InputEventHandler(InputEvent& inputEvent) {
Point xy; MatrixOS::Input::GetPosition(inputEvent.id, &xy); // Trying to get the XY coordination of the KeyID
if (xy) // IF XY is valid, means it is a key on the grid
{
MLOGD("Example", "Key %d %d %d", xy.x, xy.y, (uint8_t)inputEvent.keypad.state); // Print the key event to the debug log
if (inputEvent.keypad.state == KeypadState::Pressed) // Key is pressed
{
MatrixOS::LED::SetColor(xy, color, 0); // Set the LED color to a color. Last 0 means writes to the active layer (255 writes to the
// active layer as well but do not trigger auto update.)
}
else if (inputEvent.keypad.state == KeypadState::Released)
{
MatrixOS::LED::SetColor(xy, 0x000000, 0); // Set the LED to off
}
}
else // XY Not valid,
{
if (inputEvent.id == InputId::FunctionKey())
{
UIMenu(); // Open UI Menu
}
}
}
void ExampleAPP::MidiEventHandler(MidiPacket& midiPacket) {
// Echo back the midi packet to the source
MatrixOS::MIDI::Send(midiPacket);
// Midi Packet has port, status, and data
// Port shows where this midi signal is from (USB, Bluetooth, RTPMIDI, HWPort, etc)
// When sending midi packets. This is also where the midi signal will be sent to
// See EMidiStatus enum in /OS/Framework/Midi/MidiPacket.h for all the midi status
// 0x0 sends to all first of available ports
// Status is the midi status (NoteOn, NoteOff, ControlChange, etc)
// See EMidiStatus enum in /OS/Framework/Midi/MidiPacket.h for all the midi status
// Wanna do more with the packet? Here's a example parser
/*
switch (midiPacket.status)
{
case NoteOn:
case ControlChange:
NoteHandler(midiPacket.channel(), midiPacket.note(), midiPacket.velocity());
break;
case NoteOff:
NoteHandler(midiPacket.channel(), midiPacket.note(), 0);
break;
case SysExData:
case SysExEnd:
SysExHandler(midiPacket);
break;
default:
break;
}
*/
}
void ExampleAPP::UIMenu() {
// Matrix OS Debug Log, sent to hardware UART and USB CDC
MLOGI("Example", "Enter UI Menu");
// Create a UI Object
// UI Name, Color (as the text scroll color). and new led layer (Set as true, the UI will render on a new led layer. Persevere what was
// rendered before after UI exits)
UI menu("UI Menu", Color(0x00FFFF), true);
// Create an UI element
UIButton numberSelector;
numberSelector.SetName("Number Selector"); // Name of this UI element
numberSelector.SetColor(Color(0xFF0000)); // Color of the UI element
numberSelector.OnPress([&]() -> void { // Callback function when the button is pressed
number = MatrixOS::UIUtility::NumberSelector8x8(number, 0xFF0000, "Number", 0, 100); // Current Number, color, low range, high range
// EXAMPLEAPP_SAVED_VAR does not affect this code
// For most value types, the saved variable wrapper library requires no changes to code!
});
// Add the UI element to the UI object to top left conner
menu.AddUIComponent(numberSelector, Point(0, 0));
// Create an dynamic colored button
UIButton colorSelector;
colorSelector.SetName("Color Selector"); // Name of this UI element
colorSelector.SetColorFunc([&]() -> Color { return color; }); // Use the color variable as the color of this UI element
colorSelector.OnPress([&]() -> void { // Callback function when the button is pressed
#ifndef EXAMPLEAPP_SAVED_VAR
MatrixOS::UIUtility::ColorPicker(color); // References to the color variable. The color variable will be updated by the ColorPicker
// function. Return true if color is changed, false if not.
#else
MatrixOS::UIUtility::ColorPicker(color.value); // Get the actual value from the saved variable wrapper library
color.Set(color.value); // Save the new variable
// The saved variable wrapper doesn't implicitly convert to the references type.
// This way you know you have to get the references manually and set the value back to the saved variable manually.
#endif
});
colorSelector.OnHold([&]() -> void { // Optional Callback function for hold down. Reset color to default white.
color = 0xFFFFFF;
});
// Add the UI element to the UI object to top right conner
menu.AddUIComponent(colorSelector, Point(MatrixOS::Input::GetPrimaryGridCluster()->dimension.x - 1, 0));
// A large button that cycles though the brightness of the device
UIButton brightnessBtn;
brightnessBtn.SetName("Brightness"); // Name
brightnessBtn.SetColor(Color::White); // Color
brightnessBtn.SetSize(Dimension(2, 2)); // Size of the button
brightnessBtn.OnPress([&]() -> void { MatrixOS::LED::NextBrightness(); }); // Function to call when the button is pressed
brightnessBtn.OnHold([&]() -> void { BrightnessControl().Start(); }); // Function to call when the button is hold down
// Place this button in the center of the device
menu.AddUIComponent(brightnessBtn, Point((MatrixOS::Input::GetPrimaryGridCluster()->dimension.x - 1) / 2, (MatrixOS::Input::GetPrimaryGridCluster()->dimension.y - 1) / 2));
// Set a key event handler for the UI object
// By default, the UI exits after the function key is PRESSED.
// Since this is the main UI for this application.
// We want to exit the application when the function key is hold down,
// and exit the UI is released (but before the hold down time threshold)
// First, disable the default exit behavior
menu.AllowExit(false);
// Second, set the key event handler to match the intended behavior
menu.SetInputEventHandler([&](InputEvent* inputEvent) -> bool {
// If function key is hold down. Exit the application
if (inputEvent->id == InputId::FunctionKey())
{
if (inputEvent->keypad.state == KeypadState::Hold)
{
Exit(); // Exit the application.
return true; // Block UI from to do anything with FN, basically this function control the life cycle of the UI. This is not really
// needed as the application exits after Exit();
}
else if (inputEvent->keypad.state == KeypadState::Released)
{
menu.Exit(); // Exit the UI
return true; // Block UI from to do anything with FN, basically this function control the life cycle of the UI
}
}
return false; // Nothing happened. Let the UI handle the key event
});
// The UI object is now fully set up. Let the UI runtime to start and take over.
menu.Start();
// Once the UI is exited (Not the application exit!), the code will continue here.
// If Exit() is called in UI. The code will start in the End() of this application and then exit.
// See /OS/UI/UI.h for more UI Framework API
// See /OS/UI/UIComponents.h for more UI Components
// See /OS/UI/UIUtilities.h for more UI built in UI Interface
// You can also create your own UI Components and UI Interfaces for your own application.
// You can see the Note application for an example of how to do that. (Note Pad. Octave Shifter. Scales, ScaleVisualizer...)
MLOGI("Example", "Exited UI Menu");
}
void ExampleAPP::End() {
MLOGI("Example", "Example Exited");
}