After a little fun last Tuesday around a pink theme for AutoCAD – for which I got at least a few “we should totally do that”s from internal folk in response, so watch this space ;-) – today we’re going to talk more seriously about what’s needed to support the dark theme in your applications.
But before that, a big thanks to Lee Ambrosius, who owns – and does a fantastic job with – AutoCAD’s developer documentation. Lee pointed out the online documentation which helped me create this post. If you’re interested in the work Lee and team has been doing, please check out his blog post on the developer documentation updates in the 2015 release.
So, how best to support the dark theme? Firstly, after the nonsense I spouted last week it’s important to make clear that there’s no shortcut to supporting the dark theme: you will need to convert dialogs and user interface elements – even down to the icon level – to look good in this environment.
Let’s start by looking at CUIx: the simplest way to get this working is to create resource-only DLLs for your icons. If you haven’t done this before, the steps in this thread over on The Swamp are likely to be of help (be sure to heed Owen’s advice at the end – that’s an important step). One DLL should be named as your CUIx file – i.e. MyRibbon.cuix would have MyRibbon.dll containing the dark theme icons – while the other DLL should have the “_light” suffix – i.e. MyRibbon_light.dll.
As the themes change, the appropriate set of icons should be loaded and used for your various CUI-hosted elements without any custom code being needed (check the top-left of the below image to see our ribbon item get a different icon depending on the value of COLORTHEME).
For your custom dialogs it’s going to be a little more tricky: for a modal dialog you should check the COLORTHEME system variable on launch and choose an appropriate theme for it. Unless you’re modifying the sysvar from your code, directly or indirectly, it should be safe enough to assume that it won’t change while your dialog is displayed.
For modeless dialogs you’ll need to work a little harder: a sysvar reactor attached to the COLORTHEME system variable will notify your application when the value changes, at which point you can take appropriate action.
Here’s an example of how you might have a flag in your code that gets set when you application launches (in our case when we run the WTC command) and that gets modified when you the sysvar changes. You’d ideally have this variable notify your UI for an update – perhaps via a dependency variable in WPF, or otherwise sending some kind of refresh notification – but in our case we’re simply checking the flag via the GT command.
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
namespace ThemeWatching
{
public class Commands
{
// Maintain a flag in our code to save checking the sysvar
private bool _isDark = false;
public void CheckTheme()
{
_isDark =
(short)Application.GetSystemVariable("COLORTHEME") == 0;
}
[CommandMethod("WTC")]
public void WatchThemeChanges()
{
// Let's check the theme when we install the event handler
CheckTheme();
// And we'll check again whenever COLORTHEME changes
// (we could toggle, but this way seems safer, and the
// marginal cost difference shouldn't matter during a
// sysvar change)
Application.SystemVariableChanged +=
(s, e) =>
{
if (e.Name == "COLORTHEME" && e.Changed)
{
CheckTheme();
}
};
}
[CommandMethod("GT")]
public void GetTheme()
{
var doc = Application.DocumentManager.MdiActiveDocument;
if (doc == null) return;
doc.Editor.WriteMessage(
"\nCurrent theme this is {0}.", _isDark ? "dark" : "light"
);
}
}
}
If you’re using a UI framework that supports theming – WPF is a great example – then adjusting the look of your custom dialogs will be straightforward. It’ll be more work if you don’t currently use such a framework, but now might be a good time to consider doing so (a number exist for WinForms development, too, so WPF is not the only option if you don’t want to throw away your existing WinForms UI investment). If you have experience to share around your use of UI frameworks that support theming, please do post a comment.
You can, of course, choose to have certain dialogs not adjust according to the theme – there are a number in AutoCAD, the CUI dialog being a prime example – and to then ask your users what’s important to them in terms of UI aesthetics.