@@ -10,14 +10,24 @@ | |||
#include <nanosvg.h> | |||
/** Remaps Ctrl to Cmd on Mac | |||
Use this instead of GLFW_MOD_CONTROL, since Cmd should be used on Mac in place of Ctrl on Linux/Windows. | |||
*/ | |||
#ifdef ARCH_MAC | |||
#define WINDOW_MOD GLFW_MOD_SUPER | |||
#define WINDOW_MOD_KEY_NAME "Cmd" | |||
#define WINDOW_MOD_CTRL GLFW_MOD_SUPER | |||
#define WINDOW_MOD_CTRL_NAME "Cmd" | |||
#else | |||
#define WINDOW_MOD GLFW_MOD_CONTROL | |||
#define WINDOW_MOD_KEY_NAME "Ctrl" | |||
#define WINDOW_MOD_CTRL GLFW_MOD_CONTROL | |||
#define WINDOW_MOD_CTRL_NAME "Ctrl" | |||
#endif | |||
/** Filters actual mod keys from the mod flags. | |||
Use this if you don't care about GLFW_MOD_CAPS_LOCK and GLFW_MOD_NUM_LOCK. | |||
Example usage: | |||
if ((e.mod & WINDOW_MOD_MASK) == (WINDOW_MOD | GLFW_MOD_SHIFT)) ... | |||
*/ | |||
#define WINDOW_MOD_MASK (GLFW_MOD_SHIFT | GLFW_MOD_CONTROL | GLFW_MOD_ALT | GLFW_MOD_SUPER) | |||
namespace rack { | |||
@@ -70,8 +80,10 @@ struct Window { | |||
void close(); | |||
void cursorLock(); | |||
void cursorUnlock(); | |||
bool isModPressed(); | |||
bool isShiftPressed(); | |||
/** Gets the current keyboard mod state | |||
Don't call this from a Key event. Simply use `e.mods` instead. | |||
*/ | |||
int getMods(); | |||
math::Vec getWindowSize(); | |||
void setWindowSize(math::Vec size); | |||
math::Vec getWindowPos(); | |||
@@ -0,0 +1,249 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<!-- Created with Inkscape (http://www.inkscape.org/) --> | |||
<svg | |||
xmlns:dc="http://purl.org/dc/elements/1.1/" | |||
xmlns:cc="http://creativecommons.org/ns#" | |||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |||
xmlns:svg="http://www.w3.org/2000/svg" | |||
xmlns="http://www.w3.org/2000/svg" | |||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |||
width="50.799999mm" | |||
height="128.50069mm" | |||
viewBox="0 0 50.799999 128.50069" | |||
version="1.1" | |||
id="svg26618" | |||
inkscape:version="0.92.2 2405546, 2018-03-11" | |||
sodipodi:docname="CV-CC.svg"> | |||
<defs | |||
id="defs26612" /> | |||
<sodipodi:namedview | |||
id="base" | |||
pagecolor="#ffffff" | |||
bordercolor="#666666" | |||
borderopacity="1.0" | |||
inkscape:pageopacity="0.0" | |||
inkscape:pageshadow="2" | |||
inkscape:zoom="1.979899" | |||
inkscape:cx="85.567542" | |||
inkscape:cy="333.70852" | |||
inkscape:document-units="mm" | |||
inkscape:current-layer="layer2" | |||
showgrid="false" | |||
fit-margin-top="0" | |||
fit-margin-left="0" | |||
fit-margin-right="0" | |||
fit-margin-bottom="0" | |||
inkscape:snap-bbox="true" | |||
inkscape:snap-nodes="false" | |||
inkscape:snap-bbox-midpoints="true" | |||
inkscape:bbox-nodes="true" | |||
inkscape:window-width="1600" | |||
inkscape:window-height="882" | |||
inkscape:window-x="0" | |||
inkscape:window-y="18" | |||
inkscape:window-maximized="0" /> | |||
<metadata | |||
id="metadata26615"> | |||
<rdf:RDF> | |||
<cc:Work | |||
rdf:about=""> | |||
<dc:format>image/svg+xml</dc:format> | |||
<dc:type | |||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |||
<dc:title></dc:title> | |||
</cc:Work> | |||
</rdf:RDF> | |||
</metadata> | |||
<g | |||
inkscape:label="Layer 1" | |||
inkscape:groupmode="layer" | |||
id="layer1" | |||
transform="translate(-362.22837,-118.49952)"> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path9519" | |||
d="m 362.32207,118.59323 h 50.61256 V 246.9065 h -50.61256 z m 0,0" | |||
style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path9521" | |||
d="m 413.02837,118.49952 h -50.8 V 247.0002 h 50.8 z m -0.18743,128.31327 H 362.41439 V 118.68694 h 50.42655 z m 0,0" | |||
style="fill:#ababab;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path9555" | |||
d="m 370.22785,195.95078 h 34.79962" | |||
style="fill:none;stroke:#000000;stroke-width:0.35277775;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path9557" | |||
d="m 370.22785,207.55111 h 34.79962" | |||
style="fill:none;stroke:#000000;stroke-width:0.35277775;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path9559" | |||
d="m 370.22785,219.15143 h 34.79962" | |||
style="fill:none;stroke:#000000;stroke-width:0.35277775;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path9561" | |||
d="m 370.22785,230.75037 h 34.79962" | |||
style="fill:none;stroke:#000000;stroke-width:0.35277775;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path12881" | |||
d="m 384.87504,242.85644 c -0.11715,0 -0.22323,-0.0661 -0.27562,-0.1695 l -1.00182,-2.00504 c -0.0772,-0.15296 -0.0152,-0.33762 0.13779,-0.41479 0.15159,-0.0758 0.33761,-0.0138 0.41342,0.13918 l 0.72623,1.45245 0.72623,-1.45245 c 0.0758,-0.15296 0.26183,-0.21497 0.41339,-0.13918 0.15296,0.0772 0.21498,0.26183 0.13783,0.41479 l -1.00186,2.00504 c -0.0523,0.10336 -0.15846,0.1695 -0.27559,0.1695" | |||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path12883" | |||
d="m 390.38028,242.85644 c -0.11575,0 -0.22324,-0.0661 -0.27559,-0.1695 l -1.00182,-2.00504 c -0.0772,-0.15296 -0.0152,-0.33762 0.1378,-0.41479 0.15159,-0.0758 0.33761,-0.0138 0.41342,0.13918 l 0.72619,1.45245 0.72761,-1.45245 c 0.0758,-0.15296 0.26045,-0.21497 0.41341,-0.13918 0.1516,0.0772 0.21361,0.26183 0.1378,0.41479 l -1.00319,2.00504 c -0.051,0.10336 -0.15847,0.1695 -0.27563,0.1695" | |||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path12885" | |||
d="m 387.77717,242.85644 c -0.72207,0 -1.3105,-0.58705 -1.3105,-1.31051 0,-0.72209 0.58843,-1.31052 1.3105,-1.31052 0.28663,0 0.55813,0.091 0.78687,0.26183 0.13642,0.10197 0.16401,0.29628 0.062,0.4327 -0.10336,0.13505 -0.2963,0.16261 -0.43272,0.0606 -0.11987,-0.091 -0.26458,-0.13919 -0.41617,-0.13919 -0.38308,0 -0.69314,0.31145 -0.69314,0.69454 0,0.38309 0.31006,0.69453 0.69314,0.69453 0.15159,0 0.2963,-0.0482 0.41617,-0.13918 0.13642,-0.10198 0.32936,-0.0744 0.43272,0.062 0.10199,0.13505 0.0744,0.32935 -0.062,0.43132 -0.22874,0.17088 -0.50024,0.26183 -0.78687,0.26183" | |||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path12887" | |||
d="m 388.19888,241.53077 c 0,0.22186 -0.18055,0.40101 -0.40104,0.40101 -0.22186,0 -0.401,-0.17915 -0.401,-0.40101 0,-0.22186 0.17914,-0.40101 0.401,-0.40101 0.22049,0 0.40104,0.17915 0.40104,0.40101" | |||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.35277775" | |||
d="m 382.2781,128.11472 c 0.47407,0 0.78825,-0.1378 1.05834,-0.36931 0.0551,-0.0551 0.11024,-0.13229 0.11024,-0.23703 0,-0.16536 -0.1433,-0.29765 -0.30868,-0.29765 -0.0771,0 -0.1433,0.0276 -0.19293,0.0717 -0.1874,0.14882 -0.36929,0.23151 -0.64492,0.23151 -0.50711,0 -0.85989,-0.42444 -0.85989,-0.93156 v -0.005 c 0,-0.50711 0.36382,-0.92604 0.85989,-0.92604 0.23153,0 0.42443,0.0772 0.60636,0.21497 0.0496,0.0276 0.1047,0.0606 0.1929,0.0606 0.18192,0 0.32522,-0.13781 0.32522,-0.3142 0,-0.11575 -0.0606,-0.20946 -0.12679,-0.25907 -0.24803,-0.1819 -0.54567,-0.30317 -0.99218,-0.30317 -0.9095,0 -1.54341,0.68903 -1.54341,1.53238 v 0.011 c 0,0.84887 0.64495,1.52135 1.51585,1.52135 z m 0,0" | |||
id="path24553" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.35277775" | |||
d="m 385.20172,128.10921 h 0.0441 c 0.17638,0 0.29763,-0.0937 0.36378,-0.25356 l 0.97014,-2.32062 c 0.0166,-0.0386 0.0332,-0.0937 0.0332,-0.14331 0,-0.1819 -0.14334,-0.31419 -0.31972,-0.31419 -0.15434,0 -0.27009,0.0992 -0.31419,0.20395 l -0.74965,1.94027 -0.73861,-1.91823 c -0.0496,-0.13229 -0.15988,-0.22599 -0.33073,-0.22599 -0.18193,0 -0.32523,0.1378 -0.32523,0.3197 0,0.0551 0.0166,0.10473 0.0386,0.15985 l 0.9591,2.29857 c 0.0661,0.15985 0.19293,0.25356 0.36932,0.25356 z m 0,0" | |||
id="path24545" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.35277775" | |||
d="m 387.17918,127.0619 h 0.7331 c 0.17089,0 0.31419,-0.1378 0.31419,-0.30868 0,-0.17088 -0.1433,-0.30868 -0.31419,-0.30868 h -0.7331 c -0.17089,0 -0.30868,0.1378 -0.30868,0.30868 0,0.17088 0.13779,0.30868 0.30868,0.30868 z m 0,0" | |||
id="path24549" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.35277775" | |||
d="m 390.30112,128.11472 c 0.47406,0 0.78824,-0.1378 1.05833,-0.36931 0.0551,-0.0551 0.11025,-0.13229 0.11025,-0.23703 0,-0.16536 -0.1433,-0.29765 -0.30869,-0.29765 -0.0771,0 -0.14329,0.0276 -0.19293,0.0717 -0.1874,0.14882 -0.36929,0.23151 -0.64491,0.23151 -0.50712,0 -0.8599,-0.42444 -0.8599,-0.93156 v -0.005 c 0,-0.50711 0.36382,-0.92604 0.8599,-0.92604 0.23152,0 0.42442,0.0772 0.60635,0.21497 0.0496,0.0276 0.10471,0.0606 0.1929,0.0606 0.18193,0 0.32522,-0.13781 0.32522,-0.3142 0,-0.11575 -0.0606,-0.20946 -0.12678,-0.25907 -0.24804,-0.1819 -0.54568,-0.30317 -0.99219,-0.30317 -0.9095,0 -1.5434,0.68902 -1.5434,1.53238 v 0.011 c 0,0.84887 0.64495,1.52135 1.51585,1.52135 z m 0,0" | |||
id="path24541" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.35277775" | |||
d="m 393.37282,128.11472 c 0.47407,0 0.78825,-0.1378 1.05834,-0.36931 0.0551,-0.0551 0.11024,-0.13229 0.11024,-0.23703 0,-0.16536 -0.1433,-0.29765 -0.30868,-0.29765 -0.0771,0 -0.1433,0.0276 -0.19293,0.0717 -0.1874,0.14882 -0.36929,0.23151 -0.64492,0.23151 -0.50711,0 -0.85989,-0.42444 -0.85989,-0.93156 v -0.005 c 0,-0.50711 0.36382,-0.92604 0.85989,-0.92604 0.23153,0 0.42443,0.0772 0.60636,0.21497 0.0496,0.0276 0.1047,0.0606 0.1929,0.0606 0.18192,0 0.32522,-0.13781 0.32522,-0.3142 0,-0.11575 -0.0606,-0.20946 -0.12679,-0.25907 -0.24803,-0.1819 -0.54567,-0.30317 -0.99218,-0.30317 -0.9095,0 -1.54341,0.68903 -1.54341,1.53238 v 0.011 c 0,0.84887 0.64495,1.52135 1.51585,1.52135 z m 0,0" | |||
id="path24537" /> | |||
</g> | |||
<g | |||
inkscape:groupmode="layer" | |||
id="layer2" | |||
inkscape:label="widgets" | |||
style="display:none"> | |||
<circle | |||
style="opacity:1;vector-effect:none;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" | |||
id="path27377" | |||
cx="7.9994998" | |||
cy="77.451263" | |||
r="2" /> | |||
<circle | |||
r="2" | |||
cy="77.451263" | |||
cx="19.599819" | |||
id="circle28184" | |||
style="opacity:1;vector-effect:none;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> | |||
<circle | |||
style="opacity:1;vector-effect:none;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" | |||
id="circle28186" | |||
cx="31.199474" | |||
cy="77.451263" | |||
r="2" /> | |||
<circle | |||
r="2" | |||
cy="77.451263" | |||
cx="42.799793" | |||
id="circle28188" | |||
style="opacity:1;vector-effect:none;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> | |||
<circle | |||
r="2" | |||
cy="89.050903" | |||
cx="7.9994998" | |||
id="circle28190" | |||
style="opacity:1;vector-effect:none;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> | |||
<circle | |||
style="opacity:1;vector-effect:none;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" | |||
id="circle28192" | |||
cx="19.599819" | |||
cy="89.050903" | |||
r="2" /> | |||
<circle | |||
r="2" | |||
cy="89.050903" | |||
cx="31.199474" | |||
id="circle28194" | |||
style="opacity:1;vector-effect:none;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> | |||
<circle | |||
style="opacity:1;vector-effect:none;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" | |||
id="circle28196" | |||
cx="42.799793" | |||
cy="89.050903" | |||
r="2" /> | |||
<circle | |||
style="opacity:1;vector-effect:none;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" | |||
id="circle28198" | |||
cx="7.9994998" | |||
cy="100.65122" | |||
r="2" /> | |||
<circle | |||
r="2" | |||
cy="100.65122" | |||
cx="19.599819" | |||
id="circle28200" | |||
style="opacity:1;vector-effect:none;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> | |||
<circle | |||
style="opacity:1;vector-effect:none;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" | |||
id="circle28202" | |||
cx="31.199474" | |||
cy="100.65122" | |||
r="2" /> | |||
<circle | |||
r="2" | |||
cy="100.65122" | |||
cx="42.799793" | |||
id="circle28204" | |||
style="opacity:1;vector-effect:none;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> | |||
<circle | |||
r="2" | |||
cy="112.25155" | |||
cx="7.9994998" | |||
id="circle28206" | |||
style="opacity:1;vector-effect:none;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> | |||
<circle | |||
style="opacity:1;vector-effect:none;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" | |||
id="circle28208" | |||
cx="19.599819" | |||
cy="112.25155" | |||
r="2" /> | |||
<circle | |||
r="2" | |||
cy="112.25155" | |||
cx="31.199474" | |||
id="circle28210" | |||
style="opacity:1;vector-effect:none;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> | |||
<circle | |||
style="opacity:1;vector-effect:none;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" | |||
id="circle28212" | |||
cx="42.799793" | |||
cy="112.25155" | |||
r="2" /> | |||
<rect | |||
style="opacity:1;vector-effect:none;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.87907022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" | |||
id="rect28214" | |||
width="44.00074" | |||
height="54.666771" | |||
x="3.39961" | |||
y="14.83872" /> | |||
</g> | |||
</svg> |
@@ -0,0 +1,146 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<!-- Created with Inkscape (http://www.inkscape.org/) --> | |||
<svg | |||
xmlns:dc="http://purl.org/dc/elements/1.1/" | |||
xmlns:cc="http://creativecommons.org/ns#" | |||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |||
xmlns:svg="http://www.w3.org/2000/svg" | |||
xmlns="http://www.w3.org/2000/svg" | |||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |||
width="50.799999mm" | |||
height="128.50069mm" | |||
viewBox="0 0 50.799999 128.50069" | |||
version="1.1" | |||
id="svg28661" | |||
inkscape:version="0.92.2 2405546, 2018-03-11" | |||
sodipodi:docname="CV-GATE.svg"> | |||
<defs | |||
id="defs28655" /> | |||
<sodipodi:namedview | |||
id="base" | |||
pagecolor="#ffffff" | |||
bordercolor="#666666" | |||
borderopacity="1.0" | |||
inkscape:pageopacity="0.0" | |||
inkscape:pageshadow="2" | |||
inkscape:zoom="1.4" | |||
inkscape:cx="299.51464" | |||
inkscape:cy="255.96778" | |||
inkscape:document-units="mm" | |||
inkscape:current-layer="layer1" | |||
showgrid="false" | |||
fit-margin-top="0" | |||
fit-margin-left="0" | |||
fit-margin-right="0" | |||
fit-margin-bottom="0" | |||
inkscape:window-width="1600" | |||
inkscape:window-height="882" | |||
inkscape:window-x="0" | |||
inkscape:window-y="18" | |||
inkscape:window-maximized="0" /> | |||
<metadata | |||
id="metadata28658"> | |||
<rdf:RDF> | |||
<cc:Work | |||
rdf:about=""> | |||
<dc:format>image/svg+xml</dc:format> | |||
<dc:type | |||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |||
<dc:title></dc:title> | |||
</cc:Work> | |||
</rdf:RDF> | |||
</metadata> | |||
<g | |||
inkscape:label="Layer 1" | |||
inkscape:groupmode="layer" | |||
id="layer1" | |||
transform="translate(-423.18863,-118.49952)"> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path9523" | |||
d="m 423.28099,118.59323 h 50.61394 V 246.9065 h -50.61394 z m 0,0" | |||
style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path9525" | |||
d="m 473.98863,118.49952 h -50.8 V 247.0002 h 50.8 z m -0.18739,128.31327 H 423.37469 V 118.68694 h 50.42655 z m 0,0" | |||
style="fill:#ababab;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path9547" | |||
d="m 431.13717,195.95078 h 34.79959" | |||
style="fill:none;stroke:#000000;stroke-width:0.35277775;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path9549" | |||
d="m 431.13717,207.55111 h 34.79959" | |||
style="fill:none;stroke:#000000;stroke-width:0.35277775;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path9551" | |||
d="m 431.13717,219.15143 h 34.79959" | |||
style="fill:none;stroke:#000000;stroke-width:0.35277775;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path9553" | |||
d="m 431.13717,230.75037 h 34.79959" | |||
style="fill:none;stroke:#000000;stroke-width:0.35277775;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path13127" | |||
d="m 445.83534,242.85644 c -0.11715,0 -0.22465,-0.0661 -0.27562,-0.1695 l -1.0032,-2.00504 c -0.0758,-0.15296 -0.0138,-0.33762 0.1378,-0.41479 0.15296,-0.0758 0.33761,-0.0138 0.41342,0.13918 l 0.7276,1.45245 0.72623,-1.45245 c 0.0758,-0.15296 0.2618,-0.21497 0.41339,-0.13918 0.15296,0.0772 0.21498,0.26183 0.13783,0.41479 l -1.00186,2.00504 c -0.0523,0.10336 -0.15984,0.1695 -0.27559,0.1695" | |||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path13129" | |||
d="m 451.34058,242.85644 c -0.11712,0 -0.22324,-0.0661 -0.27559,-0.1695 l -1.00185,-2.00504 c -0.0771,-0.15296 -0.0152,-0.33762 0.13783,-0.41479 0.15155,-0.0758 0.3376,-0.0138 0.41338,0.13918 l 0.72623,1.45245 0.72623,-1.45245 c 0.0758,-0.15296 0.26183,-0.21497 0.41342,-0.13918 0.15296,0.0772 0.21498,0.26183 0.13917,0.41479 l -1.00319,2.00504 c -0.051,0.10336 -0.15847,0.1695 -0.27563,0.1695" | |||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path13131" | |||
d="m 448.73747,242.85644 c -0.72348,0 -1.3105,-0.58705 -1.3105,-1.31051 0,-0.72209 0.58702,-1.31052 1.3105,-1.31052 0.28663,0 0.55813,0.091 0.78687,0.26183 0.13642,0.10197 0.16397,0.29628 0.0606,0.4327 -0.10199,0.13505 -0.29492,0.16261 -0.43134,0.0606 -0.11988,-0.091 -0.26459,-0.13919 -0.41617,-0.13919 -0.38309,0 -0.69452,0.31145 -0.69452,0.69454 0,0.38309 0.31143,0.69453 0.69452,0.69453 0.15158,0 0.29629,-0.0482 0.41617,-0.13918 0.13642,-0.10198 0.32935,-0.0744 0.43134,0.062 0.10333,0.13505 0.0758,0.32935 -0.0606,0.43132 -0.22874,0.17088 -0.50024,0.26183 -0.78687,0.26183" | |||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path13133" | |||
d="m 449.15914,241.53077 c 0,0.22186 -0.18051,0.40101 -0.40237,0.40101 -0.22049,0 -0.39963,-0.17915 -0.39963,-0.40101 0,-0.22186 0.17914,-0.40101 0.39963,-0.40101 0.22186,0 0.40237,0.17915 0.40237,0.40101" | |||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.35277775" | |||
d="m 440.45065,128.11472 c 0.47406,0 0.78825,-0.1378 1.05833,-0.36931 0.0551,-0.0551 0.11024,-0.13229 0.11024,-0.23703 0,-0.16536 -0.14329,-0.29765 -0.30868,-0.29765 -0.0772,0 -0.14329,0.0276 -0.19293,0.0717 -0.1874,0.14882 -0.36929,0.23151 -0.64491,0.23151 -0.50712,0 -0.8599,-0.42444 -0.8599,-0.93156 v -0.005 c 0,-0.50711 0.36382,-0.92604 0.8599,-0.92604 0.23153,0 0.42442,0.0772 0.60635,0.21497 0.0496,0.0276 0.10471,0.0606 0.1929,0.0606 0.18193,0 0.32523,-0.13781 0.32523,-0.3142 0,-0.11575 -0.0606,-0.20946 -0.12679,-0.25907 -0.24804,-0.1819 -0.54568,-0.30317 -0.99219,-0.30317 -0.9095,0 -1.5434,0.68903 -1.5434,1.53238 v 0.011 c 0,0.84887 0.64495,1.52135 1.51585,1.52135 z m 0,0" | |||
id="path24277" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.35277775" | |||
d="m 443.37426,128.10921 h 0.0441 c 0.17639,0 0.29764,-0.0937 0.36378,-0.25356 l 0.97014,-2.32062 c 0.0166,-0.0386 0.0332,-0.0937 0.0332,-0.14331 0,-0.1819 -0.14333,-0.31419 -0.31972,-0.31419 -0.15434,0 -0.27009,0.0992 -0.31418,0.20395 l -0.74966,1.94027 -0.73861,-1.91823 c -0.0496,-0.13229 -0.15988,-0.22599 -0.33073,-0.22599 -0.18193,0 -0.32522,0.1378 -0.32522,0.3197 0,0.0551 0.0166,0.10473 0.0386,0.15985 l 0.95909,2.29857 c 0.0661,0.15985 0.19294,0.25356 0.36933,0.25356 z m 0,0" | |||
id="path24273" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.35277775" | |||
d="m 445.35299,127.0619 h 0.73311 c 0.17088,0 0.31418,-0.1378 0.31418,-0.30868 0,-0.17088 -0.1433,-0.30868 -0.31418,-0.30868 h -0.73311 c -0.17089,0 -0.30868,0.1378 -0.30868,0.30868 0,0.17088 0.13779,0.30868 0.30868,0.30868 z m 0,0" | |||
id="path24269" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.35277775" | |||
d="m 448.51353,128.11472 c 0.44647,0 0.79925,-0.14882 1.03628,-0.29765 0.15984,-0.0882 0.23149,-0.22049 0.23149,-0.41341 v -0.71658 c 0,-0.18191 -0.1433,-0.33073 -0.32519,-0.33073 h -0.74415 c -0.15984,0 -0.28663,0.13229 -0.28663,0.28663 0,0.15434 0.12679,0.28112 0.28663,0.28112 h 0.44098 v 0.41892 c -0.16539,0.12127 -0.38033,0.1819 -0.61737,0.1819 -0.52366,0 -0.89849,-0.39687 -0.89849,-0.94258 v -0.005 c 0,-0.50711 0.38033,-0.92604 0.8544,-0.92604 0.27559,0 0.46852,0.0772 0.64491,0.20395 0.0496,0.0331 0.10474,0.0662 0.19844,0.0662 0.18189,0 0.32522,-0.14332 0.32522,-0.31971 0,-0.12678 -0.0717,-0.21497 -0.13779,-0.26458 -0.26459,-0.1819 -0.56226,-0.28663 -1.00873,-0.28663 -0.89849,0 -1.55445,0.68902 -1.55445,1.53237 v 0.011 c 0,0.87643 0.63391,1.52135 1.55445,1.52135 z m 0,0" | |||
id="path24265" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.35277775" | |||
d="m 450.19155,127.78399 c 0,0.17088 0.12679,0.30868 0.29767,0.30868 0.1378,0 0.24804,-0.0772 0.30314,-0.20394 l 0.20398,-0.49059 h 1.30637 l 0.19844,0.46854 c 0.0606,0.13229 0.15984,0.22599 0.31418,0.22599 0.17089,0 0.30868,-0.14331 0.30868,-0.31419 0,-0.0441 -0.0109,-0.0882 -0.0332,-0.13229 l -1.03628,-2.33164 c -0.0717,-0.15985 -0.19844,-0.25907 -0.37483,-0.25907 h -0.0386 c -0.17639,0 -0.30868,0.0992 -0.38033,0.25907 l -1.03078,2.33164 c -0.0219,0.0441 -0.0386,0.0937 -0.0386,0.1378 z m 1.04732,-0.95911 0.41339,-0.97565 0.40792,0.97565 z m 0,0" | |||
id="path24261" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.35277775" | |||
d="m 453.98691,127.76194 c 0,0.18191 0.1433,0.33073 0.32519,0.33073 0.18193,0 0.32522,-0.14882 0.32522,-0.33073 v -2.06154 h 0.62841 c 0.16534,0 0.29764,-0.13229 0.29764,-0.29766 0,-0.16536 -0.1323,-0.30316 -0.29764,-0.30316 h -1.90723 c -0.16534,0 -0.29763,0.1378 -0.29763,0.30316 0,0.16537 0.13229,0.29766 0.29763,0.29766 h 0.62841 z m 0,0" | |||
id="path24257" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.35277775" | |||
d="m 456.35147,128.06511 h 1.65915 c 0.16538,0 0.29217,-0.12678 0.29217,-0.28663 0,-0.15985 -0.12679,-0.29214 -0.29217,-0.29214 h -1.33943 v -0.62288 h 1.12999 c 0.15984,0 0.29213,-0.12678 0.29213,-0.28663 0,-0.16536 -0.13229,-0.29214 -0.29213,-0.29214 h -1.12999 v -0.60083 h 1.32292 c 0.15984,0 0.29214,-0.12678 0.29214,-0.29214 0,-0.15985 -0.1323,-0.29214 -0.29214,-0.29214 h -1.64264 c -0.18189,0 -0.32523,0.14882 -0.32523,0.33072 v 2.3096 c 0,0.1819 0.14334,0.32521 0.32523,0.32521 z m 0,0" | |||
id="path24253" /> | |||
</g> | |||
</svg> |
@@ -0,0 +1,117 @@ | |||
#include "Core.hpp" | |||
template <int N> | |||
struct CCMidiOutput : midi::Output { | |||
int ccs[N]; | |||
int lastValues[N]; | |||
CCMidiOutput() { | |||
reset(); | |||
} | |||
void reset() { | |||
for (int n = 0; n < N; n++) { | |||
ccs[n] = n; | |||
lastValues[n] = -1; | |||
} | |||
} | |||
void setCC(int cc, int n) { | |||
ccs[n] = cc; | |||
} | |||
void setValue(int value, int n) { | |||
if (value == lastValues[n]) | |||
return; | |||
lastValues[n] = value; | |||
// CC | |||
midi::Message m; | |||
m.setStatus(0xb); | |||
m.setNote(ccs[n]); | |||
m.setValue(value); | |||
sendMessage(m); | |||
} | |||
}; | |||
struct CV_CC : Module { | |||
enum ParamIds { | |||
NUM_PARAMS | |||
}; | |||
enum InputIds { | |||
ENUMS(CC_INPUTS, 16), | |||
NUM_INPUTS | |||
}; | |||
enum OutputIds { | |||
NUM_OUTPUTS | |||
}; | |||
enum LightIds { | |||
NUM_LIGHTS | |||
}; | |||
CCMidiOutput<16> midiOutput; | |||
float rateLimiterPhase = 0.f; | |||
CV_CC() { | |||
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); | |||
} | |||
void step() override { | |||
const float rateLimiterPeriod = 0.010f; | |||
rateLimiterPhase += app()->engine->getSampleTime() / rateLimiterPeriod; | |||
if (rateLimiterPhase >= 1.f) { | |||
rateLimiterPhase -= 1.f; | |||
} | |||
else { | |||
return; | |||
} | |||
for (int n = 0; n < 16; n++) { | |||
int value = (int) std::round(inputs[CC_INPUTS + n].getVoltage() / 10.f * 127); | |||
value = clamp(value, 0, 127); | |||
midiOutput.setValue(value, n); | |||
} | |||
} | |||
}; | |||
struct CV_CCWidget : ModuleWidget { | |||
CV_CCWidget(CV_CC *module) { | |||
setModule(module); | |||
setPanel(SVG::load(asset::system("res/Core/CV-CC.svg"))); | |||
addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, 0))); | |||
addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0))); | |||
addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); | |||
addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(8, 77)), module, CV_CC::CC_INPUTS + 0)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(20, 77)), module, CV_CC::CC_INPUTS + 1)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(31, 77)), module, CV_CC::CC_INPUTS + 2)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(43, 77)), module, CV_CC::CC_INPUTS + 3)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(8, 89)), module, CV_CC::CC_INPUTS + 4)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(20, 89)), module, CV_CC::CC_INPUTS + 5)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(31, 89)), module, CV_CC::CC_INPUTS + 6)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(43, 89)), module, CV_CC::CC_INPUTS + 7)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(8, 101)), module, CV_CC::CC_INPUTS + 8)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(20, 101)), module, CV_CC::CC_INPUTS + 9)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(31, 101)), module, CV_CC::CC_INPUTS + 10)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(43, 101)), module, CV_CC::CC_INPUTS + 11)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(8, 112)), module, CV_CC::CC_INPUTS + 12)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(20, 112)), module, CV_CC::CC_INPUTS + 13)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(31, 112)), module, CV_CC::CC_INPUTS + 14)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(43, 112)), module, CV_CC::CC_INPUTS + 15)); | |||
MidiWidget *midiWidget = createWidget<MidiWidget>(mm2px(Vec(3.4, 14.839))); | |||
midiWidget->box.size = mm2px(Vec(44, 54.667)); | |||
if (module) | |||
midiWidget->midiIO = &module->midiOutput; | |||
// midiWidget->createGridChoices(); | |||
addChild(midiWidget); | |||
} | |||
}; | |||
Model *modelCV_CC = createModel<CV_CC, CV_CCWidget>("CV-CC"); | |||
@@ -0,0 +1,159 @@ | |||
#include "Core.hpp" | |||
template <int N> | |||
struct GateMidiOutput : midi::Output { | |||
int vels[N]; | |||
bool lastGates[N]; | |||
int notes[N]; | |||
GateMidiOutput() { | |||
reset(); | |||
} | |||
void reset() { | |||
for (int n = 0; n < N; n++) { | |||
vels[n] = 100; | |||
lastGates[n] = false; | |||
notes[n] = 60 + n; | |||
} | |||
} | |||
void panic() { | |||
reset(); | |||
// Send all note off commands | |||
for (int note = 0; note <= 127; note++) { | |||
// Note off | |||
midi::Message m; | |||
m.setStatus(0x8); | |||
m.setNote(note); | |||
m.setValue(0); | |||
sendMessage(m); | |||
} | |||
} | |||
void setVelocity(int vel, int n) { | |||
vels[n] = vel; | |||
} | |||
void setGate(bool gate, int n) { | |||
if (gate && !lastGates[n]) { | |||
// Note on | |||
midi::Message m; | |||
m.setStatus(0x9); | |||
m.setNote(notes[n]); | |||
m.setValue(vels[n]); | |||
sendMessage(m); | |||
} | |||
else if (!gate && lastGates[n]) { | |||
// Note off | |||
midi::Message m; | |||
m.setStatus(0x8); | |||
m.setNote(notes[n]); | |||
m.setValue(vels[n]); | |||
sendMessage(m); | |||
} | |||
lastGates[n] = gate; | |||
} | |||
void setNote(int note, int n) { | |||
if (note == notes[n]) | |||
return; | |||
if (lastGates[n]) { | |||
// Note off | |||
midi::Message m1; | |||
m1.setStatus(0x8); | |||
m1.setNote(notes[n]); | |||
m1.setValue(vels[n]); | |||
sendMessage(m1); | |||
// Note on | |||
midi::Message m2; | |||
m2.setStatus(0x9); | |||
m2.setNote(note); | |||
m2.setValue(vels[n]); | |||
sendMessage(m2); | |||
} | |||
notes[n] = note; | |||
} | |||
}; | |||
struct CV_Gate : Module { | |||
enum ParamIds { | |||
NUM_PARAMS | |||
}; | |||
enum InputIds { | |||
ENUMS(GATE_INPUTS, 16), | |||
NUM_INPUTS | |||
}; | |||
enum OutputIds { | |||
NUM_OUTPUTS | |||
}; | |||
enum LightIds { | |||
NUM_LIGHTS | |||
}; | |||
GateMidiOutput<16> midiOutput; | |||
bool velocityMode = false; | |||
CV_Gate() { | |||
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); | |||
} | |||
void step() override { | |||
for (int n = 0; n < 16; n++) { | |||
if (velocityMode) { | |||
int vel = (int) std::round(inputs[GATE_INPUTS + n].getVoltage() / 10.f * 127); | |||
vel = clamp(vel, 0, 127); | |||
midiOutput.setVelocity(vel, n); | |||
midiOutput.setGate(vel > 0, n); | |||
} | |||
else { | |||
bool gate = inputs[GATE_INPUTS + n].getVoltage() >= 1.f; | |||
midiOutput.setVelocity(100, n); | |||
midiOutput.setGate(gate, n); | |||
} | |||
} | |||
} | |||
}; | |||
struct CV_GateWidget : ModuleWidget { | |||
CV_GateWidget(CV_Gate *module) { | |||
setModule(module); | |||
setPanel(SVG::load(asset::system("res/Core/CV-Gate.svg"))); | |||
addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, 0))); | |||
addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0))); | |||
addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); | |||
addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(8, 77)), module, CV_Gate::GATE_INPUTS + 0)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(20, 77)), module, CV_Gate::GATE_INPUTS + 1)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(31, 77)), module, CV_Gate::GATE_INPUTS + 2)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(43, 77)), module, CV_Gate::GATE_INPUTS + 3)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(8, 89)), module, CV_Gate::GATE_INPUTS + 4)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(20, 89)), module, CV_Gate::GATE_INPUTS + 5)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(31, 89)), module, CV_Gate::GATE_INPUTS + 6)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(43, 89)), module, CV_Gate::GATE_INPUTS + 7)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(8, 101)), module, CV_Gate::GATE_INPUTS + 8)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(20, 101)), module, CV_Gate::GATE_INPUTS + 9)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(31, 101)), module, CV_Gate::GATE_INPUTS + 10)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(43, 101)), module, CV_Gate::GATE_INPUTS + 11)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(8, 112)), module, CV_Gate::GATE_INPUTS + 12)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(20, 112)), module, CV_Gate::GATE_INPUTS + 13)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(31, 112)), module, CV_Gate::GATE_INPUTS + 14)); | |||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(43, 112)), module, CV_Gate::GATE_INPUTS + 15)); | |||
MidiWidget *midiWidget = createWidget<MidiWidget>(mm2px(Vec(3.4, 14.839))); | |||
midiWidget->box.size = mm2px(Vec(44, 54.667)); | |||
if (module) | |||
midiWidget->midiIO = &module->midiOutput; | |||
// midiWidget->createGridChoices(); | |||
addChild(midiWidget); | |||
} | |||
}; | |||
Model *modelCV_Gate = createModel<CV_Gate, CV_GateWidget>("CV-Gate"); | |||
@@ -52,7 +52,7 @@ struct PolyphonicMidiOutput : midi::Output { | |||
} | |||
} | |||
void setVel(int vel, int c) { | |||
void setVelocity(int vel, int c) { | |||
vels[c] = vel; | |||
} | |||
@@ -229,16 +229,26 @@ struct CV_MIDI : Module { | |||
}; | |||
PolyphonicMidiOutput<PORT_MAX_CHANNELS> midiOutput; | |||
float rateLimiterPhase = 0.f; | |||
CV_MIDI() { | |||
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); | |||
} | |||
void step() override { | |||
const float rateLimiterPeriod = 0.005f; | |||
rateLimiterPhase += app()->engine->getSampleTime() / rateLimiterPeriod; | |||
if (rateLimiterPhase >= 1.f) { | |||
rateLimiterPhase -= 1.f; | |||
} | |||
else { | |||
return; | |||
} | |||
for (int c = 0; c < inputs[PITCH_INPUT].getChannels(); c++) { | |||
int vel = (int) std::round(inputs[VEL_INPUT].normalize(10.f * 100 / 127, c) / 10.f * 127); | |||
vel = clamp(vel, 0, 127); | |||
midiOutput.setVel(vel, c); | |||
midiOutput.setVelocity(vel, c); | |||
int note = (int) std::round(inputs[PITCH_INPUT].getVoltage(c) * 12.f + 60.f); | |||
note = clamp(note, 0, 127); | |||
@@ -262,9 +272,6 @@ struct CV_MIDI : Module { | |||
mw = clamp(mw, 0, 127); | |||
midiOutput.setModWheel(mw); | |||
bool clk = inputs[CLK_INPUT].value >= 1.f; | |||
midiOutput.setClock(clk); | |||
int vol = (int) std::round(inputs[VOL_INPUT].normalize(10.f) / 10.f * 127); | |||
vol = clamp(vol, 0, 127); | |||
midiOutput.setVolume(vol); | |||
@@ -273,6 +280,9 @@ struct CV_MIDI : Module { | |||
pan = clamp(pan, 0, 127); | |||
midiOutput.setPan(pan); | |||
bool clk = inputs[CLK_INPUT].value >= 1.f; | |||
midiOutput.setClock(clk); | |||
bool start = inputs[START_INPUT].value >= 1.f; | |||
midiOutput.setStart(start); | |||
@@ -14,7 +14,7 @@ void init(rack::Plugin *p) { | |||
p->sourceUrl = "https://github.com/VCVRack/Rack"; | |||
modelAudioInterface->name = "Audio"; | |||
modelAudioInterface->description = ""; | |||
modelAudioInterface->description = "Sends audio and CV to/from an audio device"; | |||
modelAudioInterface->tags = {"External"}; | |||
p->addModel(modelAudioInterface); | |||
@@ -43,6 +43,16 @@ void init(rack::Plugin *p) { | |||
modelCV_MIDI->tags = {"External", "MIDI"}; | |||
p->addModel(modelCV_MIDI); | |||
modelCV_CC->name = "CV-CC"; | |||
modelCV_CC->description = ""; | |||
modelCV_CC->tags = {"External", "MIDI"}; | |||
p->addModel(modelCV_CC); | |||
modelCV_Gate->name = "CV-Gate"; | |||
modelCV_Gate->description = ""; | |||
modelCV_Gate->tags = {"External", "MIDI"}; | |||
p->addModel(modelCV_Gate); | |||
modelBlank->name = "Blank"; | |||
modelBlank->description = ""; | |||
modelBlank->tags = {"Blank"}; | |||
@@ -11,6 +11,8 @@ extern Model *modelQuadMIDIToCVInterface; | |||
extern Model *modelMIDICCToCVInterface; | |||
extern Model *modelMIDITriggerToCVInterface; | |||
extern Model *modelCV_MIDI; | |||
extern Model *modelCV_CC; | |||
extern Model *modelCV_Gate; | |||
extern Model *modelBlank; | |||
extern Model *modelNotes; | |||
@@ -67,7 +67,7 @@ void Knob::onDragMove(const event::DragMove &e) { | |||
float delta = KNOB_SENSITIVITY * -e.mouseDelta.y * speed * range; | |||
// Drag slower if Mod is held | |||
if (app()->window->isModPressed()) | |||
if ((app()->window->getMods() & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) | |||
delta /= 16.f; | |||
if (snap) { | |||
@@ -16,12 +16,13 @@ namespace rack { | |||
ModuleWidget::~ModuleWidget() { | |||
if (module) { | |||
delete module; | |||
} | |||
setModule(NULL); | |||
} | |||
void ModuleWidget::setModule(Module *module) { | |||
if (this->module) { | |||
delete this->module; | |||
} | |||
this->module = module; | |||
} | |||
@@ -338,7 +339,7 @@ void ModuleWidget::onHover(const event::Hover &e) { | |||
// Instead of checking key-down events, delete the module even if key-repeat hasn't fired yet and the cursor is hovering over the widget. | |||
if (glfwGetKey(app()->window->win, GLFW_KEY_DELETE) == GLFW_PRESS || glfwGetKey(app()->window->win, GLFW_KEY_BACKSPACE) == GLFW_PRESS) { | |||
if (!app()->window->isModPressed() && !app()->window->isShiftPressed()) { | |||
if ((app()->window->getMods() & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
ModuleWidget_removeAction(this); | |||
e.consume(NULL); | |||
return; | |||
@@ -348,8 +349,9 @@ void ModuleWidget::onHover(const event::Hover &e) { | |||
void ModuleWidget::onButton(const event::Button &e) { | |||
OpaqueWidget::onButton(e); | |||
if (e.getConsumed() == this) { | |||
if (e.button == 1) { | |||
if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT) { | |||
createContextMenu(); | |||
} | |||
} | |||
@@ -359,43 +361,43 @@ void ModuleWidget::onHoverKey(const event::HoverKey &e) { | |||
if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) { | |||
switch (e.key) { | |||
case GLFW_KEY_I: { | |||
if (app()->window->isModPressed() && !app()->window->isShiftPressed()) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
reset(); | |||
e.consume(this); | |||
} | |||
} break; | |||
case GLFW_KEY_R: { | |||
if (app()->window->isModPressed() && !app()->window->isShiftPressed()) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
randomize(); | |||
e.consume(this); | |||
} | |||
} break; | |||
case GLFW_KEY_C: { | |||
if (app()->window->isModPressed() && !app()->window->isShiftPressed()) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
copyClipboard(); | |||
e.consume(this); | |||
} | |||
} break; | |||
case GLFW_KEY_V: { | |||
if (app()->window->isModPressed() && !app()->window->isShiftPressed()) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
pasteClipboard(); | |||
e.consume(this); | |||
} | |||
} break; | |||
case GLFW_KEY_D: { | |||
if (app()->window->isModPressed() && !app()->window->isShiftPressed()) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
app()->scene->rackWidget->cloneModule(this); | |||
e.consume(this); | |||
} | |||
} break; | |||
case GLFW_KEY_U: { | |||
if (app()->window->isModPressed() && !app()->window->isShiftPressed()) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
disconnect(); | |||
e.consume(this); | |||
} | |||
} break; | |||
case GLFW_KEY_E: { | |||
if (app()->window->isModPressed() && !app()->window->isShiftPressed()) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
ModuleWidget_bypassAction(this); | |||
e.consume(this); | |||
} | |||
@@ -436,7 +438,7 @@ struct ModuleDisconnectItem : MenuItem { | |||
ModuleWidget *moduleWidget; | |||
ModuleDisconnectItem() { | |||
text = "Disconnect cables"; | |||
rightText = WINDOW_MOD_KEY_NAME "+U"; | |||
rightText = WINDOW_MOD_CTRL_NAME "+U"; | |||
} | |||
void onAction(const event::Action &e) override { | |||
moduleWidget->disconnect(); | |||
@@ -447,7 +449,7 @@ struct ModuleResetItem : MenuItem { | |||
ModuleWidget *moduleWidget; | |||
ModuleResetItem() { | |||
text = "Initialize"; | |||
rightText = WINDOW_MOD_KEY_NAME "+I"; | |||
rightText = WINDOW_MOD_CTRL_NAME "+I"; | |||
} | |||
void onAction(const event::Action &e) override { | |||
moduleWidget->reset(); | |||
@@ -458,7 +460,7 @@ struct ModuleRandomizeItem : MenuItem { | |||
ModuleWidget *moduleWidget; | |||
ModuleRandomizeItem() { | |||
text = "Randomize"; | |||
rightText = WINDOW_MOD_KEY_NAME "+R"; | |||
rightText = WINDOW_MOD_CTRL_NAME "+R"; | |||
} | |||
void onAction(const event::Action &e) override { | |||
moduleWidget->randomize(); | |||
@@ -469,7 +471,7 @@ struct ModuleCopyItem : MenuItem { | |||
ModuleWidget *moduleWidget; | |||
ModuleCopyItem() { | |||
text = "Copy preset"; | |||
rightText = WINDOW_MOD_KEY_NAME "+C"; | |||
rightText = WINDOW_MOD_CTRL_NAME "+C"; | |||
} | |||
void onAction(const event::Action &e) override { | |||
moduleWidget->copyClipboard(); | |||
@@ -480,7 +482,7 @@ struct ModulePasteItem : MenuItem { | |||
ModuleWidget *moduleWidget; | |||
ModulePasteItem() { | |||
text = "Paste preset"; | |||
rightText = WINDOW_MOD_KEY_NAME "+V"; | |||
rightText = WINDOW_MOD_CTRL_NAME "+V"; | |||
} | |||
void onAction(const event::Action &e) override { | |||
moduleWidget->pasteClipboard(); | |||
@@ -511,7 +513,7 @@ struct ModuleCloneItem : MenuItem { | |||
ModuleWidget *moduleWidget; | |||
ModuleCloneItem() { | |||
text = "Duplicate"; | |||
rightText = WINDOW_MOD_KEY_NAME "+D"; | |||
rightText = WINDOW_MOD_CTRL_NAME "+D"; | |||
} | |||
void onAction(const event::Action &e) override { | |||
app()->scene->rackWidget->cloneModule(moduleWidget); | |||
@@ -524,7 +526,7 @@ struct ModuleBypassItem : MenuItem { | |||
text = "Bypass"; | |||
} | |||
void step() override { | |||
rightText = WINDOW_MOD_KEY_NAME "+E"; | |||
rightText = WINDOW_MOD_CTRL_NAME "+E"; | |||
if (!moduleWidget->module) | |||
return; | |||
if (moduleWidget->module->bypass) | |||
@@ -119,7 +119,7 @@ void ParamWidget::fromJson(json_t *rootJ) { | |||
void ParamWidget::onButton(const event::Button &e) { | |||
// Right click to reset | |||
if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT && !(e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) { | |||
if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT && (e.mods & WINDOW_MOD_MASK) == 0) { | |||
if (paramQuantity && paramQuantity->isBounded()) { | |||
float oldValue = paramQuantity->getValue(); | |||
paramQuantity->reset(); | |||
@@ -141,7 +141,7 @@ void ParamWidget::onButton(const event::Button &e) { | |||
} | |||
// Shift-click to open value entry | |||
if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT && !(e.mods & WINDOW_MOD) && (e.mods & GLFW_MOD_SHIFT)) { | |||
if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT && (e.mods & WINDOW_MOD_MASK) == GLFW_MOD_SHIFT) { | |||
// Create ParamField | |||
MenuOverlay *overlay = new MenuOverlay; | |||
app()->scene->addChild(overlay); | |||
@@ -72,7 +72,10 @@ void PortWidget::onButton(const event::Button &e) { | |||
void PortWidget::onDragStart(const event::DragStart &e) { | |||
// Try to grab cable on top of stack | |||
CableWidget *cable = NULL; | |||
if (type == INPUT || !app()->window->isModPressed()) { | |||
if (type == OUTPUT && (app()->window->getMods() & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
// Keep cable NULL | |||
} | |||
else { | |||
cable = app()->scene->rackWidget->cableContainer->getTopCable(this); | |||
} | |||
@@ -591,11 +591,11 @@ void RackWidget::draw(NVGcontext *vg) { | |||
void RackWidget::onHover(const event::Hover &e) { | |||
// Scroll with arrow keys | |||
float arrowSpeed = 30.0; | |||
if (app()->window->isShiftPressed() && app()->window->isModPressed()) | |||
if ((app()->window->getMods() & WINDOW_MOD_MASK) == (WINDOW_MOD_CTRL |GLFW_MOD_SHIFT)) | |||
arrowSpeed /= 16.0; | |||
else if (app()->window->isShiftPressed()) | |||
else if ((app()->window->getMods() & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) | |||
arrowSpeed *= 4.0; | |||
else if (app()->window->isModPressed()) | |||
else if ((app()->window->getMods() & WINDOW_MOD_MASK) == GLFW_MOD_SHIFT) | |||
arrowSpeed /= 4.0; | |||
ScrollWidget *scrollWidget = app()->scene->scrollWidget; | |||
@@ -84,49 +84,49 @@ void Scene::onHoverKey(const event::HoverKey &e) { | |||
if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) { | |||
switch (e.key) { | |||
case GLFW_KEY_N: { | |||
if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
rackWidget->reset(); | |||
e.consume(this); | |||
} | |||
} break; | |||
case GLFW_KEY_Q: { | |||
if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
app()->window->close(); | |||
e.consume(this); | |||
} | |||
} break; | |||
case GLFW_KEY_O: { | |||
if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
rackWidget->loadDialog(); | |||
e.consume(this); | |||
} | |||
if ((e.mods & WINDOW_MOD) && (e.mods & GLFW_MOD_SHIFT)) { | |||
if ((e.mods & WINDOW_MOD_MASK) == (WINDOW_MOD_CTRL | GLFW_MOD_SHIFT)) { | |||
rackWidget->revert(); | |||
e.consume(this); | |||
} | |||
} break; | |||
case GLFW_KEY_S: { | |||
if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
rackWidget->saveDialog(); | |||
e.consume(this); | |||
} | |||
if ((e.mods & WINDOW_MOD) && (e.mods & GLFW_MOD_SHIFT)) { | |||
if ((e.mods & WINDOW_MOD_MASK) == (WINDOW_MOD_CTRL | GLFW_MOD_SHIFT)) { | |||
rackWidget->saveAsDialog(); | |||
e.consume(this); | |||
} | |||
} break; | |||
case GLFW_KEY_V: { | |||
if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
rackWidget->pastePresetClipboard(); | |||
e.consume(this); | |||
} | |||
} break; | |||
case GLFW_KEY_Z: { | |||
if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
app()->history->undo(); | |||
e.consume(this); | |||
} | |||
if ((e.mods & WINDOW_MOD) && (e.mods & GLFW_MOD_SHIFT)) { | |||
if ((e.mods & WINDOW_MOD_MASK) == (WINDOW_MOD_CTRL | GLFW_MOD_SHIFT)) { | |||
app()->history->redo(); | |||
e.consume(this); | |||
} | |||
@@ -33,12 +33,13 @@ void Switch::onDragStart(const event::DragStart &e) { | |||
else { | |||
if (paramQuantity) { | |||
float oldValue = paramQuantity->getValue(); | |||
// Increment value by 1, or reset back to minimum | |||
if (paramQuantity->isMax()) { | |||
// Reset value back to minimum | |||
paramQuantity->setMin(); | |||
} | |||
else { | |||
paramQuantity->setValue(std::floor(paramQuantity->getValue() + 1)); | |||
// Increment value by 1 | |||
paramQuantity->setValue(std::round(paramQuantity->getValue()) + 1.f); | |||
} | |||
float newValue = paramQuantity->getValue(); | |||
@@ -35,7 +35,7 @@ struct MenuButton : Button { | |||
struct NewItem : MenuItem { | |||
NewItem() { | |||
text = "New"; | |||
rightText = "(" WINDOW_MOD_KEY_NAME "+N)"; | |||
rightText = "(" WINDOW_MOD_CTRL_NAME "+N)"; | |||
} | |||
void onAction(const event::Action &e) override { | |||
app()->scene->rackWidget->reset(); | |||
@@ -46,7 +46,7 @@ struct NewItem : MenuItem { | |||
struct OpenItem : MenuItem { | |||
OpenItem() { | |||
text = "Open"; | |||
rightText = "(" WINDOW_MOD_KEY_NAME "+O)"; | |||
rightText = "(" WINDOW_MOD_CTRL_NAME "+O)"; | |||
} | |||
void onAction(const event::Action &e) override { | |||
app()->scene->rackWidget->loadDialog(); | |||
@@ -57,7 +57,7 @@ struct OpenItem : MenuItem { | |||
struct SaveItem : MenuItem { | |||
SaveItem() { | |||
text = "Save"; | |||
rightText = "(" WINDOW_MOD_KEY_NAME "+S)"; | |||
rightText = "(" WINDOW_MOD_CTRL_NAME "+S)"; | |||
} | |||
void onAction(const event::Action &e) override { | |||
app()->scene->rackWidget->saveDialog(); | |||
@@ -68,7 +68,7 @@ struct SaveItem : MenuItem { | |||
struct SaveAsItem : MenuItem { | |||
SaveAsItem() { | |||
text = "Save as"; | |||
rightText = "(" WINDOW_MOD_KEY_NAME "+Shift+S)"; | |||
rightText = "(" WINDOW_MOD_CTRL_NAME "+Shift+S)"; | |||
} | |||
void onAction(const event::Action &e) override { | |||
app()->scene->rackWidget->saveAsDialog(); | |||
@@ -109,7 +109,7 @@ struct DisconnectCablesItem : MenuItem { | |||
struct QuitItem : MenuItem { | |||
QuitItem() { | |||
text = "Quit"; | |||
rightText = "(" WINDOW_MOD_KEY_NAME "+Q)"; | |||
rightText = "(" WINDOW_MOD_CTRL_NAME "+Q)"; | |||
} | |||
void onAction(const event::Action &e) override { | |||
app()->window->close(); | |||
@@ -63,8 +63,8 @@ struct RtMidiOutputDevice : midi::OutputDevice { | |||
void sendMessage(midi::Message message) override { | |||
unsigned char msg[3]; | |||
msg[0] = message.cmd; | |||
msg[0] = message.data1; | |||
msg[0] = message.data2; | |||
msg[1] = message.data1; | |||
msg[2] = message.data2; | |||
rtMidiOut->sendMessage(msg, 3); | |||
} | |||
}; | |||
@@ -94,7 +94,7 @@ void TextField::onSelectKey(const event::SelectKey &e) { | |||
} | |||
} break; | |||
case GLFW_KEY_LEFT: { | |||
if (app()->window->isModPressed()) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
while (--cursor > 0) { | |||
if (text[cursor] == ' ') | |||
break; | |||
@@ -103,12 +103,12 @@ void TextField::onSelectKey(const event::SelectKey &e) { | |||
else { | |||
cursor--; | |||
} | |||
if (!app()->window->isShiftPressed()) { | |||
if ((e.mods & WINDOW_MOD_MASK) == 0) { | |||
selection = cursor; | |||
} | |||
} break; | |||
case GLFW_KEY_RIGHT: { | |||
if (app()->window->isModPressed()) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
while (++cursor < (int) text.size()) { | |||
if (text[cursor] == ' ') | |||
break; | |||
@@ -117,7 +117,7 @@ void TextField::onSelectKey(const event::SelectKey &e) { | |||
else { | |||
cursor++; | |||
} | |||
if (!app()->window->isShiftPressed()) { | |||
if ((e.mods & WINDOW_MOD_MASK) == 0) { | |||
selection = cursor; | |||
} | |||
} break; | |||
@@ -128,14 +128,14 @@ void TextField::onSelectKey(const event::SelectKey &e) { | |||
selection = cursor = text.size(); | |||
} break; | |||
case GLFW_KEY_V: { | |||
if (app()->window->isModPressed()) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
const char *newText = glfwGetClipboardString(app()->window->win); | |||
if (newText) | |||
insertText(newText); | |||
} | |||
} break; | |||
case GLFW_KEY_X: { | |||
if (app()->window->isModPressed()) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
if (cursor != selection) { | |||
int begin = std::min(cursor, selection); | |||
std::string selectedText = text.substr(begin, std::abs(selection - cursor)); | |||
@@ -145,7 +145,7 @@ void TextField::onSelectKey(const event::SelectKey &e) { | |||
} | |||
} break; | |||
case GLFW_KEY_C: { | |||
if (app()->window->isModPressed()) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
if (cursor != selection) { | |||
int begin = std::min(cursor, selection); | |||
std::string selectedText = text.substr(begin, std::abs(selection - cursor)); | |||
@@ -154,7 +154,7 @@ void TextField::onSelectKey(const event::SelectKey &e) { | |||
} | |||
} break; | |||
case GLFW_KEY_A: { | |||
if (app()->window->isModPressed()) { | |||
if ((e.mods & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||
selectAll(); | |||
} | |||
} break; | |||
@@ -66,6 +66,7 @@ static void mouseButtonCallback(GLFWwindow *win, int button, int action, int mod | |||
if (button == GLFW_MOUSE_BUTTON_LEFT) { | |||
if (mods & GLFW_MOD_CONTROL) { | |||
button = GLFW_MOUSE_BUTTON_RIGHT; | |||
mods &= ~GLFW_MOD_CONTROL; | |||
} | |||
} | |||
#endif | |||
@@ -123,12 +124,12 @@ static void cursorEnterCallback(GLFWwindow *win, int entered) { | |||
static void scrollCallback(GLFWwindow *win, double x, double y) { | |||
Window *window = (Window*) glfwGetWindowUserPointer(win); | |||
math::Vec scrollDelta = math::Vec(x, y); | |||
#if ARCH_LIN || ARCH_WIN | |||
if (window->isShiftPressed()) | |||
scrollDelta = math::Vec(y, x); | |||
#endif | |||
scrollDelta = scrollDelta.mult(50.0); | |||
// Flip coordinates if shift is held | |||
if ((window->getMods() & WINDOW_MOD_MASK) == GLFW_MOD_SHIFT) | |||
scrollDelta = scrollDelta.flip(); | |||
app()->event->handleScroll(window->mousePos, scrollDelta); | |||
} | |||
@@ -142,7 +143,7 @@ static void keyCallback(GLFWwindow *win, int key, int scancode, int action, int | |||
app()->event->handleKey(window->mousePos, key, scancode, action, mods); | |||
// Keyboard MIDI driver | |||
if (!(mods & (GLFW_MOD_SHIFT | GLFW_MOD_CONTROL | GLFW_MOD_ALT | GLFW_MOD_SUPER))) { | |||
if ((mods & WINDOW_MOD_MASK) == 0) { | |||
if (action == GLFW_PRESS) { | |||
keyboard::press(key); | |||
} | |||
@@ -380,16 +381,17 @@ void Window::cursorUnlock() { | |||
} | |||
} | |||
bool Window::isModPressed() { | |||
#ifdef ARCH_MAC | |||
return glfwGetKey(win, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS || glfwGetKey(win, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS; | |||
#else | |||
return glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS || glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS; | |||
#endif | |||
} | |||
bool Window::isShiftPressed() { | |||
return glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS || glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS; | |||
int Window::getMods() { | |||
int mods = 0; | |||
if (glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS || glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS) | |||
mods |= GLFW_MOD_SHIFT; | |||
if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS || glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) | |||
mods |= GLFW_MOD_CONTROL; | |||
if (glfwGetKey(win, GLFW_KEY_LEFT_ALT) == GLFW_PRESS || glfwGetKey(win, GLFW_KEY_RIGHT_ALT) == GLFW_PRESS) | |||
mods |= GLFW_MOD_ALT; | |||
if (glfwGetKey(win, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS || glfwGetKey(win, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS) | |||
mods |= GLFW_MOD_SUPER; | |||
return mods; | |||
} | |||
math::Vec Window::getWindowSize() { | |||