feat: add radio element #494
Co-authored-by: jeffycai <caixiaobing@live.cn> Co-authored-by: Hufe921 <huangyunfeihufe@hotmail.com>pr675
parent
2e1403507f
commit
c6d9cffc27
|
After Width: | Height: | Size: 236 B |
@ -0,0 +1,57 @@
|
||||
import { ControlComponent } from '../../../../dataset/enum/Control'
|
||||
import {
|
||||
IControlContext,
|
||||
IControlRuleOption
|
||||
} from '../../../../interface/Control'
|
||||
import { CheckboxControl } from '../checkbox/CheckboxControl'
|
||||
|
||||
export class RadioControl extends CheckboxControl {
|
||||
public setSelect(
|
||||
codes: string[],
|
||||
context: IControlContext = {},
|
||||
options: IControlRuleOption = {}
|
||||
) {
|
||||
// 校验是否可以设置
|
||||
if (!options.isIgnoreDisabledRule && this.control.getIsDisabledControl()) {
|
||||
return
|
||||
}
|
||||
const { control } = this.element
|
||||
const elementList = context.elementList || this.control.getElementList()
|
||||
const { startIndex } = context.range || this.control.getRange()
|
||||
const startElement = elementList[startIndex]
|
||||
// 向左查找
|
||||
let preIndex = startIndex
|
||||
while (preIndex > 0) {
|
||||
const preElement = elementList[preIndex]
|
||||
if (
|
||||
preElement.controlId !== startElement.controlId ||
|
||||
preElement.controlComponent === ControlComponent.PREFIX
|
||||
) {
|
||||
break
|
||||
}
|
||||
if (preElement.controlComponent === ControlComponent.RADIO) {
|
||||
const radio = preElement.radio!
|
||||
radio.value = codes.includes(radio.code!)
|
||||
}
|
||||
preIndex--
|
||||
}
|
||||
// 向右查找
|
||||
let nextIndex = startIndex + 1
|
||||
while (nextIndex < elementList.length) {
|
||||
const nextElement = elementList[nextIndex]
|
||||
if (
|
||||
nextElement.controlId !== startElement.controlId ||
|
||||
nextElement.controlComponent === ControlComponent.POSTFIX
|
||||
) {
|
||||
break
|
||||
}
|
||||
if (nextElement.controlComponent === ControlComponent.RADIO) {
|
||||
const radio = nextElement.radio!
|
||||
radio.value = codes.includes(radio.code!)
|
||||
}
|
||||
nextIndex++
|
||||
}
|
||||
control!.code = codes.join(',')
|
||||
this.control.repaintControl()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
import { DeepRequired } from '../../../interface/Common'
|
||||
import { IEditorOption } from '../../../interface/Editor'
|
||||
import { IElement } from '../../../interface/Element'
|
||||
import { IRowElement } from '../../../interface/Row'
|
||||
import { Draw } from '../Draw'
|
||||
|
||||
export class RadioParticle {
|
||||
private draw: Draw
|
||||
private options: DeepRequired<IEditorOption>
|
||||
|
||||
constructor(draw: Draw) {
|
||||
this.draw = draw
|
||||
this.options = draw.getOptions()
|
||||
}
|
||||
|
||||
public setSelect(element: IElement) {
|
||||
const { radio } = element
|
||||
if (radio) {
|
||||
radio.value = !radio.value
|
||||
} else {
|
||||
element.radio = {
|
||||
value: true
|
||||
}
|
||||
}
|
||||
this.draw.render({
|
||||
isCompute: false,
|
||||
isSetCursor: false
|
||||
})
|
||||
}
|
||||
|
||||
public render(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
element: IRowElement,
|
||||
x: number,
|
||||
y: number
|
||||
) {
|
||||
const {
|
||||
radio: { gap, lineWidth, fillStyle, strokeStyle },
|
||||
scale
|
||||
} = this.options
|
||||
const { metrics, radio } = element
|
||||
// left top 四舍五入避免1像素问题
|
||||
const left = Math.round(x + gap * scale)
|
||||
const top = Math.round(y - metrics.height + lineWidth)
|
||||
const width = metrics.width - gap * 2 * scale
|
||||
const height = metrics.height
|
||||
ctx.save()
|
||||
ctx.beginPath()
|
||||
ctx.translate(0.5, 0.5)
|
||||
// 边框
|
||||
ctx.strokeStyle = radio?.value ? fillStyle : strokeStyle
|
||||
ctx.lineWidth = lineWidth
|
||||
ctx.arc(left + width / 2, top + height / 2, width / 2, 0, Math.PI * 2)
|
||||
ctx.stroke()
|
||||
// 填充选中色
|
||||
if (radio?.value) {
|
||||
ctx.beginPath()
|
||||
ctx.fillStyle = fillStyle
|
||||
ctx.arc(left + width / 2, top + height / 2, width / 3, 0, Math.PI * 2)
|
||||
ctx.fill()
|
||||
}
|
||||
ctx.closePath()
|
||||
ctx.restore()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
import { IRadioOption } from '../../interface/Radio'
|
||||
|
||||
export const defaultRadioOption: Readonly<Required<IRadioOption>> = {
|
||||
width: 14,
|
||||
height: 14,
|
||||
gap: 5,
|
||||
lineWidth: 1,
|
||||
fillStyle: '#5175f4',
|
||||
strokeStyle: '#000000'
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
export interface IRadio {
|
||||
value: boolean | null
|
||||
code?: string
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
export interface IRadioOption {
|
||||
width?: number
|
||||
height?: number
|
||||
gap?: number
|
||||
lineWidth?: number
|
||||
fillStyle?: string
|
||||
strokeStyle?: string
|
||||
}
|
||||
Loading…
Reference in new issue