Graphic EQ controls; focus/click bugs.
This commit is contained in:
@@ -324,6 +324,7 @@ void Lv2Pedalboard::PrepareMidiMap(const PedalboardItem &pedalboardItem)
|
||||
mapping.midiBinding = binding;
|
||||
mapping.instanceId = pedalboardItem.instanceId();
|
||||
|
||||
|
||||
if (pPortInfo->mod_momentaryOffByDefault() || pPortInfo->mod_momentaryOnByDefault())
|
||||
{
|
||||
mapping.mappingType = MidiControlType::MomentarySwitch;
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
|
||||
#define PIPEDAL_UI__ledColor PIPEDAL_UI_PREFIX "ledColor"
|
||||
|
||||
#define PIPEDAL_UI__graphicEq PIPEDAL_UI_PREFIX "graphicEq"
|
||||
|
||||
|
||||
namespace pipedal {
|
||||
|
||||
|
||||
@@ -159,6 +159,7 @@ void PluginHost::LilvUris::Initialize(LilvWorld *pWorld)
|
||||
pipedalUI__yBottom = lilv_new_uri(pWorld, PIPEDAL_UI__yBottom);
|
||||
pipedalUI__xLog = lilv_new_uri(pWorld, PIPEDAL_UI__xLog);
|
||||
pipedalUI__width = lilv_new_uri(pWorld, PIPEDAL_UI__width);
|
||||
pipedalUI__graphicEq = lilv_new_uri(pWorld,PIPEDAL_UI__graphicEq);
|
||||
|
||||
ui__portNotification = lilv_new_uri(pWorld, LV2_UI__portNotification);
|
||||
ui__plugin = lilv_new_uri(pWorld, LV2_UI__plugin);
|
||||
@@ -1005,8 +1006,12 @@ Lv2PortInfo::Lv2PortInfo(PluginHost *host, const LilvPlugin *plugin, const LilvP
|
||||
this->integer_property_ = lilv_port_has_property(plugin, pPort, host->lilvUris->integer_property_uri);
|
||||
this->mod_momentaryOffByDefault_ = lilv_port_has_property(plugin, pPort, host->lilvUris->mod__preferMomentaryOffByDefault);
|
||||
this->mod_momentaryOnByDefault_ = lilv_port_has_property(plugin, pPort, host->lilvUris->mod__preferMomentaryOnByDefault);
|
||||
this->pipedal_graphicEq_ = lilv_port_has_property(plugin, pPort, host->lilvUris->pipedalUI__graphicEq);
|
||||
|
||||
|
||||
this->enumeration_property_ = lilv_port_has_property(plugin, pPort, host->lilvUris->enumeration_property_uri);
|
||||
|
||||
|
||||
this->toggled_property_ = lilv_port_has_property(plugin, pPort, host->lilvUris->core__toggled);
|
||||
this->not_on_gui_ = lilv_port_has_property(plugin, pPort, host->lilvUris->portprops__not_on_gui_property_uri);
|
||||
this->connection_optional_ = lilv_port_has_property(plugin, pPort, host->lilvUris->core__connectionOptional);
|
||||
@@ -1729,6 +1734,7 @@ json_map::storage_type<Lv2PortInfo> Lv2PortInfo::jmap{
|
||||
MAP_REF(Lv2PortInfo, toggled_property),
|
||||
MAP_REF(Lv2PortInfo, mod_momentaryOffByDefault),
|
||||
MAP_REF(Lv2PortInfo, mod_momentaryOnByDefault),
|
||||
MAP_REF(Lv2PortInfo, pipedal_graphicEq),
|
||||
MAP_REF(Lv2PortInfo, not_on_gui),
|
||||
MAP_REF(Lv2PortInfo, buffer_type),
|
||||
MAP_REF(Lv2PortInfo, port_group),
|
||||
@@ -1796,6 +1802,7 @@ json_map::storage_type<Lv2PluginUiPort> Lv2PluginUiPort::jmap{{
|
||||
|
||||
MAP_REF(Lv2PluginUiPort, mod_momentaryOffByDefault),
|
||||
MAP_REF(Lv2PluginUiPort, mod_momentaryOnByDefault),
|
||||
MAP_REF(Lv2PluginUiPort, pipedal_graphicEq),
|
||||
MAP_REF(Lv2PluginUiPort, enumeration_property),
|
||||
MAP_REF(Lv2PluginUiPort, not_on_gui),
|
||||
MAP_REF(Lv2PluginUiPort, toggled_property),
|
||||
|
||||
@@ -221,6 +221,7 @@ namespace pipedal
|
||||
|
||||
bool mod_momentaryOffByDefault_ = false;
|
||||
bool mod_momentaryOnByDefault_ = false;
|
||||
bool pipedal_graphicEq_ = false;
|
||||
|
||||
bool not_on_gui_ = false;
|
||||
std::string buffer_type_;
|
||||
@@ -294,6 +295,7 @@ namespace pipedal
|
||||
LV2_PROPERTY_GETSET_SCALAR(integer_property);
|
||||
LV2_PROPERTY_GETSET_SCALAR(mod_momentaryOffByDefault);
|
||||
LV2_PROPERTY_GETSET_SCALAR(mod_momentaryOnByDefault);
|
||||
LV2_PROPERTY_GETSET_SCALAR(pipedal_graphicEq);
|
||||
LV2_PROPERTY_GETSET_SCALAR(enumeration_property);
|
||||
LV2_PROPERTY_GETSET_SCALAR(toggled_property);
|
||||
LV2_PROPERTY_GETSET_SCALAR(not_on_gui);
|
||||
@@ -513,6 +515,7 @@ namespace pipedal
|
||||
integer_property_(pPort->integer_property()),
|
||||
mod_momentaryOffByDefault_(pPort->mod_momentaryOffByDefault()),
|
||||
mod_momentaryOnByDefault_(pPort->mod_momentaryOnByDefault()),
|
||||
pipedal_graphicEq_(pPort->pipedal_graphicEq()),
|
||||
|
||||
enumeration_property_(pPort->enumeration_property()),
|
||||
toggled_property_(pPort->toggled_property()), not_on_gui_(pPort->not_on_gui()), scale_points_(pPort->scale_points()),
|
||||
@@ -558,6 +561,8 @@ namespace pipedal
|
||||
|
||||
bool mod_momentaryOffByDefault_ = false;
|
||||
bool mod_momentaryOnByDefault_ = false;
|
||||
bool pipedal_graphicEq_ = false;
|
||||
|
||||
bool enumeration_property_ = false;
|
||||
bool not_on_gui_ = false;
|
||||
bool toggled_property_ = false;
|
||||
@@ -728,6 +733,7 @@ namespace pipedal
|
||||
AutoLilvNode pipedalUI__yTop;
|
||||
AutoLilvNode pipedalUI__yBottom;
|
||||
AutoLilvNode pipedalUI__width;
|
||||
AutoLilvNode pipedalUI__graphicEq;
|
||||
|
||||
|
||||
AutoLilvNode pipedalUI__outputPorts;
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Robin E. R. Davies
|
||||
* All rights reserved.
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import SvgPathBuilder from "./SvgPathBuilder";
|
||||
|
||||
export interface GraphicEqCtlProps {
|
||||
position: number;
|
||||
imgRef: React.Ref<SVGSVGElement> | undefined;
|
||||
onTouchStart: React.TouchEventHandler<SVGSVGElement> | undefined;
|
||||
onTouchMove: React.TouchEventHandler<SVGSVGElement> | undefined;
|
||||
onPointerDown: React.PointerEventHandler<SVGSVGElement> | undefined;
|
||||
onPointerUp: React.PointerEventHandler<SVGSVGElement> | undefined;
|
||||
onPointerMoveCapture: React.PointerEventHandler<SVGSVGElement> | undefined;
|
||||
onDrag: React.DragEventHandler<SVGSVGElement> | undefined;
|
||||
dialColor: string;
|
||||
opacity: number;
|
||||
};
|
||||
|
||||
const STROKE_HEIGHT=8.0;
|
||||
|
||||
function MakeGraphicEqPath(value: number)
|
||||
{
|
||||
|
||||
let x0 = 6;
|
||||
let xN = 64-x0;
|
||||
let xC0 = (64-STROKE_HEIGHT)/2;
|
||||
let xC1 = xC0+STROKE_HEIGHT;
|
||||
|
||||
let h = 64-STROKE_HEIGHT*2.5;
|
||||
|
||||
let y0 = 0;
|
||||
let y1 = h-h*value;;
|
||||
let y2 = y1 + STROKE_HEIGHT;
|
||||
let y3 = y2 + STROKE_HEIGHT/2;
|
||||
let y4 = y3 + STROKE_HEIGHT;
|
||||
let y5 = 64;
|
||||
|
||||
|
||||
let s = new SvgPathBuilder();
|
||||
s.moveTo(x0,y1)
|
||||
.lineTo(xC0,y1)
|
||||
.lineTo(xC0,y0)
|
||||
.lineTo(xC1,y0)
|
||||
.lineTo(xC1,y1)
|
||||
.lineTo(xN,y1)
|
||||
.lineTo(xN,y2)
|
||||
.lineTo(x0,y2)
|
||||
.closePath()
|
||||
|
||||
.moveTo(x0,y3)
|
||||
.lineTo(x0,y4)
|
||||
.lineTo(xC0,y4)
|
||||
.lineTo(xC0,y5)
|
||||
.lineTo(xC1,y5)
|
||||
.lineTo(xC1,y4)
|
||||
.lineTo(xN,y4)
|
||||
.lineTo(xN,y3)
|
||||
.lineTo(x0,y3)
|
||||
.closePath();
|
||||
return s.toString();
|
||||
|
||||
}
|
||||
export function UpdateGraphicEqPath(el: SVGSVGElement, value: number) {
|
||||
if (!el) return;
|
||||
let p = MakeGraphicEqPath(value);
|
||||
let pathEl = el.getElementById("myPath");
|
||||
pathEl?.setAttribute("d",p);
|
||||
}
|
||||
|
||||
export default function GraphicEqCtl(props: GraphicEqCtlProps) {
|
||||
return (
|
||||
<svg width="64px" height="64px"
|
||||
ref={props.imgRef}
|
||||
viewBox="0 0 64 64"
|
||||
style={{
|
||||
overscrollBehavior: "none",
|
||||
touchAction: "none",
|
||||
width: 36, height: 42, opacity: props.opacity
|
||||
}}
|
||||
onTouchStart={props.onTouchStart}
|
||||
onTouchMove={props.onTouchMove}
|
||||
onPointerDown={props.onPointerDown}
|
||||
onPointerUp={props.onPointerUp}
|
||||
onPointerMoveCapture={props.onPointerMoveCapture}
|
||||
onDrag={props.onDrag}
|
||||
fill={props.dialColor}
|
||||
>
|
||||
<path id="myPath" d={MakeGraphicEqPath(props.position)} />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -453,6 +453,7 @@ export enum ControlType {
|
||||
Trigger,
|
||||
Momentary,
|
||||
MomentaryOnByDefault,
|
||||
GraphicEq,
|
||||
|
||||
Tuner,
|
||||
Vu,
|
||||
@@ -497,6 +498,7 @@ deserialize(input: any): UiControl {
|
||||
this.integer_property = input.integer_property;
|
||||
this.mod_momentaryOffByDefault = input.mod_momentaryOffByDefault;
|
||||
this.mod_momentaryOnByDefault = input.mod_momentaryOnByDefault;
|
||||
this.pipedal_graphicEq = input.pipedal_graphicEq;
|
||||
this.enumeration_property = input.enumeration_property;
|
||||
this.toggled_property = input.toggled_property;
|
||||
this.trigger_property = input.trigger_property;
|
||||
@@ -548,7 +550,11 @@ deserialize(input: any): UiControl {
|
||||
}
|
||||
if (this.is_input)
|
||||
{
|
||||
if (this.mod_momentaryOnByDefault) {
|
||||
if (this.pipedal_graphicEq)
|
||||
{
|
||||
this.controlType = ControlType.GraphicEq;
|
||||
}
|
||||
else if (this.mod_momentaryOnByDefault) {
|
||||
this.controlType = ControlType.MomentaryOnByDefault;
|
||||
} else if (this.mod_momentaryOffByDefault) {
|
||||
this.controlType = ControlType.Momentary;
|
||||
@@ -604,6 +610,7 @@ deserialize(input: any): UiControl {
|
||||
integer_property: boolean = false;
|
||||
mod_momentaryOffByDefault: boolean = false;
|
||||
mod_momentaryOnByDefault: boolean = false;
|
||||
pipedal_graphicEq: boolean = false;
|
||||
enumeration_property: boolean = false;
|
||||
trigger_property: boolean = false;
|
||||
not_on_gui: boolean = false;
|
||||
@@ -647,6 +654,9 @@ deserialize(input: any): UiControl {
|
||||
isAbToggle(): boolean {
|
||||
return this.controlType === ControlType.ABSwitch;
|
||||
}
|
||||
isGraphicEq() : boolean {
|
||||
return this.controlType === ControlType.GraphicEq;
|
||||
}
|
||||
isSelect(): boolean {
|
||||
return this.controlType === ControlType.Select;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ import ControlTooltip from './ControlTooltip';
|
||||
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
|
||||
import StopIcon from '@mui/icons-material/Stop';
|
||||
import FiberManualRecordIcon from '@mui/icons-material/FiberManualRecord';
|
||||
import GraphicEqCtl, { UpdateGraphicEqPath } from './GraphicEqCtl';
|
||||
|
||||
const MIN_ANGLE = -135;
|
||||
const MAX_ANGLE = 135;
|
||||
@@ -59,6 +60,21 @@ const ULTRA_FINE_RANGE_SCALE = RANGE_SCALE * 50; // 12000 pixels to move from 0
|
||||
export const StandardItemSize = { width: 80, height: 140 }
|
||||
|
||||
|
||||
function preventNextClickAfterDrag() {
|
||||
// the broswer fires a click event when the pointer goes up
|
||||
// on ANY element under the mouse. Prevent this click event
|
||||
// (and any other click event) from happening for 100ms
|
||||
// after the drag stops.
|
||||
let clickHandler = (e: MouseEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
};
|
||||
document.addEventListener('click',clickHandler,true);
|
||||
window.setTimeout(() => {
|
||||
document.removeEventListener('click',clickHandler,true);
|
||||
},100);
|
||||
}
|
||||
|
||||
function androidEmoji(text: string) {
|
||||
// android chrome doesn't support these characters properly.
|
||||
if (text === "⏹") {
|
||||
@@ -67,9 +83,8 @@ function androidEmoji(text: string) {
|
||||
if (text === "⏺") {
|
||||
return (<FiberManualRecordIcon fontSize={"medium"} />)
|
||||
}
|
||||
if (text === "⏵")
|
||||
{
|
||||
return (<PlayArrowIcon fontSize={"medium"}/>);
|
||||
if (text === "⏵") {
|
||||
return (<PlayArrowIcon fontSize={"medium"} />);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
@@ -129,6 +144,7 @@ export interface PluginControlProps extends WithStyles<typeof pluginControlStyle
|
||||
}
|
||||
type PluginControlState = {
|
||||
error: boolean;
|
||||
editFocused: boolean;
|
||||
};
|
||||
|
||||
const PluginControl =
|
||||
@@ -137,6 +153,7 @@ const PluginControl =
|
||||
|
||||
frameRef: React.RefObject<HTMLDivElement | null>;
|
||||
imgRef: React.RefObject<SVGSVGElement | null>;
|
||||
graphicEqControlRef: React.RefObject<SVGSVGElement | null>;
|
||||
inputRef: React.RefObject<HTMLInputElement | null>;
|
||||
selectRef: React.RefObject<HTMLSelectElement | null>;
|
||||
|
||||
@@ -148,10 +165,12 @@ const PluginControl =
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
error: false
|
||||
error: false,
|
||||
editFocused: false
|
||||
};
|
||||
this.model = PiPedalModelFactory.getInstance();
|
||||
this.imgRef = React.createRef();
|
||||
this.graphicEqControlRef = React.createRef();
|
||||
this.inputRef = React.createRef();
|
||||
this.selectRef = React.createRef();
|
||||
this.displayValueRef = React.createRef();
|
||||
@@ -195,16 +214,19 @@ const PluginControl =
|
||||
inputChanged: boolean = false;
|
||||
|
||||
onInputLostFocus(event: any): void {
|
||||
this.setState({editFocused: false});
|
||||
if (this.inputChanged) // validation requried?
|
||||
{
|
||||
this.inputChanged = false;
|
||||
this.validateInput(event, true);
|
||||
|
||||
}
|
||||
this.displayValueRef.current!.style.display = "block";
|
||||
|
||||
//this.displayValueRef.current!.style.display = "block";
|
||||
}
|
||||
onInputFocus(event: SyntheticEvent): void {
|
||||
this.displayValueRef.current!.style.display = "none";
|
||||
//this.displayValueRef.current!.style.display = "none";
|
||||
this.setState({editFocused: true});
|
||||
if (Utility.hasIMEKeyboard()) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
@@ -273,6 +295,7 @@ const PluginControl =
|
||||
|
||||
onDrag(e: SyntheticEvent) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
isValidPointer(e: PointerEvent<SVGSVGElement>): boolean {
|
||||
@@ -333,9 +356,19 @@ const PluginControl =
|
||||
if (!this.mouseDown && this.isValidPointer(e)) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (document.activeElement)
|
||||
{
|
||||
let e = document.activeElement as any;
|
||||
if (e.blur)
|
||||
{
|
||||
e.blur();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isTouchDevice()) {
|
||||
if (this.props.uiControl?.isDial() ?? false) {
|
||||
if (this.props.uiControl
|
||||
&& (this.props.uiControl.isDial() || this.props.uiControl.isGraphicEq())
|
||||
) {
|
||||
this.isTap = false;
|
||||
this.showZoomedControl();
|
||||
return;
|
||||
@@ -390,7 +423,9 @@ const PluginControl =
|
||||
|
||||
onPointerLostCapture(e: PointerEvent<SVGSVGElement>) {
|
||||
if (this.isCapturedPointer(e)) {
|
||||
--this.pointersDown;
|
||||
if (this.pointersDown !== 0) {
|
||||
--this.pointersDown;
|
||||
}
|
||||
this.isTap = false;
|
||||
|
||||
|
||||
@@ -438,7 +473,7 @@ const PluginControl =
|
||||
onPointerDoubleTap() {
|
||||
let uiControl = this.props.uiControl;
|
||||
if (uiControl) {
|
||||
if (uiControl.isDial()) {
|
||||
if (uiControl.isDial() || uiControl.isGraphicEq()) {
|
||||
this.resetToDefaultValue(uiControl);
|
||||
}
|
||||
}
|
||||
@@ -457,10 +492,14 @@ const PluginControl =
|
||||
onPointerUp(e: PointerEvent<SVGSVGElement>) {
|
||||
|
||||
if (this.isCapturedPointer(e)) {
|
||||
--this.pointersDown;
|
||||
|
||||
if (this.pointersDown !== 0)
|
||||
{
|
||||
--this.pointersDown;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
let dRange = this.updateRange(e)
|
||||
this.previewRange(dRange, true);
|
||||
|
||||
@@ -471,9 +510,15 @@ const PluginControl =
|
||||
this.onPointerTap();
|
||||
}
|
||||
}
|
||||
// prevent click from firing on other elements
|
||||
// when the pointer goes up0.
|
||||
preventNextClickAfterDrag();
|
||||
|
||||
} else {
|
||||
--this.pointersDown;
|
||||
if (this.pointersDown !== 0)
|
||||
{
|
||||
--this.pointersDown;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -518,7 +563,7 @@ const PluginControl =
|
||||
this.isTap = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
handleButtonMouseLeave(buttonStyle: ButtonStyle) {
|
||||
}
|
||||
@@ -527,10 +572,10 @@ const PluginControl =
|
||||
if (uiControl) {
|
||||
switch (buttonStyle) {
|
||||
case ButtonStyle.Momentary:
|
||||
this.model.setPedalboardControl(this.props.instanceId, uiControl.symbol,uiControl.max_value);
|
||||
this.model.setPedalboardControl(this.props.instanceId, uiControl.symbol, uiControl.max_value);
|
||||
break;
|
||||
case ButtonStyle.MomentaryOnByDefault:
|
||||
this.model.setPedalboardControl(this.props.instanceId, uiControl.symbol,uiControl.min_value);
|
||||
this.model.setPedalboardControl(this.props.instanceId, uiControl.symbol, uiControl.min_value);
|
||||
break;
|
||||
case ButtonStyle.Trigger:
|
||||
{
|
||||
@@ -539,7 +584,7 @@ const PluginControl =
|
||||
value = uiControl.min_value;
|
||||
}
|
||||
this.model.sendPedalboardControlTrigger(this.props.instanceId, uiControl.symbol, value);
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -550,10 +595,10 @@ const PluginControl =
|
||||
if (uiControl) {
|
||||
switch (buttonStyle) {
|
||||
case ButtonStyle.Momentary:
|
||||
this.model.setPedalboardControl(this.props.instanceId, uiControl.symbol,uiControl.min_value);
|
||||
this.model.setPedalboardControl(this.props.instanceId, uiControl.symbol, uiControl.min_value);
|
||||
break;
|
||||
case ButtonStyle.MomentaryOnByDefault:
|
||||
this.model.setPedalboardControl(this.props.instanceId, uiControl.symbol,uiControl.max_value);
|
||||
this.model.setPedalboardControl(this.props.instanceId, uiControl.symbol, uiControl.max_value);
|
||||
break;
|
||||
case ButtonStyle.Trigger:
|
||||
{
|
||||
@@ -567,14 +612,22 @@ const PluginControl =
|
||||
let range = this.valueToRange(value);
|
||||
value = this.rangeToValue(range);
|
||||
|
||||
let transform = this.rangeToRotationTransform(range);
|
||||
if (this.mouseDown && !commitValue) {
|
||||
transform += " scale(1.5, 1.5)";
|
||||
}
|
||||
let imgElement = this.imgRef.current
|
||||
if (imgElement) {
|
||||
if (imgElement.style) {
|
||||
imgElement.style.transform = transform;
|
||||
if (this.props.uiControl?.isGraphicEq()) {
|
||||
let imgElement = this.imgRef.current
|
||||
if (imgElement) {
|
||||
UpdateGraphicEqPath(imgElement, range);
|
||||
}
|
||||
} else {
|
||||
|
||||
let transform = this.rangeToRotationTransform(range);
|
||||
if (this.mouseDown && !commitValue) {
|
||||
transform += " scale(1.5, 1.5)";
|
||||
}
|
||||
if (imgElement.style) {
|
||||
imgElement.style.transform = transform;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (commitValue) {
|
||||
@@ -594,10 +647,18 @@ const PluginControl =
|
||||
// apply value quantization and clipping.
|
||||
range = this.valueToRange(value);
|
||||
|
||||
let imgElement = this.imgRef.current
|
||||
if (imgElement) {
|
||||
if (imgElement.style) {
|
||||
imgElement.style.transform = this.rangeToRotationTransform(range);
|
||||
if (this.props.uiControl?.isGraphicEq()) {
|
||||
let imgElement = this.imgRef.current
|
||||
if (imgElement) {
|
||||
UpdateGraphicEqPath(imgElement, range);
|
||||
}
|
||||
|
||||
} else {
|
||||
let imgElement = this.imgRef.current
|
||||
if (imgElement) {
|
||||
if (imgElement.style) {
|
||||
imgElement.style.transform = this.rangeToRotationTransform(range);
|
||||
}
|
||||
}
|
||||
}
|
||||
let inputElement = this.inputRef.current;
|
||||
@@ -779,6 +840,16 @@ const PluginControl =
|
||||
return "rotate(" + angle + "deg)";
|
||||
}
|
||||
|
||||
getEqPosition(): number {
|
||||
let range = 0;
|
||||
let uiControl = this.props.uiControl;
|
||||
if (uiControl) {
|
||||
let value = this.props.value;
|
||||
range = this.valueToRange(value);
|
||||
}
|
||||
return range;
|
||||
|
||||
}
|
||||
getRotationTransform(): string {
|
||||
let range = 0;
|
||||
let uiControl = this.props.uiControl;
|
||||
@@ -812,6 +883,8 @@ const PluginControl =
|
||||
|
||||
let isButton = false;
|
||||
let buttonStyle: ButtonStyle = ButtonStyle.None;
|
||||
let isGraphicEq = control.isGraphicEq();
|
||||
|
||||
if (control.isTrigger()) {
|
||||
isButton = true;
|
||||
buttonStyle = ButtonStyle.Trigger;
|
||||
@@ -833,6 +906,9 @@ const PluginControl =
|
||||
if (isButton) {
|
||||
item_width = undefined;
|
||||
}
|
||||
if (isGraphicEq) {
|
||||
item_width = 58;
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
@@ -862,27 +938,29 @@ const PluginControl =
|
||||
(
|
||||
control.name.length !== 1 ? (
|
||||
<Button variant="contained" color="primary" size="small"
|
||||
onMouseDown={
|
||||
(evt) => { this.handleButtonMouseDown(buttonStyle); }
|
||||
}
|
||||
onMouseUp={
|
||||
(evt) => { this.handleButtonMouseUp(buttonStyle); }
|
||||
}
|
||||
onTouchStart={
|
||||
(evt) => { evt.preventDefault();
|
||||
this.handleButtonMouseDown(buttonStyle); }
|
||||
}
|
||||
onTouchEnd={
|
||||
(evt) => {
|
||||
evt.preventDefault();
|
||||
this.handleButtonMouseUp(buttonStyle);
|
||||
onMouseDown={
|
||||
(evt) => { this.handleButtonMouseDown(buttonStyle); }
|
||||
}
|
||||
}
|
||||
onMouseLeave={(
|
||||
(evet) => { this.handleButtonMouseLeave(buttonStyle); }
|
||||
)}
|
||||
onMouseUp={
|
||||
(evt) => { this.handleButtonMouseUp(buttonStyle); }
|
||||
}
|
||||
onTouchStart={
|
||||
(evt) => {
|
||||
evt.preventDefault();
|
||||
this.handleButtonMouseDown(buttonStyle);
|
||||
}
|
||||
}
|
||||
onTouchEnd={
|
||||
(evt) => {
|
||||
evt.preventDefault();
|
||||
this.handleButtonMouseUp(buttonStyle);
|
||||
}
|
||||
}
|
||||
onMouseLeave={(
|
||||
(evet) => { this.handleButtonMouseLeave(buttonStyle); }
|
||||
)}
|
||||
|
||||
style={{
|
||||
style={{
|
||||
textTransform: "none",
|
||||
background: (isDarkMode() ? "#6750A4" : undefined),
|
||||
marginLeft: 8, marginRight: 8, minWidth: 60,
|
||||
@@ -903,12 +981,14 @@ const PluginControl =
|
||||
(evt) => { this.handleButtonMouseUp(buttonStyle); }
|
||||
}
|
||||
onTouchStart={
|
||||
(evt) => { evt.preventDefault();
|
||||
this.handleButtonMouseDown(buttonStyle); }
|
||||
(evt) => {
|
||||
evt.preventDefault();
|
||||
this.handleButtonMouseDown(buttonStyle);
|
||||
}
|
||||
}
|
||||
onTouchEnd={
|
||||
(evt) => {
|
||||
evt.preventDefault();
|
||||
evt.preventDefault();
|
||||
this.handleButtonMouseUp(buttonStyle);
|
||||
}
|
||||
}
|
||||
@@ -935,22 +1015,41 @@ const PluginControl =
|
||||
)
|
||||
)
|
||||
|
||||
: ((isSelect || isAbSwitch || isOnOffSwitch) ? (
|
||||
: (isSelect || isAbSwitch || isOnOffSwitch) ? (
|
||||
this.makeSelect(control, value)
|
||||
) : (
|
||||
<div style={{ flex: "0 1 auto" }}>
|
||||
<DialIcon ref={this.imgRef}
|
||||
style={{
|
||||
overscrollBehavior: "none", touchAction: "none", fill: dialColor,
|
||||
width: 36, height: 36, opacity: DEFAULT_OPACITY, transform: this.getRotationTransform()
|
||||
}}
|
||||
onTouchStart={this.onTouchStart} onTouchMove={this.onTouchMove}
|
||||
onPointerDown={this.onPointerDown} onPointerUp={this.onPointerUp} onPointerMoveCapture={this.onPointerMove} onDrag={this.onDrag}
|
||||
)
|
||||
: (isGraphicEq) ? (
|
||||
<div style={{ flex: "0 1 auto" }}>
|
||||
<GraphicEqCtl
|
||||
imgRef={this.imgRef}
|
||||
position={this.getEqPosition()}
|
||||
dialColor={dialColor}
|
||||
opacity={DEFAULT_OPACITY}
|
||||
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
onTouchStart={this.onTouchStart}
|
||||
onTouchMove={this.onTouchMove}
|
||||
onPointerDown={this.onPointerDown} onPointerUp={this.onPointerUp}
|
||||
onPointerMoveCapture={this.onPointerMove}
|
||||
onDrag={this.onDrag}
|
||||
|
||||
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ flex: "0 1 auto" }}>
|
||||
<DialIcon ref={this.imgRef}
|
||||
style={{
|
||||
overscrollBehavior: "none", touchAction: "none", fill: dialColor,
|
||||
width: 36, height: 36, opacity: DEFAULT_OPACITY, transform: this.getRotationTransform()
|
||||
}}
|
||||
onTouchStart={this.onTouchStart} onTouchMove={this.onTouchMove}
|
||||
onPointerDown={this.onPointerDown} onPointerUp={this.onPointerUp}
|
||||
onPointerMoveCapture={this.onPointerMove}
|
||||
onDrag={this.onDrag}
|
||||
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -969,6 +1068,8 @@ const PluginControl =
|
||||
defaultValue={control.formatShortValue(value)}
|
||||
error={this.state.error}
|
||||
inputProps={{
|
||||
min: this.props.uiControl?.min_value,
|
||||
max: this.props.uiControl?.max_value,
|
||||
'aria-label':
|
||||
control.symbol + " value",
|
||||
style: { textAlign: "center", fontSize: FONT_SIZE },
|
||||
@@ -978,7 +1079,10 @@ const PluginControl =
|
||||
onFocus={this.onInputFocus}
|
||||
|
||||
onKeyPress={this.onInputKeyPress} />
|
||||
<div className={classes.displayValue} ref={this.displayValueRef} onClick={(e) => { this.inputRef.current!.focus(); }} >
|
||||
<div className={classes.displayValue}
|
||||
ref={this.displayValueRef} onClick={(e) => { this.inputRef.current!.focus(); }}
|
||||
style={{display: this.state.editFocused? "none": "block"}}
|
||||
>
|
||||
<Typography noWrap color="inherit" style={{ fontSize: "12.8px", paddingTop: 4, paddingBottom: 6 }}
|
||||
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user