First, how do you get the current value of a color well? If I could figure that out, then I’d try to get a hex string myself.
This should end up being a preference for an HTML related app. If I could tell when the color well has changed, then turn the new color into a hex string (placed inside a text field), that would be great.
Edit: I found an old post in Google’s cache, as well as a sub-routine from Apple.
Edit: I found the original post mentioned above. I searched for all sorts of phrases here and got nothing. I searched for users named “Kadis” and his only thread came up almost instantly.
Edit: I can get the color now (the heat is really getting to me today). I still want to know how to tell when the color well/panel has changed. (Kadis didn’t figure it out either.)
Edit: Thanks to everyone that contributed to this.
Say you had a color well named “color_well” in your project, just attach an “on clicked” handler to it and then catch the click:
on clicked the_object
set object_name to the_object's name as Unicode text
if object_name = "color_well" then
set the_color to the_object's color
log the_color
end if
end clicked
Here’s a bit of Obj-C that you can add to your app to easily get the HEX value for the color (save this as a file called “methods.m” and add it to your project):
on clicked the_object
set object_name to the_object's name as Unicode text
if object_name = "color_well" then
set the_color to the_object's color
log the_color
set hex_color to (call method "getHEXValue:" of class "methods" with parameter the_object)
log hex_color
end if
end clicked
You can convert the color to the RGB color space by adding one line to the method I posted and you can go the opposite direction (get the color from a HEX value) by using the following code:
@end[/code]
And then, say you had an editable text field named “HEX_value” with an “on end editing” handler attached, set up your AS like so:
on clicked the_object
set object_name to the_object's name as Unicode text
if object_name = "color_well" then
set the_color to the_object's color
set hex_color to (call method "getHEXValue:" of class "methods" with parameter the_object)
set string value of text field "HEX_value" of super view of the_object to hex_color
end if
end clicked
on end editing the_object
set object_name to the_object's name as Unicode text
if object_name = "HEX_value" then
call method "setHEXValue:toColor:" of class "methods" with parameters {color well "color_well" of super view of the_object, string value of the_object}
end if
end end editing
I’d like the text field to handle short hex strings (e.g., #0F0, short for #00FF00). Is there a better way to do this?
on end editing theObject
if (content of theObject) starts with "#" and length of (get content of theObject) is 4 then
set oldValue to characters 2 through 4 of (get content of theObject)
set newValue to {"#"}
repeat with i from 1 to 3
set newValue's end to (item i of oldValue) & (item i of oldValue)
end repeat
set content of theObject to (newValue as text)
end if
call method "setHEXValue:toColor:" of class "methods" with parameters {color well (theObject's name) of (theObject's super view), string value of theObject}
end end editing
There are probably better ways of validating the input but try this:
on end editing the_object
set object_name to the_object's name as Unicode text
if object_name = "HEX_value" then
set HEX_value to string value of the_object
if (HEX_value's character 1 ≠"#") then set HEX_value to "#" & HEX_value as Unicode text
set HEX_value_count to (count HEX_value)
if (HEX_value_count = 4) then
set new_value to {}
repeat with i from 1 to HEX_value_count
set this_char to HEX_value's character i
set end of new_value to this_char
if this_char ≠"#" then set end of new_value to this_char
end repeat
set HEX_value to (new_value as Unicode text)
else if (HEX_value_count ≠7) then
beep
return (display dialog (""" & HEX_value's text 2 thru -1 & "" is not a valid HEX color value.") buttons {"OK"} default button 1 with icon 2 giving up after 5)
end if
set string value of the_object to HEX_value
call method "setHEXValue:toColor:" of class "methods" with parameters {color well "color_well" of super view of the_object, HEX_value}
end if
end end editing
I’m not sure if the two numbers were #0f0 and #00ff00, but if you’re adding leading zeros, then here’s another way:
display dialog “Enter hex:” default answer “#”
set t to text returned of result
if t begins with “#” then
set t to rest of (text items of t) as string
end if
set t to text -6 thru -1 of (“000000” & t)
I’m not certain if it’s a good idea, but what if I wanted to accept common color names? That is, if a common color name is entered, convert it to a hex value, then change the color well.
kel, the HEX values don’t need leading zeros. As to using color names, try this:
property color_names : {"Black", "Green", "Silver", "Lime", "Gray", "Olive", "White", "Yellow", "Maroon", "Navy", "Red", "Blue", "Purple", "Teal", "Fuchsia", "Aqua"}
property color_values : {"#000000", "#008000", "#C0C0C0", "#00FF00", "#808080", "#808000", "#FFFFFF", "#FFFF00", "#800000", "#000080", "#FF0000", "#0000FF", "#800080", "#008080", "#FF00FF", "#00FFFF"}
on end editing the_object
set object_name to the_object's name as Unicode text
if object_name = "HEX_value" then
set HEX_value to string value of the_object
if HEX_value is in color_names then
repeat with i from 1 to (count color_names)
if item i of color_names = HEX_value then
set HEX_value to item i of color_values
exit repeat
end if
end repeat
end if
if (HEX_value's character 1 ≠"#") then set HEX_value to "#" & HEX_value as Unicode text
set HEX_value_count to (count HEX_value)
if (HEX_value_count = 4) then
set new_value to {}
repeat with i from 1 to HEX_value_count
set this_char to HEX_value's character i
set end of new_value to this_char
if this_char ≠"#" then set end of new_value to this_char
end repeat
set HEX_value to (new_value as Unicode text)
else if (HEX_value_count ≠7) then
beep
return (display dialog (""" & HEX_value's text 2 thru -1 & "" is not a valid HEX color value.") buttons {"OK"} default button 1 with icon 2 giving up after 5)
end if
set string value of the_object to HEX_value
call method "setHEXValue:toColor:" of class "methods" with parameters {color well "color_well" of super view of the_object, HEX_value}
end if
end end editing
I don’t understand this. It seems like Guardian is trying to add leading zeros. From the post Guardian wants to change ofo to ooffoo so I thought it was a typo and Guardian actually wanted to change ffoo to ooffoo adding leading zeroes and forgot the other f. I’m still perpexed.
HTML colors are defined using a hexadecimal notation (HEX) for the combination of red, green, and blue color values (RGB). The values go from 0 to 255 or, in HEX notation, #00 to #FF. If the HEX value of a color contains three component values whose HEX notation contains “even” matched values (like black, for instance, #000000 = RGB(0, 0, 0); white #FFFFFF = RGB(255, 255, 255); or blue #0000FF = RGB(0, 0, 255) but not grey #C0C0C0 = RGB(192, 192, 192)), that is, where each value in the triplet contains the same character twice, it is common to use the 3-character simplified HEX value. So, white would be shorted from #FFFFFF to #FFF and blue to #00F. When converted to an actual HEX color value, you would need to expand each value to the “double value”. The grey example couldn’t be shortened because you’d get either #CCC or #000 which would be expanded to #CCCCCC (RGB(204, 204, 204) = grey, though a different shade) or #000000 (RGB(0, 0, 0) = black) respectively. It isn’t a matter of adding leading zeros but of duplicating each character in the HEX value. I hope I’ve made it clear, but I doubt it. Try a Google search on “hex color rgb”.
What would I need to do if I wanted to leave the text field as is (leaving a short hex string [#00F] or common color name) and still have the color well change?
You could always pass the ‘call method’ the expanded hex string while leaving the text field untouched. And in the inverse ‘call method’ that sets the text field, you could then collapse the hex string back to #xxx, if it needs it.
on expandHex(hexString)
if (count of hexString) is 4 and character 1 of hexString is "#" then
set newHex to {"#"}
repeat with i from 2 to 4
copy {character i of hexString, character i of hexString} to end of newHex
end repeat
set hexString to newHex as text
end if
return hexString
end expandHex
on collapseHex(hexString)
if (count of hexString) is 7 and character 1 of hexString is "#" then
set newHex to {"#"}
set {a, b, c, d, e, f} to (characters 2 thru 7 of hexString)
if a = b and c = d and e = f then
copy {a, c, e} to end of newHex
set hexString to newHex as text
end if
end if
return hexString
end collapseHex
For the color names you would have to do something similar but also check for missing value in case the color name or hex string passed to the below handlers aren’t in the properties. The below handlers also assume two properties listed previously: color_names, and color_values.
colorNameForHex("#008080") --> returns "Teal"
hexForColorName("Teal") --> returns "#008080"
on colorNameForHex(hexString)
try
return item indexOfMatch(color_values, hexString, 1) of color_names
on error
return missing value
end try
end colorNameForHex
on hexForColorName(colorName)
try
return item indexOfMatch(color_names, colorName, 1) of color_values
on error
return missing value
end try
end hexForColorName
on indexOfMatch(checkList, matchItem, instance)
if instance = 0 then -- return every instance
set match to {}
repeat with i from 1 to count of checkList
if item i of checkList = matchItem then copy i to end of match
end repeat
else if instance > 0 then -- pos instance
set match to 0
set found to 0
repeat with i from 1 to count of checkList
if item i of checkList = matchItem then
set found to found + 1
if found = instance then
set match to i
end if
end if
end repeat
else if instance < 0 then -- neg instance
set match to {}
repeat with i from 1 to count of checkList
if item i of checkList = matchItem then copy i to end of match
end repeat
try
set match to item instance of match
on error
set match to 0
end try
end if
return match
end indexOfMatch