Opacity slider in "choose color" color picker

Shane, :slight_smile:
thank you.

I removed some problematic peaces from your code, and now I have color picker with opacity slider. I added returning the opacity component too:


use AppleScript version "2.3.1"
use scripting additions
use framework "Foundation"
use framework "AppKit"
global rgbValues

set rgbValues to missing value -- start off empty
set thePicker to current application's NSColorPanel's sharedColorPanel()
thePicker's setShowsAlpha:true -- ADDED
current application's NSColorPanel's setPickerMode:(current application's NSWheelModeColorPanel)

-- set what happens when you click
thePicker's setTarget:me -- message will be sent to this script
thePicker's setAction:"colorPicked:" -- message will call handler of this name

-- show the panel
thePicker's orderFront:me

repeat -- loop until the user clicks
	if rgbValues is not missing value then exit repeat
	delay 0.01
end repeat
return rgbValues

-- gets called when you click
on colorPicked:sender
	-- get the color
	set theColor to sender's |color|()
	-- convert to correct colorspace
	set newColor to theColor's colorUsingColorSpace:(current application's NSColorSpace's deviceRGBColorSpace())
	-- get components
	set theRed to newColor's redComponent()
	set theBlue to newColor's blueComponent()
	set theGreen to newColor's greenComponent()
	set theOpacity to newColor's alphaComponent()
	-- close panel
	sender's orderOut:me
	-- set property
	set rgbValues to {theRed * 255 as integer, theGreen * 255 as integer, theBlue * 255 as integer, theOpacity * 100 as integer}
end colorPicked:

Wow, thanks KniazidisR! But how can I run this script? My Script Editor crashes when I try to run it.

The previous script allows only one of 2 settings at time. Here is enhanced version. It allows the user to select sequentially opacity, then color, or vice versa:


use AppleScript version "2.3.1"
use scripting additions
use framework "Foundation"
use framework "AppKit"
global rgbValues

display dialog "\"Color Picker script\".

  Pick the Opacity first, then pick Color, or vice versa"

set rgbValues to missing value -- start off empty
set thePicker to current application's NSColorPanel's sharedColorPanel()
thePicker's setShowsAlpha:true -- ADDED
current application's NSColorPanel's setPickerMode:(current application's NSWheelModeColorPanel)

-- set what happens when you click
thePicker's setTarget:me -- message will be sent to this script
thePicker's setAction:"colorPicked:" -- message will call handler of this name

set rgbValues to missing value -- start off empty
-- show the panel
thePicker's orderFront:me
repeat -- loop until the user clicks
	if rgbValues is not missing value then exit repeat
	delay 0.01
end repeat
set rgbValues to missing value -- start off empty again
-- show the panel
thePicker's orderFront:me
repeat -- loop until the user clicks
	if rgbValues is not missing value then exit repeat
	delay 0.01
end repeat

return rgbValues

-- gets called when you click
on colorPicked:sender
	-- get the color
	set theColor to sender's |color|()
	-- convert to correct colorspace
	set newColor to theColor's colorUsingColorSpace:(current application's NSColorSpace's deviceRGBColorSpace())
	-- get components
	set theRed to newColor's redComponent()
	set theBlue to newColor's blueComponent()
	set theGreen to newColor's greenComponent()
	set theOpacity to newColor's alphaComponent()
	-- close panel
	sender's orderOut:me
	-- set property
	set rgbValues to {theRed * 255 as integer, theGreen * 255 as integer, theBlue * 255 as integer, theOpacity * 100 as integer}
end colorPicked:

I checked the update and I still don’t see the opacity slider. This is how it normally looks like:

Thanks for helping out!

You should run it on main thread, that is, as application. Or, press shortcut Command+Control+R in the Script Editor. This runs it as script too. In the Script Debugger press shortcut Command+Option+R, then run script.

Thanks, I installed Script Debugger, ran the script successfully, but still the opacity slider is nowhere to be seen.

I’m puzzled.
I tested using ctrl + cmd + R.
I didn’t see the disk with numerous colors.
If I move the slider dedicated to opacity, I’m not allowed to change the color.
If I re-run the script, and trigger the pipette, I may select a color but the dialog disappear without letting me setting the opacity.
If I save the script as an application, I see the disk with numerous colors but once again I can’t set two parameters, the color OR the opacity.
Is it the designed behavior ?

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 4 mai 2020 19:28:41

The OP was right. After creating thePicker need this code line for stability of color picker:

thePicker's setShowsAlpha:true

I will update 2 my scripts. (the changes is marked with ADDED)

Now, what puzzle the Yvan Koenig. When you choose firstly the opacity it remains on second show too .When you choose firstly the color it remains on second show too. The final result is correct values of both values.

This is the desired behavior (demonstrated via Apple Pages):

Simple solution:


use AppleScript version "2.3.1"
use scripting additions
use framework "Foundation"
use framework "AppKit"

set thePicker to current application's NSColorPanel's sharedColorPanel()
thePicker's setShowsAlpha:true -- ADDED
current application's NSColorPanel's setPickerMode:(current application's NSWheelModeColorPanel)

-- show the panel
thePicker's orderFront:me

set appName to name of current application
tell application "System Events" to tell process appName
	repeat until window "Colours" exists
		delay 0.02
	end repeat
	repeat while window "Colours" exists
		delay 0.02
		set theColor to thePicker's |color|()
		-- convert to correct colorspace
		set newColor to theColor's colorUsingColorSpace:(current application's NSColorSpace's deviceRGBColorSpace())
		-- get components
		set theRed to newColor's redComponent()
		set theBlue to newColor's blueComponent()
		set theGreen to newColor's greenComponent()
		set theOpacity to newColor's alphaComponent()
	end repeat
end tell

set rgbValues to {theRed * 255 as integer, theGreen * 255 as integer, theBlue * 255 as integer, theOpacity * 100 as integer}

I apologizes but when I have selected a color, moving the cursor to the slider force the dialog to close.
I must re-run the script to adjust the slider.
Is it really the designed behavior ?

Yvan, :confused:

The previous scripts are just attempts on my part to bring the original from Shane to working condition. Although he is not to blame for this “strange” behavior of the slider. He published his script about registering a mouse click from a user. And very successful.

But, let people read my previous post if you don’t read it yourself. The last script has correct behavior. The last script is already a solution, although there may be something better.

No. Unfortunately, it would be very inconvenient to the end-user.

KniazidisR I wonder if there is a way to combine this piece:

set thePicker to current application's NSColorPanel's sharedColorPanel()
thePicker's setShowsAlpha:true -- ADDED

… with this:

tell current application to choose color default color {0, 0, 0}

Thanks!!

You missed 2 of my posts. I do not know how to help you if you do not read carefully. Combination of choose color and NSColorPanel should be impossible. And, no need, as I think.

I missed nothing.

What I assume is that your code allow to choose the color and its opacity as is done in the messages #1, #7 and #12.
Even the script in message #13 doesn’t allow that.

I didn’t blame this behavior, I asked if it’s the designed one.

It’s just different than the way the dialog behaves in Apple’s applications like Pages or Numbers which allow me to define a color and its opacity without quitting the dedicated dialog.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 4 mai 2020 21:58:42

2 posts missed the OP. I turned to him because you had already confused him. But now I will go to work, and in the morning, of course, the long-awaited solution to the problem from Yvan Koenig awaits me. But even if this happens, I will only be glad. Because there are very few Color Picker programming examples.

KniazidisR,

Thanks for having a go at fixing my script. I posted the pointer late at night, without checking, and didn’t realize that the structure of the panel has changed since then.

This version lets you choose both color and opacity, and doesn’t return the values until the picker is closed. Again, it requires the main thread.

use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"
property rgbValues : missing value
property windowClosed : missing value

set thePicker to current application's NSColorPanel's sharedColorPanel()
current application's NSColorPanel's setPickerMode:(current application's NSWheelModeColorPanel)
thePicker's setShowsAlpha:true
thePicker's setDelegate:me -- so windowWillClose: gets called
set my windowClosed to false

-- set what happens when you click
thePicker's setTarget:me -- message will be sent to this script
thePicker's setAction:"colorPicked:" -- message will call handler of this name

-- show the panel
thePicker's orderFront:me

repeat -- loop until the user clicks
	if windowClosed then exit repeat
	delay 0.1
end repeat
return rgbValues

on windowWillClose:notif
	set my windowClosed to true
end windowWillClose:

-- gets called when you click
on colorPicked:sender
	-- get the color
	set theColor to sender's |color|()
	-- convert to correct colorspace
	set newColor to theColor's colorUsingColorSpace:(current application's NSColorSpace's deviceRGBColorSpace())
	-- get components
	set theRed to newColor's redComponent()
	set theBlue to newColor's blueComponent()
	set theGreen to newColor's greenComponent()
	set theOpacity to newColor's alphaComponent()
	-- set property
	set rgbValues to {theRed * 255 as integer, theGreen * 255 as integer, theBlue * 255 as integer, theOpacity * 100 as integer}
end colorPicked:

Here it is - the best solution to the problem. Thank you, Shane.

(Eight posts of squabbling and insult hurling deleted by moderator.)

Thank you very much to everyone for helping me out. I apologize to KniazidisR for not paying enough attention to the details in your posts.

I’ve released my Visual Studio Code extension today:
https://marketplace.visualstudio.com/items?itemName=dae.vscode-mac-color-picker

However, I’ve decided not to use the suggested script and keep “choose color” because:

  1. “choose color” can have a “default” (starting) color and this is essential to the functionality of my extension.

  1. NSColorPanel invoked via the script posted here feels slightly less responsive to mouse clicks.

  2. NSColorPanel invoked via “choose color” has OK and Cancel buttons, which are very convenient.

I figured out I could strip the alpha channel value before feeding the color to the color picker, and restore it when the user closes the picker. In other words, if the user selects the following:

rgba(255, 255, 255, 0.5)

The extension would save 0.5 and send only {65 535, 65 535, 65 535} to the color picker. When the user hits OK, the extension converts the color back to rgba(…) notation with the previously saved alpha channel value.

I thought it’d be fair to post an update.

Once again, thank you!