Nadro/1919/on drag number fix (#3997)
* fix: fixing on drag number inc/dec massive amount of unit tests * fix: implemented all scenarios for inc/dec formatting * fix: deleting unused code * fix: clearer name * fix: adding commments * A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest) * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest) * A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest) * A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest) * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest) * fix: does this trigger the CI? * A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores) * A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores) --------- Co-authored-by: 49fl <ircsurfer33@gmail.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@ -4,7 +4,7 @@ import { Themes, getSystemTheme } from 'lib/theme'
|
||||
import { useMemo, useRef } from 'react'
|
||||
import { highlightSelectionMatches, searchKeymap } from '@codemirror/search'
|
||||
import { lineHighlightField } from 'editor/highlightextension'
|
||||
import { roundOff } from 'lib/utils'
|
||||
import { onMouseDragMakeANewNumber, onMouseDragRegex } from 'lib/utils'
|
||||
import {
|
||||
lineNumbers,
|
||||
rectangularSelection,
|
||||
@ -139,29 +139,12 @@ export const KclEditorPane = () => {
|
||||
// a rule for a number dragger
|
||||
{
|
||||
// the regexp matching the value
|
||||
regexp: /-?\b\d+\.?\d*\b/g,
|
||||
regexp: onMouseDragRegex,
|
||||
// set cursor to "ew-resize" on hover
|
||||
cursor: 'ew-resize',
|
||||
// change number value based on mouse X movement on drag
|
||||
onDrag: (text, setText, e) => {
|
||||
const multiplier =
|
||||
e.shiftKey && e.metaKey
|
||||
? 0.01
|
||||
: e.metaKey
|
||||
? 0.1
|
||||
: e.shiftKey
|
||||
? 10
|
||||
: 1
|
||||
|
||||
const delta = e.movementX * multiplier
|
||||
|
||||
const newVal = roundOff(
|
||||
Number(text) + delta,
|
||||
multiplier === 0.01 ? 2 : multiplier === 0.1 ? 1 : 0
|
||||
)
|
||||
|
||||
if (isNaN(newVal)) return
|
||||
setText(newVal.toString())
|
||||
onMouseDragMakeANewNumber(text, setText, e)
|
||||
},
|
||||
},
|
||||
],
|
||||
|
File diff suppressed because it is too large
Load Diff
129
src/lib/utils.ts
129
src/lib/utils.ts
@ -53,11 +53,6 @@ export function isOverlap(a: SourceRange, b: SourceRange) {
|
||||
return lastOfFirst >= firstOfSecond
|
||||
}
|
||||
|
||||
export function roundOff(num: number, places: number = 2): number {
|
||||
const x = Math.pow(10, places)
|
||||
return Math.round(num * x) / x
|
||||
}
|
||||
|
||||
export function getLength(a: [number, number], b: [number, number]): number {
|
||||
const x = b[0] - a[0]
|
||||
const y = b[1] - a[1]
|
||||
@ -269,3 +264,127 @@ export function XOR(bool1: boolean, bool2: boolean): boolean {
|
||||
export function getActorNextEvents(snapshot: AnyMachineSnapshot) {
|
||||
return [...new Set([...snapshot._nodes.flatMap((sn) => sn.ownEvents)])]
|
||||
}
|
||||
|
||||
export const onMouseDragRegex = /-?\.?\b\d+\.?\d*\b/g
|
||||
|
||||
export function simulateOnMouseDragMatch(text: string) {
|
||||
return text.match(onMouseDragRegex)
|
||||
}
|
||||
|
||||
export function roundOff(num: number, precision: number = 2): number {
|
||||
const x = Math.pow(10, precision)
|
||||
return Math.round(num * x) / x
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the number as a string has any precision in the decimal places
|
||||
* '1' -> 0
|
||||
* '1.0' -> 1
|
||||
* '1.01' -> 2
|
||||
*/
|
||||
function getPrecision(text: string): number {
|
||||
const wholeFractionSplit = text.split('.')
|
||||
const precision =
|
||||
wholeFractionSplit.length === 2 ? wholeFractionSplit[1].split('').length : 0
|
||||
return precision
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a number string has a leading digit
|
||||
* 0.1 -> yes
|
||||
* -0.1 -> yes
|
||||
* .1 -> no
|
||||
* 10.1 -> no
|
||||
* The text.split('.') should evaluate to ['','<decimals>']
|
||||
*/
|
||||
export function hasLeadingZero(text: string): boolean {
|
||||
const wholeFractionSplit = text.split('.')
|
||||
return wholeFractionSplit.length === 2
|
||||
? wholeFractionSplit[0] === '0' || wholeFractionSplit[0] === '-0'
|
||||
: false
|
||||
}
|
||||
|
||||
export function hasDigitsLeftOfDecimal(text: string): boolean | undefined {
|
||||
const wholeFractionSplit = text.split('.')
|
||||
|
||||
if (wholeFractionSplit.length === 2) {
|
||||
const wholeNumber = wholeFractionSplit[0]
|
||||
|
||||
if (wholeNumber.length === 0) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if (wholeFractionSplit.length === 1) {
|
||||
return true
|
||||
}
|
||||
|
||||
// What if someone passes in 1..2.3.1...1.1.43
|
||||
return undefined
|
||||
}
|
||||
|
||||
export function onDragNumberCalculation(text: string, e: MouseEvent) {
|
||||
const multiplier =
|
||||
e.shiftKey && e.metaKey ? 0.01 : e.metaKey ? 0.1 : e.shiftKey ? 10 : 1
|
||||
|
||||
const delta = e.movementX * multiplier
|
||||
const hasPeriod = text.includes('.')
|
||||
const leadsWithZero = hasLeadingZero(text)
|
||||
const addition = Number(text) + delta
|
||||
const positiveAddition = e.movementX > 0
|
||||
const negativeAddition = e.movementX < 0
|
||||
const containsDigitsLeftOfDecimal = hasDigitsLeftOfDecimal(text)
|
||||
let precision = Math.max(
|
||||
getPrecision(text),
|
||||
getPrecision(multiplier.toString())
|
||||
)
|
||||
const newVal = roundOff(addition, precision)
|
||||
|
||||
if (isNaN(newVal)) {
|
||||
return
|
||||
}
|
||||
|
||||
let formattedString = newVal.toString()
|
||||
if (hasPeriod && !formattedString.includes('.')) {
|
||||
// If the original number included a period lets add that back to the output string
|
||||
// e.g. '1.0' add +1 then we get 2, we want to send '2.0' back since the original one had a decimal place
|
||||
formattedString = formattedString.toString() + '.0'
|
||||
}
|
||||
|
||||
/**
|
||||
* Whenever you add two numbers you can always remove the the leading zero the result will make sense
|
||||
* 1 + -0.01 = 0.99, the code would remove the leading 0 to make it .99 but since the number has a
|
||||
* digit left of the decimal to begin with I want to make it 0.99.
|
||||
* negativeAddition with fractional numbers will provide a leading 0.
|
||||
*/
|
||||
const removeZeros =
|
||||
positiveAddition ||
|
||||
(negativeAddition && multiplier < 1 && !containsDigitsLeftOfDecimal)
|
||||
|
||||
/**
|
||||
* If the original value has no leading 0
|
||||
* If if the new updated value has a leading zero
|
||||
* If the math operation means you can actually remove the zero.
|
||||
*/
|
||||
if (!leadsWithZero && hasLeadingZero(formattedString) && removeZeros) {
|
||||
if (formattedString[0] === '-') {
|
||||
return ['-', formattedString.split('.')[1]].join('.')
|
||||
} else {
|
||||
return formattedString.substring(1)
|
||||
}
|
||||
}
|
||||
|
||||
return formattedString
|
||||
}
|
||||
|
||||
export function onMouseDragMakeANewNumber(
|
||||
text: string,
|
||||
setText: (t: string) => void,
|
||||
e: MouseEvent
|
||||
) {
|
||||
const newVal = onDragNumberCalculation(text, e)
|
||||
if (!newVal) return
|
||||
setText(newVal)
|
||||
}
|
||||
|
Reference in New Issue
Block a user