try destroyDialog ::colorMixer catch()
rollout colorMixer "Color Mixer v0.1" width:500 height:24
(
	spinner spnSteps "Steps: " pos:[33,4] fieldWidth:28 width:50 height:16 range:[3,200,15] type:#integer
	colorPicker cpStartColor pos:[85,2] width:24 height:20 color:[150,0,150]
	subRollout subPanel pos:[108,-2] width:(colorMixer.width - 255) height:27
	colorPicker cpEndColor pos:[colorMixer.width - 152,2] width:24 height:20 color:[255,255,0]
	colorPicker cpResult pos:[colorMixer.width - 130,2] width:30 height:20 color:[197,55,32]
	spinner spnPercent "%" pos:[colorMixer.width - 85,4] width:48 height:16 range:[0,100,50] type:#integer
	button btnRgbHsv "HSV" pos:[colorMixer.width - 34,3] width:30 height:17

	local QtWidgets = python.import "PySide2.QtWidgets"
	local QtCore = python.import "PySide2.QtCore"
	local QtGui = python.import "PySide2.QtGui"
	local gradientSlider

	struct sliderWidget
	(
		public self, gamma = 1.0,
		public connectedPicker, connectedSpinner,
		private startColor = red, endColor = blue, steps = 10,
		private getColorAt = this.getRGBColorAt, indexedGradient,
		private colorMenu = rcMenu colorMenu
		(
			local clr, invGamma

			menuItem miCopyRGB "Copy to Clipboard as RGB"
			menuItem miCopyRGBGamma "Copy to Clipboard as RGB with gamma"
			separator sepVoid1
			menuItem miCopyCMYK "Copy to Clipboard as CMYK"
			menuItem miCopyCMYKGamma "Copy to Clipboard as CMYK with gamma"
			separator sepVoid2
			menuItem miCopyHEX "Copy to Clipboard as HEX"
			menuItem miCopyHEXGamma "Copy to Clipboard as HEX with gamma"

			fn show clr gamma =
			(
				popupMenu colorMenu
				colorMenu.clr = clr
				colorMenu.invGamma = 1 / gamma
			)

			fn gammaCorrect clr gamma =
				255 * [(clr.r / 255.)^gamma, (clr.g / 255.)^gamma, (clr.b / 255.)^gamma] as color

			fn convertColor2HEX clr f:"02X" =
				"#" + formattedPrint (int clr.r) format:f + formattedPrint (int clr.g) format:f + formattedPrint (int clr.b) format:f		

			fn convertColor2CMYK clr =
			(
				local maxClr = amax clr.r clr.g clr.b
				local cmy = (maxClr - clr as point3) / maxClr
				[cmy[1], cmy[2], cmy[3], 1 - maxClr / 255.] * 100
			)

			on miCopyRGB picked do setClipboardText ((clr as point3) as string)
			on miCopyRGBGamma picked do setClipboardText ((gammaCorrect clr invGamma as point3) as string)
			on miCopyCMYK picked do setClipboardText (convertColor2CMYK clr as string)
			on miCopyCMYKGamma picked do setClipboardText (convertColor2CMYK (gammaCorrect clr invGamma) as string)
			on miCopyHEX picked do setClipboardText (convertColor2HEX clr)
			on miCopyHEXGamma picked do setClipboardText (convertColor2HEX (gammaCorrect clr invGamma))
		);,

		public fn update =
		(
			self.repaint()
			this.updateCurrentColor (self.value())
		),

		public fn setNumSteps num =
		(
			this.steps = num
			this.update()
		),

		public fn setColor start: end: =
		(
			if start != unsupplied do startColor = colorMenu.gammaCorrect start gamma
			if end != unsupplied do endColor = colorMenu.gammaCorrect end gamma
			this.update()
		),

		public fn setColorModel model =
		(
			this.getColorAt = if model == #RGB then this.getRGBColorAt else this.getHSVColorAt
			this.update()
		),

		private fn lerp amount minVal maxVal =
			minVal + (maxVal - minVal) * amount,

		private fn qColorToMaxColor qColor =
			color (qColor.red()) (qColor.green()) (qColor.blue()),

		private fn getRGBColorAt param native:off =
		(
			local rgb = lerp param startColor endColor
			QtGui.QColor.fromRgb rgb.r rgb.g rgb.b
		),

		private fn getHSVColorAt param native:off =
		(
			local hue = lerp param (startColor.h * 359 / 255.) (endColor.h * 359 / 255.)
			local sat = lerp param startColor.s endColor.s
			local val = lerp param startColor.v endColor.v

			QtGui.QColor.fromHsv hue sat val
		),

		private fn updateCurrentColor val = if isKindOf indexedGradient PyWrapperBase do
		(
			connectedPicker.color = colorMenu.gammaCorrect (qColorToMaxColor (indexedGradient.pixelColor (steps * val / 100.) 0)) (1 / gamma)
			connectedSpinner.value = val
		),

		private fn mousePressEvent evnt =
			if evnt.button() == QtCore.Qt.RightButton do colorMenu.show cpResult.color this.gamma,

		private fn paintEvent evnt =
		(
			local painter = QtGui.QPainter self
			indexedGradient = QtGui.QImage steps 1 QtGui.QImage.Format_RGB888
			local step = (1 - 1. / steps) / (steps - 1)

			for i = 0. to steps - 1 do
			(
				local param = .5 / steps + step * i
				indexedGradient.setPixelColor i 0 (getColorAt param)
			)

			painter.drawImage (QtCore.QRect 4 4 (self.width() - 8) (self.height() - 8)) indexedGradient
			painter.end()

			QtWidgets.QSlider.paintEvent self evnt
		),

		on create do
		(
			self = QtWidgets.QSlider()
			self.setOrientation QtCore.Qt.Horizontal
			self.setFocusPolicy QtCore.Qt.NoFocus
			self.setStyleSheet "QSlider::groove:horizontal {background:rgba(0,0,0,0); }
				QSlider::handle:horizontal
				{
					width: 1px;
					border-right: 5px solid rgba(0,0,0,.005);
					border-left: 5px solid rgba(0,0,0,.005);
					border-bottom: 5px solid #f0f0f0;
					border-top: 5px solid #f0f0f0;
				}"
			self.valueChanged.connect updateCurrentColor
			self.mousePressEvent = this.mousePressEvent
			self.paintEvent = this.paintEvent
			self.setMaximum 100
			self.setMinimum 0
			self.setValue 50
		)
	)

	fn arePickersColorCorrected =
		isKindOf IDisplayGamma Interface and isProperty IDisplayGamma #affectColorPickers and getProperty IDisplayGamma #affectColorPickers

	on btnRgbHsv pressed do gradientSlider.setColorModel ((btnRgbHsv.text = (if btnRgbHsv.text == "RGB" then "HSV" else "RGB")) as name)
	on cpStartColor changed clr do gradientSlider.setColor start:clr
	on cpEndColor changed clr do gradientSlider.setColor end:clr
	on spnSteps changed steps do gradientSlider.setNumSteps (amin steps subPanel.width)
	on spnPercent changed val do gradientSlider.self.setValue val

	on colorMixer open do
	(
		local panelHWnd = UIAccessor.GetFirstChildWindow colorMixer.subPanel.hwnd[1]
		local panel = QtWidgets.QWidget.find panelHWnd
		local layout = QtWidgets.QHBoxLayout()
		UIAccessor.CloseDialog (UIAccessor.GetFirstChildWindow panelHWnd)

		gradientSlider = sliderWidget connectedPicker:cpResult connectedSpinner:spnPercent gamma:(if arePickersColorCorrected() then (1 / displayGamma) else 1.0)
		cpStartColor.changed cpStartColor.color
		cpEndColor.changed cpEndColor.color
		spnSteps.changed spnSteps.value
		btnRgbHsv.pressed()

		layout.addWidget gradientSlider.self
		panel.setLayout layout
	)

	on colorMixer resized size do
	(
		if size.x < 400 do colorMixer.width = 400
		updateRolloutLayout colorMixer forceUpdate:on
	)
)
createDialog colorMixer lockHeight:on style:#(#style_titlebar, #style_sysmenu, #style_resizing)