Go Back   WowAce Forums > Official Addon Threads > General AddOns
General AddOns Authors, post your release ready addons here to get feedback or just to let everyone know about it.

Reply
 
Thread Tools
Old 02-13-2009   #1
Phanx
Seal Cub Clubbing Club
 
Phanx's Avatar
 
Join Date: May 2005
Posts: 5,576
Send a message via AIM to Phanx Send a message via MSN to Phanx Send a message via Yahoo to Phanx
Default !ClassColors - change class colors without tainting

Change class colors without breaking the Blizzard UI.

Download from WoWInterface or Curse.

Please post specific bug reports and feature requests in using the ticket tracking systems on either CurseForge or WoWInterface.

General questions, comments, suggestions, and other feedback may be posted in this thread.

The Problem:

Addons like !ReTeal change the RAID_CLASS_COLORS table, which is originally created by Blizzard code. Doing so causes all other Blizzard code which reads from RAID_CLASS_COLORS to become "tainted", and Blizzard's restrictions on "secure" code cause certain parts of the UI to stop working. Some examples of problems caused by tainting RAID_CLASS_COLORS include being unable to view the raid panel while in combat, and being unable to set main tanks and main assists from the right-click menu in the raid panel.

The Solution:

Class Colors solves this problem by not touching RAID_CLASS_COLORS at all. Instead, it creates its own separate table called CUSTOM_CLASS_COLORS. Since this table isn't created by Blizzard code, and isn't used by any Blizzard code, it doesn't taint anything, and its values can be changed as much as you like. However, this does mean that any addons that read colors from RAID_CLASS_COLORS must be updated to read from CUSTOM_CLASS_COLORS instead (if it exists).

Information for Users

In addition to solving the taint problem, Class Colors also provides an in-game UI for changing class colors. It also applies your custom colors to the Blizzard UI in a safe way that doesn't taint it.

To access the configuration UI, type "/classcolors" or open the Blizzard Interface Options window, select the AddOns tab, and select the "Class Colors" entry in the left-hand column.

If you would like more precision for color selection than the Blizzard color picker allows, I highly recommend ColorTools.

Information for Addon Authors

Supporting this system is as easy as checking for the existence of a global table CUSTOM_CLASS_COLORS and reading from it instead of RAID_CLASS_COLORS if it exists.

If your addon creates a local cache of class colors, it is recommended that you also register for a callback when class colors are changed by the user (see API documentation below) and update your color cache when the callback is fired.

Note that your addon should never modify the values of CUSTOM_CLASS_COLORS. The only addon that should ever do that is the one creating that table. There are reasons users might need different colors for a specific addon, and having random addons change global colors is just confusing and annoying for users. The ability to fire callbacks is not exposed in the API intentionally.

As not all users are on systems which load addon folders in alphabetical order, there is no guarantee that !ClassColors will be loaded before your addon naturally. There are two ways you can account for this possibility.
  • Ideally, you should delay using any class colors until the PLAYER_LOGIN event; if this is not possible, you could just build your cache from RAID_CLASS_COLORS if CUSTOM_CLASS_COLORS is not yet available when your addon loads, and then update your cache and register for callbacks on PLAYER_LOGIN.
  • Alternatively, you can just add !ClassColors to your addon's OptionalDeps field, though this is not the recommended solution, as it will prohibit other implementations of CUSTOM_CLASS_COLORS and clutter up your TOC.
Several examples of CUSTOM_CLASS_COLORS support can be found in the README text file inside the addon's folder.

API Documentation

The following methods are defined on the CUSTOM_CLASS_COLORS table. They are defined using a metatable __index, so pairs() can still be used to iterate over CUSTOM_CLASS_COLORS without requiring extra code to filter out function values.

Code:
:RegisterCallback(method[, handler])
Arguments:
  • method - function or string
  • handler - table containing function value 'method' (required if 'method' is a string, ignored if 'method' is a function)
Notes:
  • Registers a function to be called when class colors are changed.
  • If 'method' is a function, that function will be called with no arguments.
  • If 'method' is a string, 'handler' is a table, and 'handler[method]' is a function, 'handler[method]' will be called with 'handler' as the first argument.
  • If the function is already registered, nothing will happen.

Code:
:UnregisterCallback(method[, handler])
Arguments:
  • method - function or string
  • handler - table containing function value 'method' (required if 'method' is a string, ignored if 'method' is a function)
Notes:
  • Removes a function from the callback registry.
  • If the function is not registered, nothing will happen.

Implementation Details

Class Colors is built on a proposed community standard for a global table of alternate class colors that can be freely modified without tainting anything. This means that addons must explicitly support this standard (see below for details). Class Colors is only one possible implementation of this standard. Any implementation must provide the following:
  • Create and populate a global table CUSTOM_CLASS_COLORS with the same keys and value structure as RAID_CLASS_COLORS
  • Define methods :RegisterCallback, and :UnregisterCallback on the CUSTOM_CLASS_COLORS table (see API documentation above), using a metatable __index so that people can still iterate over the table using pairs() without having to work around function values
The following are highly recommended, and generally expected, but won't technically break anything if they aren't provided:
  • Provide a facility by which users may change class colors
  • Store changed class colors between sessions
  • Maintain a registry of functions requesting callbacks when class colors are changed, and call those functions when appropriate (see API documentation above)
  • Apply user-defined class colors to the Blizzard UI

Last edited by Phanx; 12-14-2009 at 02:50 PM.
Phanx is offline   Reply With Quote
Old 02-13-2009   #2
Phanx
Seal Cub Clubbing Club
 
Phanx's Avatar
 
Join Date: May 2005
Posts: 5,576
Send a message via AIM to Phanx Send a message via MSN to Phanx Send a message via Yahoo to Phanx
Default Re: !ClassColors - change class colors without tainting

I've modified all of my local addon copies to use CUSTOM_CLASS_COLORS if it exists instead of RAID_CLASS_COLORS, and things are working great (though I didn't take the time to also add code that should be added to update any visible parts when colors change). Here's a quick example:

Code:
local classColors = { }
for class, color in pairs(CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS) do
     classColors[class] = { color.r, color.g, color.b }
end
if CUSTOM_CLASS_COLORS then
     CUSTOM_CLASS_COLORS:RegisterCallback(function()
          for class, color in pairs(CUSTOM_CLASS_COLORS) do
               classColors[class] = { color.r, color.g, color.b }
          end
          -- update visible addon parts with new colors here!
     end)
end
I've named my addon !ClassColors so that it should (on most systems) load before other addons, for the sake of simplicity. I don't want addons to have to add anything to OptionalDependencies, or to have to delay caching class colors until later in the loading process than they are currently doing it, so this was the best solution I could think of. If anyone has any better suggestions, I'm all ears... er... eyes?

Last edited by Phanx; 02-13-2009 at 10:19 PM.
Phanx is offline   Reply With Quote
Old 02-13-2009   #3
Slakah
Senior Member
 
Slakah's Avatar
 
Join Date: Jul 2007
Posts: 375
Default Re: !ClassColors - change class colors without tainting

First thing I noticed is :IterateClasses() why not just use pairs(CUSTOM_CLASS_COLORS) and put all the callback methods into the __index metatable, so they don't get touched by pairs.

Second it might be nice if the callback would pass the keys which have been changed, in the callback.

Last edited by Slakah; 02-13-2009 at 10:19 PM.
Slakah is offline   Reply With Quote
Old 02-13-2009   #4
Phanx
Seal Cub Clubbing Club
 
Phanx's Avatar
 
Join Date: May 2005
Posts: 5,576
Send a message via AIM to Phanx Send a message via MSN to Phanx Send a message via Yahoo to Phanx
Default Re: !ClassColors - change class colors without tainting

Because I'm lazy and metatables are annoying. I guess I could do that, though...

Edit: Done. Drycoded, will be tested later tonight.

Last edited by Phanx; 02-13-2009 at 10:37 PM.
Phanx is offline   Reply With Quote
Old 02-13-2009   #5
Elsia
Amazing Member
 
Join Date: Dec 2005
Posts: 1,779
Default Re: !ClassColors - change class colors without tainting

Added support of this to Recount, see R987. Looks nice.

Some feedback on the config UI.

1) Add a "reset to blizz defaults button"
2) Make colors take effect immediately when the color picker is closed (OK'd) and get rid of the OK/Cancel pair. Much more intuitive. I actually thought something was broken because I got no change after selecting colors and them showing in the ClassColor config UI but not showing in my addon.

Else very nice!
Elsia is offline   Reply With Quote
Old 02-13-2009   #6
Slakah
Senior Member
 
Slakah's Avatar
 
Join Date: Jul 2007
Posts: 375
Default Re: !ClassColors - change class colors without tainting

Quote:
1) Add a "reset to blizz defaults button"
I'm not certain but I vaguely remember thats what happens when you press the default button in the panel.
Slakah is offline   Reply With Quote
Old 02-13-2009   #7
Elsia
Amazing Member
 
Join Date: Dec 2005
Posts: 1,779
Default Re: !ClassColors - change class colors without tainting

I'm somewhat scared of that button given that people can accidentally default everything :P
Elsia is offline   Reply With Quote
Old 02-13-2009   #8
Phanx
Seal Cub Clubbing Club
 
Phanx's Avatar
 
Join Date: May 2005
Posts: 5,576
Send a message via AIM to Phanx Send a message via MSN to Phanx Send a message via Yahoo to Phanx
Default Re: !ClassColors - change class colors without tainting

1) The "Defaults" button in the lower left corner of the Interface Options window should work as intended. I guess I can add an addon-specific button though...

2) I guess I can do that, though if more addons used the "Okay" and "Cancel" buttons properly it would be more intuitive.

Last edited by Phanx; 02-14-2009 at 12:03 AM.
Phanx is offline   Reply With Quote
Old 02-13-2009   #9
Xinhuan
Asian Sheep Lover
 
Xinhuan's Avatar
 
Join Date: Aug 2007
Location: Singapore
Posts: 3,556
Default Re: !ClassColors - change class colors without tainting

Quote:
Originally Posted by Phanx View Post
1) The "Defaults" button in the lower left corner of the Interface Options window should work as intended.
What is not intuitive is whether that Defaults button resets the default on ALL options on ALL addons and default UI options, or just the page you are browsing, because currently, the OK/Cancel buttons applies changes on a global-all-options basis.
__________________
Author/Maintainer of Postal, Omen3, GemHelper, BankItems, WoWEquip, GatherMate, Routes, HandyNotes and some others.
Xinhuan is offline   Reply With Quote
Old 02-14-2009   #10
Elsia
Amazing Member
 
Join Date: Dec 2005
Posts: 1,779
Default Re: !ClassColors - change class colors without tainting

Seriously that default button lower left is a hazard and an accidental "I just wanted to reset class colors and now my whole UI is reset" or ten.

Just put a button within the addon area that just defaults the colors and there is far less chance for accidents like the above...

I'd hate to have to tell people asking about this to "click lower left default but be very careful to not click the left most button so not all addons are reset!".

The lower left default button isn't the best GUI design from a HCI perspective, it's neither slip safe (no undo if you messed up), context related nor in the right visual area and it has potentially far reaching consequences... :P

But that's just me

On the OK/Cancel, Recount used to work that way. I had a flood of "why do options not work" until i changed it to options take effect as visible which is more intuitive and removes the need for any button outside the color picker.
Elsia is offline   Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT. The time now is 04:09 PM.