diff --git a/FloatingSpace/CircularMenu.js b/FloatingSpace/CircularMenu.js index 97edde860..1de5f77b1 100644 --- a/FloatingSpace/CircularMenu.js +++ b/FloatingSpace/CircularMenu.js @@ -64,6 +64,12 @@ function newCircularMenu () { menuItem.currentRadius = menuItemInitialValue.currentRadius menuItem.angle = menuItemInitialValue.angle + if (menuItem.label === undefined) { + menuItem.type = 'Icon Only' + } else { + menuItem.type = 'Icon & Text' + } + menuItem.initialize(payload) menuItem.container.connectToParent(thisObject.container, false, false, true, true, false, false, true, true) menuItems.push(menuItem) @@ -124,4 +130,3 @@ function newCircularMenu () { } } } - diff --git a/FloatingSpace/CircularMenuItem.js b/FloatingSpace/CircularMenuItem.js index 4aef13239..9140f1f4b 100644 --- a/FloatingSpace/CircularMenuItem.js +++ b/FloatingSpace/CircularMenuItem.js @@ -3,6 +3,7 @@ function newCircularMenuItem () { const MODULE_NAME = 'Circular Menu Iem' let thisObject = { + type: undefined, isDeployed: undefined, iconOn: undefined, iconOff: undefined, @@ -37,7 +38,7 @@ function newCircularMenuItem () { thisObject.container.frame.radius = 0 thisObject.container.frame.position.x = 0 thisObject.container.frame.position.y = 0 - thisObject.container.frame.width = 150 + thisObject.container.frame.width = 0 thisObject.container.frame.height = 30 let isMouseOver = false @@ -50,6 +51,8 @@ function newCircularMenuItem () { let defaultBackgroudColor = UI_COLOR.RED let backgroundColorToUse = UI_COLOR.RED let temporaryStatus = 0 + + const EXTRA_MOUSE_OVER_ICON_SIZE = 2 return thisObject function finalize () { @@ -87,6 +90,12 @@ function newCircularMenuItem () { selfMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) selfMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) + + if (thisObject.type === 'Icon & Text') { + thisObject.container.frame.width = 150 + } else { + thisObject.container.frame.width = 50 + } } function getContainer (point) { @@ -101,11 +110,13 @@ function newCircularMenuItem () { } function physics () { - if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= 0.5) { + const INCREASE_STEP = 0.25 + + if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= INCREASE_STEP) { if (thisObject.currentRadius < thisObject.targetRadius) { - thisObject.currentRadius = thisObject.currentRadius + 0.5 + thisObject.currentRadius = thisObject.currentRadius + INCREASE_STEP } else { - thisObject.currentRadius = thisObject.currentRadius - 0.5 + thisObject.currentRadius = thisObject.currentRadius - INCREASE_STEP } } @@ -162,22 +173,24 @@ function newCircularMenuItem () { function drawBackground () { if (thisObject.container.frame.position.x > 0 && thisObject.isDeployed === true && thisObject.currentRadius >= thisObject.targetRadius) { - let params = { - cornerRadius: 3, - lineWidth: 0.1, - container: thisObject.container, - borderColor: UI_COLOR.DARK, - backgroundColor: backgroundColorToUse, - castShadow: false - } + if (thisObject.type === 'Icon & Text') { + let params = { + cornerRadius: 3, + lineWidth: 0.1, + container: thisObject.container, + borderColor: UI_COLOR.DARK, + backgroundColor: backgroundColorToUse, + castShadow: false + } - if (isMouseOver === true) { - params.opacity = 1 - } else { - params.opacity = 0.8 - } + if (isMouseOver === true) { + params.opacity = 1 + } else { + params.opacity = 0.8 + } - roundedCornersBackground(params) + roundedCornersBackground(params) + } } } @@ -191,26 +204,36 @@ function newCircularMenuItem () { /* Menu Item */ + let iconSize + if (isMouseOver === true) { + iconSize = thisObject.currentRadius + EXTRA_MOUSE_OVER_ICON_SIZE + } else { + iconSize = thisObject.currentRadius + } + if (thisObject.canDrawIcon === true && thisObject.currentRadius > 1 && thisObject.isDeployed === true) { - browserCanvasContext.drawImage(thisObject.icon, menuPosition.x - thisObject.currentRadius, menuPosition.y - thisObject.currentRadius, thisObject.currentRadius * 2, thisObject.currentRadius * 2) + browserCanvasContext.drawImage(thisObject.icon, menuPosition.x - iconSize, menuPosition.y - iconSize, iconSize * 2, iconSize * 2) /* Menu Label */ - let labelPoint - let fontSize = 10 - - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - - if (thisObject.currentRadius >= thisObject.targetRadius) { - labelPoint = { - x: menuPosition.x + thisObject.currentRadius + 10, - y: menuPosition.y + fontSize * FONT_ASPECT_RATIO - } + if (thisObject.type === 'Icon & Text') { + let labelPoint + let fontSize = 10 browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' - browserCanvasContext.fillText(labelToPrint, labelPoint.x, labelPoint.y) + + if (thisObject.currentRadius >= thisObject.targetRadius) { + labelPoint = { + x: menuPosition.x + thisObject.currentRadius + 10, + y: menuPosition.y + fontSize * FONT_ASPECT_RATIO + } + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' + browserCanvasContext.fillText(labelToPrint, labelPoint.x, labelPoint.y) + } } } } } + diff --git a/FloatingSpace/FloatingObject.js b/FloatingSpace/FloatingObject.js index 5137e6d2d..fdaa69dbe 100644 --- a/FloatingSpace/FloatingObject.js +++ b/FloatingSpace/FloatingObject.js @@ -19,6 +19,8 @@ function newFloatingObject () { rawMass: 0, // This is the mass value without zoom. rawRadius: 0, // This is the radius of this floating object without zoom. targetRadius: 0, // This is the target radius of the floating object with zoom applied. It should be animated until reaching this value. + isPinned: undefined, + pinToggle: pinToggle, physics: physics, initializeMass: initializeMass, initializeRadius: initializeRadius, @@ -95,6 +97,15 @@ function newFloatingObject () { } } + function pinToggle () { + if (thisObject.isPinned !== true) { + thisObject.isPinned = true + thisObject.positionLocked = true + } else { + thisObject.isPinned = false + } + } + function physics () { thisObjectPhysics() thisObject.payload.uiObject.physics() @@ -171,7 +182,9 @@ function newFloatingObject () { thisObject.payload.uiObject.container.eventHandler.raiseEvent('onNotFocus') - thisObject.positionLocked = false + if (thisObject.isPinned !== true) { + thisObject.positionLocked = false + } thisObject.isOnFocus = false } } diff --git a/FloatingSpace/StrategyPartConstructor.js b/FloatingSpace/StrategyPartConstructor.js index 1a46ff08f..d85905835 100644 --- a/FloatingSpace/StrategyPartConstructor.js +++ b/FloatingSpace/StrategyPartConstructor.js @@ -39,7 +39,7 @@ function newStrategyPartConstructor () { let strategyPart = newStrategyPart() strategyPart.fitFunction = canvas.floatingSpace.fitIntoVisibleArea strategyPart.isVisibleFunction = canvas.floatingSpace.isThisPointVisible - let menuItemsInitialValues = getMenuItemsInitialValues(strategyPart, payload) + let menuItemsInitialValues = getMenuItemsInitialValues(strategyPart, floatingObject, payload) strategyPart.initialize(payload, menuItemsInitialValues) strategyPart.container.connectToParent(floatingObject.container, false, false, true, true, false, false, true, true, true) payload.uiObject = strategyPart @@ -51,12 +51,24 @@ function newStrategyPartConstructor () { return } - function getMenuItemsInitialValues (strategyPart, payload) { + function getMenuItemsInitialValues (strategyPart, floatingObject, payload) { let menuItemsInitialValues = [] switch (payload.node.type) { case 'Trading System': { strategyPart.imagePath = 'Images/icons/style-01/analysis.png' menuItemsInitialValues = [ + { + action: 'Pin / Unpin', + actionFunction: floatingObject.pinToggle, + label: undefined, + visible: false, + imagePathOn: 'Images/icons/style-01/target.png', + imagePathOff: 'Images/icons/style-01/target.png', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -120 + }, { action: 'Reload Trading System', actionFunction: payload.onMenuItemClick,