I’m working on a free/open-source VS Code extension that provides a macOS native color picker for working with CSS/HTML/hex colors inside VS Code. The extension opens the color picker via AppleScript like so:
tell current application to choose color default color {0, 0, 0}
It works very well, but the color picker appears without an opacity slider. The ability to change opacity could be very useful to web-developers.
Thank you for the response. I checked that topic prior to posting, but I couldn’t make anything out of it.Those code snippets are way above my AppleScript knowledge. And as far as I could tell, the snippets do not manipulate NSColorList’s instance properties.
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:
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:
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.
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.
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 ?
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.
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.
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.
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: