mirror of https://github.com/buggins/dlangui.git
fix console build #493
This commit is contained in:
parent
53e53e84ae
commit
d8333126f6
|
@ -9,6 +9,7 @@ module dlangui.graphics.iconprovider;
|
|||
*
|
||||
*/
|
||||
|
||||
import dlangui.core.config;
|
||||
import dlangui.graphics.drawbuf;
|
||||
import dlangui.core.logger;
|
||||
import isfreedesktop;
|
||||
|
@ -138,471 +139,475 @@ class DummyIconProvider : IconProviderBase
|
|||
}
|
||||
}
|
||||
|
||||
version(Windows)
|
||||
{
|
||||
import core.sys.windows.windows;
|
||||
enum SHSTOCKICONID {
|
||||
SIID_DOCNOASSOC = 0,
|
||||
SIID_DOCASSOC = 1,
|
||||
SIID_APPLICATION = 2,
|
||||
SIID_FOLDER = 3,
|
||||
SIID_FOLDEROPEN = 4,
|
||||
SIID_DRIVE525 = 5,
|
||||
SIID_DRIVE35 = 6,
|
||||
SIID_DRIVEREMOVE = 7,
|
||||
SIID_DRIVEFIXED = 8,
|
||||
SIID_DRIVENET = 9,
|
||||
SIID_DRIVENETDISABLED = 10,
|
||||
SIID_DRIVECD = 11,
|
||||
SIID_DRIVERAM = 12,
|
||||
SIID_WORLD = 13,
|
||||
SIID_SERVER = 15,
|
||||
SIID_PRINTER = 16,
|
||||
SIID_MYNETWORK = 17,
|
||||
SIID_FIND = 22,
|
||||
SIID_HELP = 23,
|
||||
SIID_SHARE = 28,
|
||||
SIID_LINK = 29,
|
||||
SIID_SLOWFILE = 30,
|
||||
SIID_RECYCLER = 31,
|
||||
SIID_RECYCLERFULL = 32,
|
||||
SIID_MEDIACDAUDIO = 40,
|
||||
SIID_LOCK = 47,
|
||||
SIID_AUTOLIST = 49,
|
||||
SIID_PRINTERNET = 50,
|
||||
SIID_SERVERSHARE = 51,
|
||||
SIID_PRINTERFAX = 52,
|
||||
SIID_PRINTERFAXNET = 53,
|
||||
SIID_PRINTERFILE = 54,
|
||||
SIID_STACK = 55,
|
||||
SIID_MEDIASVCD = 56,
|
||||
SIID_STUFFEDFOLDER = 57,
|
||||
SIID_DRIVEUNKNOWN = 58,
|
||||
SIID_DRIVEDVD = 59,
|
||||
SIID_MEDIADVD = 60,
|
||||
SIID_MEDIADVDRAM = 61,
|
||||
SIID_MEDIADVDRW = 62,
|
||||
SIID_MEDIADVDR = 63,
|
||||
SIID_MEDIADVDROM = 64,
|
||||
SIID_MEDIACDAUDIOPLUS = 65,
|
||||
SIID_MEDIACDRW = 66,
|
||||
SIID_MEDIACDR = 67,
|
||||
SIID_MEDIACDBURN = 68,
|
||||
SIID_MEDIABLANKCD = 69,
|
||||
SIID_MEDIACDROM = 70,
|
||||
SIID_AUDIOFILES = 71,
|
||||
SIID_IMAGEFILES = 72,
|
||||
SIID_VIDEOFILES = 73,
|
||||
SIID_MIXEDFILES = 74,
|
||||
SIID_FOLDERBACK = 75,
|
||||
SIID_FOLDERFRONT = 76,
|
||||
SIID_SHIELD = 77,
|
||||
SIID_WARNING = 78,
|
||||
SIID_INFO = 79,
|
||||
SIID_ERROR = 80,
|
||||
SIID_KEY = 81,
|
||||
SIID_SOFTWARE = 82,
|
||||
SIID_RENAME = 83,
|
||||
SIID_DELETE = 84,
|
||||
SIID_MEDIAAUDIODVD = 85,
|
||||
SIID_MEDIAMOVIEDVD = 86,
|
||||
SIID_MEDIAENHANCEDCD = 87,
|
||||
SIID_MEDIAENHANCEDDVD = 88,
|
||||
SIID_MEDIAHDDVD = 89,
|
||||
SIID_MEDIABLURAY = 90,
|
||||
SIID_MEDIAVCD = 91,
|
||||
SIID_MEDIADVDPLUSR = 92,
|
||||
SIID_MEDIADVDPLUSRW = 93,
|
||||
SIID_DESKTOPPC = 94,
|
||||
SIID_MOBILEPC = 95,
|
||||
SIID_USERS = 96,
|
||||
SIID_MEDIASMARTMEDIA = 97,
|
||||
SIID_MEDIACOMPACTFLASH = 98,
|
||||
SIID_DEVICECELLPHONE = 99,
|
||||
SIID_DEVICECAMERA = 100,
|
||||
SIID_DEVICEVIDEOCAMERA = 101,
|
||||
SIID_DEVICEAUDIOPLAYER = 102,
|
||||
SIID_NETWORKCONNECT = 103,
|
||||
SIID_INTERNET = 104,
|
||||
SIID_ZIPFILE = 105,
|
||||
SIID_SETTINGS = 106,
|
||||
SIID_DRIVEHDDVD = 132,
|
||||
SIID_DRIVEBD = 133,
|
||||
SIID_MEDIAHDDVDROM = 134,
|
||||
SIID_MEDIAHDDVDR = 135,
|
||||
SIID_MEDIAHDDVDRAM = 136,
|
||||
SIID_MEDIABDROM = 137,
|
||||
SIID_MEDIABDR = 138,
|
||||
SIID_MEDIABDRE = 139,
|
||||
SIID_CLUSTEREDDRIVE = 140,
|
||||
SIID_MAX_ICONS = 175
|
||||
};
|
||||
|
||||
private struct SHSTOCKICONINFO {
|
||||
DWORD cbSize;
|
||||
HICON hIcon;
|
||||
int iSysImageIndex;
|
||||
int iIcon;
|
||||
WCHAR[MAX_PATH] szPath;
|
||||
};
|
||||
|
||||
private extern(Windows) HRESULT _dummy_SHGetStockIconInfo(SHSTOCKICONID siid, UINT uFlags, SHSTOCKICONINFO *psii);
|
||||
|
||||
class WindowsIconProvider : IconProviderBase
|
||||
static if (!BACKEND_CONSOLE) {
|
||||
version(Windows)
|
||||
{
|
||||
this()
|
||||
import core.sys.windows.windows;
|
||||
enum SHSTOCKICONID {
|
||||
SIID_DOCNOASSOC = 0,
|
||||
SIID_DOCASSOC = 1,
|
||||
SIID_APPLICATION = 2,
|
||||
SIID_FOLDER = 3,
|
||||
SIID_FOLDEROPEN = 4,
|
||||
SIID_DRIVE525 = 5,
|
||||
SIID_DRIVE35 = 6,
|
||||
SIID_DRIVEREMOVE = 7,
|
||||
SIID_DRIVEFIXED = 8,
|
||||
SIID_DRIVENET = 9,
|
||||
SIID_DRIVENETDISABLED = 10,
|
||||
SIID_DRIVECD = 11,
|
||||
SIID_DRIVERAM = 12,
|
||||
SIID_WORLD = 13,
|
||||
SIID_SERVER = 15,
|
||||
SIID_PRINTER = 16,
|
||||
SIID_MYNETWORK = 17,
|
||||
SIID_FIND = 22,
|
||||
SIID_HELP = 23,
|
||||
SIID_SHARE = 28,
|
||||
SIID_LINK = 29,
|
||||
SIID_SLOWFILE = 30,
|
||||
SIID_RECYCLER = 31,
|
||||
SIID_RECYCLERFULL = 32,
|
||||
SIID_MEDIACDAUDIO = 40,
|
||||
SIID_LOCK = 47,
|
||||
SIID_AUTOLIST = 49,
|
||||
SIID_PRINTERNET = 50,
|
||||
SIID_SERVERSHARE = 51,
|
||||
SIID_PRINTERFAX = 52,
|
||||
SIID_PRINTERFAXNET = 53,
|
||||
SIID_PRINTERFILE = 54,
|
||||
SIID_STACK = 55,
|
||||
SIID_MEDIASVCD = 56,
|
||||
SIID_STUFFEDFOLDER = 57,
|
||||
SIID_DRIVEUNKNOWN = 58,
|
||||
SIID_DRIVEDVD = 59,
|
||||
SIID_MEDIADVD = 60,
|
||||
SIID_MEDIADVDRAM = 61,
|
||||
SIID_MEDIADVDRW = 62,
|
||||
SIID_MEDIADVDR = 63,
|
||||
SIID_MEDIADVDROM = 64,
|
||||
SIID_MEDIACDAUDIOPLUS = 65,
|
||||
SIID_MEDIACDRW = 66,
|
||||
SIID_MEDIACDR = 67,
|
||||
SIID_MEDIACDBURN = 68,
|
||||
SIID_MEDIABLANKCD = 69,
|
||||
SIID_MEDIACDROM = 70,
|
||||
SIID_AUDIOFILES = 71,
|
||||
SIID_IMAGEFILES = 72,
|
||||
SIID_VIDEOFILES = 73,
|
||||
SIID_MIXEDFILES = 74,
|
||||
SIID_FOLDERBACK = 75,
|
||||
SIID_FOLDERFRONT = 76,
|
||||
SIID_SHIELD = 77,
|
||||
SIID_WARNING = 78,
|
||||
SIID_INFO = 79,
|
||||
SIID_ERROR = 80,
|
||||
SIID_KEY = 81,
|
||||
SIID_SOFTWARE = 82,
|
||||
SIID_RENAME = 83,
|
||||
SIID_DELETE = 84,
|
||||
SIID_MEDIAAUDIODVD = 85,
|
||||
SIID_MEDIAMOVIEDVD = 86,
|
||||
SIID_MEDIAENHANCEDCD = 87,
|
||||
SIID_MEDIAENHANCEDDVD = 88,
|
||||
SIID_MEDIAHDDVD = 89,
|
||||
SIID_MEDIABLURAY = 90,
|
||||
SIID_MEDIAVCD = 91,
|
||||
SIID_MEDIADVDPLUSR = 92,
|
||||
SIID_MEDIADVDPLUSRW = 93,
|
||||
SIID_DESKTOPPC = 94,
|
||||
SIID_MOBILEPC = 95,
|
||||
SIID_USERS = 96,
|
||||
SIID_MEDIASMARTMEDIA = 97,
|
||||
SIID_MEDIACOMPACTFLASH = 98,
|
||||
SIID_DEVICECELLPHONE = 99,
|
||||
SIID_DEVICECAMERA = 100,
|
||||
SIID_DEVICEVIDEOCAMERA = 101,
|
||||
SIID_DEVICEAUDIOPLAYER = 102,
|
||||
SIID_NETWORKCONNECT = 103,
|
||||
SIID_INTERNET = 104,
|
||||
SIID_ZIPFILE = 105,
|
||||
SIID_SETTINGS = 106,
|
||||
SIID_DRIVEHDDVD = 132,
|
||||
SIID_DRIVEBD = 133,
|
||||
SIID_MEDIAHDDVDROM = 134,
|
||||
SIID_MEDIAHDDVDR = 135,
|
||||
SIID_MEDIAHDDVDRAM = 136,
|
||||
SIID_MEDIABDROM = 137,
|
||||
SIID_MEDIABDR = 138,
|
||||
SIID_MEDIABDRE = 139,
|
||||
SIID_CLUSTEREDDRIVE = 140,
|
||||
SIID_MAX_ICONS = 175
|
||||
};
|
||||
|
||||
private struct SHSTOCKICONINFO {
|
||||
DWORD cbSize;
|
||||
HICON hIcon;
|
||||
int iSysImageIndex;
|
||||
int iIcon;
|
||||
WCHAR[MAX_PATH] szPath;
|
||||
};
|
||||
|
||||
private extern(Windows) HRESULT _dummy_SHGetStockIconInfo(SHSTOCKICONID siid, UINT uFlags, SHSTOCKICONINFO *psii);
|
||||
|
||||
class WindowsIconProvider : IconProviderBase
|
||||
{
|
||||
import std.windows.syserror;
|
||||
_shell = wenforce(LoadLibraryA("Shell32"), "Could not load Shell32 library");
|
||||
_SHGetStockIconInfo = cast(typeof(&_dummy_SHGetStockIconInfo))wenforce(GetProcAddress(_shell, "SHGetStockIconInfo"), "Could not load SHGetStockIconInfo");
|
||||
}
|
||||
~this()
|
||||
{
|
||||
if (_shell) {
|
||||
FreeLibrary(_shell);
|
||||
}
|
||||
foreach(ref buf; _cache)
|
||||
this()
|
||||
{
|
||||
buf.clear();
|
||||
import std.windows.syserror;
|
||||
_shell = wenforce(LoadLibraryA("Shell32"), "Could not load Shell32 library");
|
||||
_SHGetStockIconInfo = cast(typeof(&_dummy_SHGetStockIconInfo))wenforce(GetProcAddress(_shell, "SHGetStockIconInfo"), "Could not load SHGetStockIconInfo");
|
||||
}
|
||||
~this()
|
||||
{
|
||||
if (_shell) {
|
||||
FreeLibrary(_shell);
|
||||
}
|
||||
foreach(ref buf; _cache)
|
||||
{
|
||||
buf.clear();
|
||||
}
|
||||
}
|
||||
|
||||
DrawBufRef getIconFromStock(SHSTOCKICONID id)
|
||||
{
|
||||
if (_SHGetStockIconInfo) {
|
||||
auto found = id in _cache;
|
||||
if (found) {
|
||||
return *found;
|
||||
}
|
||||
HICON icon = getStockIcon(id);
|
||||
if (icon) {
|
||||
scope(exit) DestroyIcon(icon);
|
||||
auto image = DrawBufRef(iconToImage(icon));
|
||||
_cache[id] = image;
|
||||
return image;
|
||||
} else {
|
||||
_cache[id] = DrawBufRef(null); // save the fact that the icon was not found
|
||||
}
|
||||
}
|
||||
return DrawBufRef(null);
|
||||
}
|
||||
|
||||
override DrawBufRef getStandardIcon(StandardIcon icon)
|
||||
{
|
||||
if (_SHGetStockIconInfo) {
|
||||
return getIconFromStock(standardIconToStockId(icon));
|
||||
}
|
||||
return DrawBufRef(null);
|
||||
}
|
||||
|
||||
private:
|
||||
SHSTOCKICONID standardIconToStockId(StandardIcon icon) nothrow pure
|
||||
{
|
||||
with(SHSTOCKICONID)
|
||||
final switch(icon) with(StandardIcon)
|
||||
{
|
||||
case document:
|
||||
return SIID_DOCASSOC;
|
||||
case application:
|
||||
return SIID_APPLICATION;
|
||||
case folder:
|
||||
return SIID_FOLDER;
|
||||
case folderOpen:
|
||||
return SIID_FOLDEROPEN;
|
||||
case driveFloppy:
|
||||
return SIID_DRIVE35;
|
||||
case driveRemovable:
|
||||
return SIID_DRIVEREMOVE;
|
||||
case driveFixed:
|
||||
return SIID_DRIVEFIXED;
|
||||
case driveCD:
|
||||
return SIID_DRIVECD;
|
||||
case driveDVD:
|
||||
return SIID_DRIVEDVD;
|
||||
case server:
|
||||
return SIID_SERVER;
|
||||
case printer:
|
||||
return SIID_PRINTER;
|
||||
case find:
|
||||
return SIID_FIND;
|
||||
case help:
|
||||
return SIID_HELP;
|
||||
case sharedItem:
|
||||
return SIID_SHARE;
|
||||
case link:
|
||||
return SIID_LINK;
|
||||
case trashcanEmpty:
|
||||
return SIID_RECYCLER;
|
||||
case trashcanFull:
|
||||
return SIID_RECYCLERFULL;
|
||||
case mediaCDAudio:
|
||||
return SIID_MEDIACDAUDIO;
|
||||
case mediaDVDAudio:
|
||||
return SIID_MEDIAAUDIODVD;
|
||||
case mediaDVD:
|
||||
return SIID_MEDIADVD;
|
||||
case mediaCD:
|
||||
return SIID_MEDIABLANKCD;
|
||||
case fileAudio:
|
||||
return SIID_AUDIOFILES;
|
||||
case fileImage:
|
||||
return SIID_IMAGEFILES;
|
||||
case fileVideo:
|
||||
return SIID_VIDEOFILES;
|
||||
case fileZip:
|
||||
return SIID_ZIPFILE;
|
||||
case fileUnknown:
|
||||
return SIID_DOCNOASSOC;
|
||||
case warning:
|
||||
return SIID_WARNING;
|
||||
case information:
|
||||
return SIID_INFO;
|
||||
case error:
|
||||
return SIID_ERROR;
|
||||
case password:
|
||||
return SIID_KEY;
|
||||
case rename:
|
||||
return SIID_RENAME;
|
||||
case deleteItem:
|
||||
return SIID_DELETE;
|
||||
case computer:
|
||||
return SIID_DESKTOPPC;
|
||||
case laptop:
|
||||
return SIID_MOBILEPC;
|
||||
case users:
|
||||
return SIID_USERS;
|
||||
case deviceCellphone:
|
||||
return SIID_DEVICECELLPHONE;
|
||||
case deviceCamera:
|
||||
return SIID_DEVICECAMERA;
|
||||
case deviceCameraVideo:
|
||||
return SIID_DEVICEVIDEOCAMERA;
|
||||
}
|
||||
}
|
||||
|
||||
HICON getStockIcon(SHSTOCKICONID id)
|
||||
{
|
||||
assert(_SHGetStockIconInfo !is null);
|
||||
enum SHGSI_ICON = 0x000000100;
|
||||
SHSTOCKICONINFO info;
|
||||
info.cbSize = SHSTOCKICONINFO.sizeof;
|
||||
if (_SHGetStockIconInfo(id, SHGSI_ICON, &info) == S_OK) {
|
||||
return info.hIcon;
|
||||
}
|
||||
Log.d("Could not get icon from stock. Id: ", id);
|
||||
return null;
|
||||
}
|
||||
|
||||
ColorDrawBuf iconToImage(HICON hIcon)
|
||||
{
|
||||
BITMAP bm;
|
||||
ICONINFO iconInfo;
|
||||
GetIconInfo(hIcon, &iconInfo);
|
||||
GetObject(iconInfo.hbmColor, BITMAP.sizeof, &bm);
|
||||
const int width = bm.bmWidth;
|
||||
const int height = bm.bmHeight;
|
||||
const int bytesPerScanLine = (width * 3 + 3) & 0xFFFFFFFC;
|
||||
const int size = bytesPerScanLine * height;
|
||||
BITMAPINFO infoheader;
|
||||
infoheader.bmiHeader.biSize = BITMAPINFOHEADER.sizeof;
|
||||
infoheader.bmiHeader.biWidth = width;
|
||||
infoheader.bmiHeader.biHeight = height;
|
||||
infoheader.bmiHeader.biPlanes = 1;
|
||||
infoheader.bmiHeader.biBitCount = 24;
|
||||
infoheader.bmiHeader.biCompression = BI_RGB;
|
||||
infoheader.bmiHeader.biSizeImage = size;
|
||||
|
||||
ubyte[] pixelsIconRGB = new ubyte[size];
|
||||
ubyte[] alphaPixels = new ubyte[size];
|
||||
HDC hDC = CreateCompatibleDC(null);
|
||||
scope(exit) DeleteDC(hDC);
|
||||
|
||||
HBITMAP hBmpOld = cast(HBITMAP)SelectObject(hDC, cast(HGDIOBJ)(iconInfo.hbmColor));
|
||||
if(!GetDIBits(hDC, iconInfo.hbmColor, 0, height, cast(LPVOID) pixelsIconRGB.ptr, &infoheader, DIB_RGB_COLORS))
|
||||
return null;
|
||||
SelectObject(hDC, hBmpOld);
|
||||
|
||||
if(!GetDIBits(hDC, iconInfo.hbmMask, 0,height,cast(LPVOID)alphaPixels.ptr, &infoheader, DIB_RGB_COLORS))
|
||||
return null;
|
||||
|
||||
const int lsSrc = width*3;
|
||||
auto colorDrawBuf = new ColorDrawBuf(width, height);
|
||||
for(int y=0; y<height; y++)
|
||||
{
|
||||
const int linePosSrc = (height-1-y)*lsSrc;
|
||||
auto pixelLine = colorDrawBuf.scanLine(y);
|
||||
for(int x=0; x<width; x++)
|
||||
{
|
||||
const int currentSrcPos = linePosSrc+x*3;
|
||||
// BGR -> ARGB
|
||||
const uint red = pixelsIconRGB[currentSrcPos+2];
|
||||
const uint green = pixelsIconRGB[currentSrcPos+1];
|
||||
const uint blue = pixelsIconRGB[currentSrcPos];
|
||||
const uint alpha = alphaPixels[currentSrcPos];
|
||||
const uint color = (red << 16) | (green << 8) | blue | (alpha << 24);
|
||||
pixelLine[x] = color;
|
||||
}
|
||||
}
|
||||
return colorDrawBuf;
|
||||
}
|
||||
|
||||
DrawBufRef[SHSTOCKICONID] _cache;
|
||||
HANDLE _shell;
|
||||
typeof(&_dummy_SHGetStockIconInfo) _SHGetStockIconInfo;
|
||||
}
|
||||
|
||||
DrawBufRef getIconFromStock(SHSTOCKICONID id)
|
||||
alias WindowsIconProvider NativeIconProvider;
|
||||
} else static if (isFreedesktop) {
|
||||
import icontheme;
|
||||
import std.typecons : tuple;
|
||||
import dlangui.graphics.images;
|
||||
class FreedesktopIconProvider : IconProviderBase
|
||||
{
|
||||
if (_SHGetStockIconInfo) {
|
||||
auto found = id in _cache;
|
||||
this()
|
||||
{
|
||||
_baseIconDirs = baseIconDirs();
|
||||
auto themeName = currentIconThemeName();
|
||||
IconThemeFile iconTheme = openIconTheme(themeName, _baseIconDirs);
|
||||
if (iconTheme) {
|
||||
_iconThemes ~= iconTheme;
|
||||
_iconThemes ~= openBaseThemes(iconTheme, _baseIconDirs);
|
||||
}
|
||||
foreach(theme; _iconThemes) {
|
||||
theme.tryLoadCache();
|
||||
}
|
||||
}
|
||||
|
||||
~this()
|
||||
{
|
||||
foreach(ref buf; _cache)
|
||||
{
|
||||
buf.clear();
|
||||
}
|
||||
}
|
||||
|
||||
DrawBufRef getIconFromTheme(string name, string context = null)
|
||||
{
|
||||
auto found = name in _cache;
|
||||
if (found) {
|
||||
return *found;
|
||||
}
|
||||
HICON icon = getStockIcon(id);
|
||||
if (icon) {
|
||||
scope(exit) DestroyIcon(icon);
|
||||
auto image = DrawBufRef(iconToImage(icon));
|
||||
_cache[id] = image;
|
||||
string iconPath;
|
||||
try {
|
||||
if (context.length) {
|
||||
iconPath = findClosestIcon!(subdir => subdir.context == context)(name, 32, _iconThemes, _baseIconDirs);
|
||||
} else {
|
||||
iconPath = findClosestIcon(name, 32, _iconThemes, _baseIconDirs);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
Log.e("Error while searching for icon", name);
|
||||
Log.e(e);
|
||||
}
|
||||
|
||||
if (iconPath.length) {
|
||||
auto image = DrawBufRef(loadImage(iconPath));
|
||||
_cache[name] = image;
|
||||
return image;
|
||||
} else {
|
||||
_cache[id] = DrawBufRef(null); // save the fact that the icon was not found
|
||||
_cache[name] = DrawBufRef(null);
|
||||
}
|
||||
return DrawBufRef(null);
|
||||
}
|
||||
return DrawBufRef(null);
|
||||
}
|
||||
|
||||
override DrawBufRef getStandardIcon(StandardIcon icon)
|
||||
{
|
||||
if (_SHGetStockIconInfo) {
|
||||
return getIconFromStock(standardIconToStockId(icon));
|
||||
}
|
||||
return DrawBufRef(null);
|
||||
}
|
||||
|
||||
private:
|
||||
SHSTOCKICONID standardIconToStockId(StandardIcon icon) nothrow pure
|
||||
{
|
||||
with(SHSTOCKICONID)
|
||||
final switch(icon) with(StandardIcon)
|
||||
override DrawBufRef getStandardIcon(StandardIcon icon)
|
||||
{
|
||||
case document:
|
||||
return SIID_DOCASSOC;
|
||||
case application:
|
||||
return SIID_APPLICATION;
|
||||
case folder:
|
||||
return SIID_FOLDER;
|
||||
case folderOpen:
|
||||
return SIID_FOLDEROPEN;
|
||||
case driveFloppy:
|
||||
return SIID_DRIVE35;
|
||||
case driveRemovable:
|
||||
return SIID_DRIVEREMOVE;
|
||||
case driveFixed:
|
||||
return SIID_DRIVEFIXED;
|
||||
case driveCD:
|
||||
return SIID_DRIVECD;
|
||||
case driveDVD:
|
||||
return SIID_DRIVEDVD;
|
||||
case server:
|
||||
return SIID_SERVER;
|
||||
case printer:
|
||||
return SIID_PRINTER;
|
||||
case find:
|
||||
return SIID_FIND;
|
||||
case help:
|
||||
return SIID_HELP;
|
||||
case sharedItem:
|
||||
return SIID_SHARE;
|
||||
case link:
|
||||
return SIID_LINK;
|
||||
case trashcanEmpty:
|
||||
return SIID_RECYCLER;
|
||||
case trashcanFull:
|
||||
return SIID_RECYCLERFULL;
|
||||
case mediaCDAudio:
|
||||
return SIID_MEDIACDAUDIO;
|
||||
case mediaDVDAudio:
|
||||
return SIID_MEDIAAUDIODVD;
|
||||
case mediaDVD:
|
||||
return SIID_MEDIADVD;
|
||||
case mediaCD:
|
||||
return SIID_MEDIABLANKCD;
|
||||
case fileAudio:
|
||||
return SIID_AUDIOFILES;
|
||||
case fileImage:
|
||||
return SIID_IMAGEFILES;
|
||||
case fileVideo:
|
||||
return SIID_VIDEOFILES;
|
||||
case fileZip:
|
||||
return SIID_ZIPFILE;
|
||||
case fileUnknown:
|
||||
return SIID_DOCNOASSOC;
|
||||
case warning:
|
||||
return SIID_WARNING;
|
||||
case information:
|
||||
return SIID_INFO;
|
||||
case error:
|
||||
return SIID_ERROR;
|
||||
case password:
|
||||
return SIID_KEY;
|
||||
case rename:
|
||||
return SIID_RENAME;
|
||||
case deleteItem:
|
||||
return SIID_DELETE;
|
||||
case computer:
|
||||
return SIID_DESKTOPPC;
|
||||
case laptop:
|
||||
return SIID_MOBILEPC;
|
||||
case users:
|
||||
return SIID_USERS;
|
||||
case deviceCellphone:
|
||||
return SIID_DEVICECELLPHONE;
|
||||
case deviceCamera:
|
||||
return SIID_DEVICECAMERA;
|
||||
case deviceCameraVideo:
|
||||
return SIID_DEVICEVIDEOCAMERA;
|
||||
auto t = standardIconToNameAndContext(icon);
|
||||
return getIconFromTheme(t[0], t[1]);
|
||||
}
|
||||
}
|
||||
|
||||
HICON getStockIcon(SHSTOCKICONID id)
|
||||
{
|
||||
assert(_SHGetStockIconInfo !is null);
|
||||
enum SHGSI_ICON = 0x000000100;
|
||||
SHSTOCKICONINFO info;
|
||||
info.cbSize = SHSTOCKICONINFO.sizeof;
|
||||
if (_SHGetStockIconInfo(id, SHGSI_ICON, &info) == S_OK) {
|
||||
return info.hIcon;
|
||||
}
|
||||
Log.d("Could not get icon from stock. Id: ", id);
|
||||
return null;
|
||||
}
|
||||
|
||||
ColorDrawBuf iconToImage(HICON hIcon)
|
||||
{
|
||||
BITMAP bm;
|
||||
ICONINFO iconInfo;
|
||||
GetIconInfo(hIcon, &iconInfo);
|
||||
GetObject(iconInfo.hbmColor, BITMAP.sizeof, &bm);
|
||||
const int width = bm.bmWidth;
|
||||
const int height = bm.bmHeight;
|
||||
const int bytesPerScanLine = (width * 3 + 3) & 0xFFFFFFFC;
|
||||
const int size = bytesPerScanLine * height;
|
||||
BITMAPINFO infoheader;
|
||||
infoheader.bmiHeader.biSize = BITMAPINFOHEADER.sizeof;
|
||||
infoheader.bmiHeader.biWidth = width;
|
||||
infoheader.bmiHeader.biHeight = height;
|
||||
infoheader.bmiHeader.biPlanes = 1;
|
||||
infoheader.bmiHeader.biBitCount = 24;
|
||||
infoheader.bmiHeader.biCompression = BI_RGB;
|
||||
infoheader.bmiHeader.biSizeImage = size;
|
||||
|
||||
ubyte[] pixelsIconRGB = new ubyte[size];
|
||||
ubyte[] alphaPixels = new ubyte[size];
|
||||
HDC hDC = CreateCompatibleDC(null);
|
||||
scope(exit) DeleteDC(hDC);
|
||||
|
||||
HBITMAP hBmpOld = cast(HBITMAP)SelectObject(hDC, cast(HGDIOBJ)(iconInfo.hbmColor));
|
||||
if(!GetDIBits(hDC, iconInfo.hbmColor, 0, height, cast(LPVOID) pixelsIconRGB.ptr, &infoheader, DIB_RGB_COLORS))
|
||||
return null;
|
||||
SelectObject(hDC, hBmpOld);
|
||||
|
||||
if(!GetDIBits(hDC, iconInfo.hbmMask, 0,height,cast(LPVOID)alphaPixels.ptr, &infoheader, DIB_RGB_COLORS))
|
||||
return null;
|
||||
|
||||
const int lsSrc = width*3;
|
||||
auto colorDrawBuf = new ColorDrawBuf(width, height);
|
||||
for(int y=0; y<height; y++)
|
||||
private:
|
||||
auto standardIconToNameAndContext(StandardIcon icon) nothrow pure
|
||||
{
|
||||
const int linePosSrc = (height-1-y)*lsSrc;
|
||||
auto pixelLine = colorDrawBuf.scanLine(y);
|
||||
for(int x=0; x<width; x++)
|
||||
final switch(icon) with(StandardIcon)
|
||||
{
|
||||
const int currentSrcPos = linePosSrc+x*3;
|
||||
// BGR -> ARGB
|
||||
const uint red = pixelsIconRGB[currentSrcPos+2];
|
||||
const uint green = pixelsIconRGB[currentSrcPos+1];
|
||||
const uint blue = pixelsIconRGB[currentSrcPos];
|
||||
const uint alpha = alphaPixels[currentSrcPos];
|
||||
const uint color = (red << 16) | (green << 8) | blue | (alpha << 24);
|
||||
pixelLine[x] = color;
|
||||
case document:
|
||||
return tuple("x-office-document", "MimeTypes");
|
||||
case application:
|
||||
return tuple("application-x-executable", "MimeTypes");
|
||||
case folder:
|
||||
return tuple("folder", "Places");
|
||||
case folderOpen:
|
||||
return tuple("folder-open", "Status");
|
||||
case driveFloppy:
|
||||
return tuple("media-floppy", "Devices");
|
||||
case driveRemovable:
|
||||
return tuple("drive-removable-media", "Devices");
|
||||
case driveFixed:
|
||||
return tuple("drive-harddisk", "Devices");
|
||||
case driveCD:
|
||||
return tuple("drive-optical", "Devices");
|
||||
case driveDVD:
|
||||
return tuple("drive-optical", "Devices");
|
||||
case server:
|
||||
return tuple("network-server", "Places");
|
||||
case printer:
|
||||
return tuple("printer", "Devices");
|
||||
case find:
|
||||
return tuple("edit-find", "Actions");
|
||||
case help:
|
||||
return tuple("help-contents", "Actions");
|
||||
case sharedItem:
|
||||
return tuple("emblem-shared", "Emblems");
|
||||
case link:
|
||||
return tuple("emblem-symbolic-link", "Emblems");
|
||||
case trashcanEmpty:
|
||||
return tuple("user-trash", "Places");
|
||||
case trashcanFull:
|
||||
return tuple("user-trash-full", "Status");
|
||||
case mediaCDAudio:
|
||||
return tuple("media-optical-audio", "Devices");
|
||||
case mediaDVDAudio:
|
||||
return tuple("media-optical-audio", "Devices");
|
||||
case mediaDVD:
|
||||
return tuple("media-optical", "Devices");
|
||||
case mediaCD:
|
||||
return tuple("media-optical", "Devices");
|
||||
case fileAudio:
|
||||
return tuple("audio-x-generic", "MimeTypes");
|
||||
case fileImage:
|
||||
return tuple("image-x-generic", "MimeTypes");
|
||||
case fileVideo:
|
||||
return tuple("video-x-generic", "MimeTypes");
|
||||
case fileZip:
|
||||
return tuple("application-zip", "MimeTypes");
|
||||
case fileUnknown:
|
||||
return tuple("unknown", "MimeTypes");
|
||||
case warning:
|
||||
return tuple("dialog-warning", "Status");
|
||||
case information:
|
||||
return tuple("dialog-information", "Status");
|
||||
case error:
|
||||
return tuple("dialog-error", "Status");
|
||||
case password:
|
||||
return tuple("dialog-password", "Status");
|
||||
case rename:
|
||||
return tuple("edit-rename", "Actions");
|
||||
case deleteItem:
|
||||
return tuple("edit-delete", "Actions");
|
||||
case computer:
|
||||
return tuple("computer", "Devices");
|
||||
case laptop:
|
||||
return tuple("computer-laptop", "Devices");
|
||||
case users:
|
||||
return tuple("system-users", "Applications");
|
||||
case deviceCellphone:
|
||||
return tuple("phone", "Devices");
|
||||
case deviceCamera:
|
||||
return tuple("camera-photo", "Devices");
|
||||
case deviceCameraVideo:
|
||||
return tuple("camera-video", "Devices");
|
||||
}
|
||||
}
|
||||
return colorDrawBuf;
|
||||
}
|
||||
|
||||
DrawBufRef[SHSTOCKICONID] _cache;
|
||||
HANDLE _shell;
|
||||
typeof(&_dummy_SHGetStockIconInfo) _SHGetStockIconInfo;
|
||||
DrawBufRef[string] _cache;
|
||||
string[] _baseIconDirs;
|
||||
IconThemeFile[] _iconThemes;
|
||||
}
|
||||
alias FreedesktopIconProvider NativeIconProvider;
|
||||
} else {
|
||||
alias DummyIconProvider NativeIconProvider;
|
||||
}
|
||||
|
||||
alias WindowsIconProvider NativeIconProvider;
|
||||
} else static if (isFreedesktop) {
|
||||
import icontheme;
|
||||
import std.typecons : tuple;
|
||||
import dlangui.graphics.images;
|
||||
class FreedesktopIconProvider : IconProviderBase
|
||||
{
|
||||
this()
|
||||
{
|
||||
_baseIconDirs = baseIconDirs();
|
||||
auto themeName = currentIconThemeName();
|
||||
IconThemeFile iconTheme = openIconTheme(themeName, _baseIconDirs);
|
||||
if (iconTheme) {
|
||||
_iconThemes ~= iconTheme;
|
||||
_iconThemes ~= openBaseThemes(iconTheme, _baseIconDirs);
|
||||
}
|
||||
foreach(theme; _iconThemes) {
|
||||
theme.tryLoadCache();
|
||||
}
|
||||
}
|
||||
|
||||
~this()
|
||||
{
|
||||
foreach(ref buf; _cache)
|
||||
{
|
||||
buf.clear();
|
||||
}
|
||||
}
|
||||
|
||||
DrawBufRef getIconFromTheme(string name, string context = null)
|
||||
{
|
||||
auto found = name in _cache;
|
||||
if (found) {
|
||||
return *found;
|
||||
}
|
||||
string iconPath;
|
||||
try {
|
||||
if (context.length) {
|
||||
iconPath = findClosestIcon!(subdir => subdir.context == context)(name, 32, _iconThemes, _baseIconDirs);
|
||||
} else {
|
||||
iconPath = findClosestIcon(name, 32, _iconThemes, _baseIconDirs);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
Log.e("Error while searching for icon", name);
|
||||
Log.e(e);
|
||||
}
|
||||
|
||||
if (iconPath.length) {
|
||||
auto image = DrawBufRef(loadImage(iconPath));
|
||||
_cache[name] = image;
|
||||
return image;
|
||||
} else {
|
||||
_cache[name] = DrawBufRef(null);
|
||||
}
|
||||
return DrawBufRef(null);
|
||||
}
|
||||
|
||||
override DrawBufRef getStandardIcon(StandardIcon icon)
|
||||
{
|
||||
auto t = standardIconToNameAndContext(icon);
|
||||
return getIconFromTheme(t[0], t[1]);
|
||||
}
|
||||
|
||||
private:
|
||||
auto standardIconToNameAndContext(StandardIcon icon) nothrow pure
|
||||
{
|
||||
final switch(icon) with(StandardIcon)
|
||||
{
|
||||
case document:
|
||||
return tuple("x-office-document", "MimeTypes");
|
||||
case application:
|
||||
return tuple("application-x-executable", "MimeTypes");
|
||||
case folder:
|
||||
return tuple("folder", "Places");
|
||||
case folderOpen:
|
||||
return tuple("folder-open", "Status");
|
||||
case driveFloppy:
|
||||
return tuple("media-floppy", "Devices");
|
||||
case driveRemovable:
|
||||
return tuple("drive-removable-media", "Devices");
|
||||
case driveFixed:
|
||||
return tuple("drive-harddisk", "Devices");
|
||||
case driveCD:
|
||||
return tuple("drive-optical", "Devices");
|
||||
case driveDVD:
|
||||
return tuple("drive-optical", "Devices");
|
||||
case server:
|
||||
return tuple("network-server", "Places");
|
||||
case printer:
|
||||
return tuple("printer", "Devices");
|
||||
case find:
|
||||
return tuple("edit-find", "Actions");
|
||||
case help:
|
||||
return tuple("help-contents", "Actions");
|
||||
case sharedItem:
|
||||
return tuple("emblem-shared", "Emblems");
|
||||
case link:
|
||||
return tuple("emblem-symbolic-link", "Emblems");
|
||||
case trashcanEmpty:
|
||||
return tuple("user-trash", "Places");
|
||||
case trashcanFull:
|
||||
return tuple("user-trash-full", "Status");
|
||||
case mediaCDAudio:
|
||||
return tuple("media-optical-audio", "Devices");
|
||||
case mediaDVDAudio:
|
||||
return tuple("media-optical-audio", "Devices");
|
||||
case mediaDVD:
|
||||
return tuple("media-optical", "Devices");
|
||||
case mediaCD:
|
||||
return tuple("media-optical", "Devices");
|
||||
case fileAudio:
|
||||
return tuple("audio-x-generic", "MimeTypes");
|
||||
case fileImage:
|
||||
return tuple("image-x-generic", "MimeTypes");
|
||||
case fileVideo:
|
||||
return tuple("video-x-generic", "MimeTypes");
|
||||
case fileZip:
|
||||
return tuple("application-zip", "MimeTypes");
|
||||
case fileUnknown:
|
||||
return tuple("unknown", "MimeTypes");
|
||||
case warning:
|
||||
return tuple("dialog-warning", "Status");
|
||||
case information:
|
||||
return tuple("dialog-information", "Status");
|
||||
case error:
|
||||
return tuple("dialog-error", "Status");
|
||||
case password:
|
||||
return tuple("dialog-password", "Status");
|
||||
case rename:
|
||||
return tuple("edit-rename", "Actions");
|
||||
case deleteItem:
|
||||
return tuple("edit-delete", "Actions");
|
||||
case computer:
|
||||
return tuple("computer", "Devices");
|
||||
case laptop:
|
||||
return tuple("computer-laptop", "Devices");
|
||||
case users:
|
||||
return tuple("system-users", "Applications");
|
||||
case deviceCellphone:
|
||||
return tuple("phone", "Devices");
|
||||
case deviceCamera:
|
||||
return tuple("camera-photo", "Devices");
|
||||
case deviceCameraVideo:
|
||||
return tuple("camera-video", "Devices");
|
||||
}
|
||||
}
|
||||
|
||||
DrawBufRef[string] _cache;
|
||||
string[] _baseIconDirs;
|
||||
IconThemeFile[] _iconThemes;
|
||||
}
|
||||
alias FreedesktopIconProvider NativeIconProvider;
|
||||
} else {
|
||||
} else { // !BACKEND_CONSOLE
|
||||
alias DummyIconProvider NativeIconProvider;
|
||||
}
|
||||
|
|
|
@ -598,6 +598,7 @@ class AndroidPlatform : Platform {
|
|||
|
||||
/// handle theme change: e.g. reload some themed resources
|
||||
override void onThemeChanged() {
|
||||
super.onThemeChanged();
|
||||
// override and call dispatchThemeChange for all windows
|
||||
}
|
||||
|
||||
|
|
|
@ -1946,6 +1946,11 @@ class Platform {
|
|||
/// handle theme change: e.g. reload some themed resources
|
||||
void onThemeChanged() {
|
||||
// override and call dispatchThemeChange for all windows
|
||||
drawableCache.clear();
|
||||
static if (!BACKEND_CONSOLE) {
|
||||
imageCache.checkpoint();
|
||||
imageCache.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
/// default icon for new created windows
|
||||
|
|
|
@ -5,6 +5,7 @@ public import dlangui.core.config;
|
|||
static if (BACKEND_CONSOLE):
|
||||
|
||||
import std.stdio;
|
||||
import dlangui.core.logger;
|
||||
|
||||
version(Windows) {
|
||||
import core.sys.windows.winbase;
|
||||
|
|
|
@ -1192,6 +1192,7 @@ class SDLPlatform : Platform {
|
|||
|
||||
/// handle theme change: e.g. reload some themed resources
|
||||
override void onThemeChanged() {
|
||||
super.onThemeChanged();
|
||||
if (currentTheme)
|
||||
currentTheme.onThemeChanged();
|
||||
foreach(w; _windowMap)
|
||||
|
|
|
@ -1136,6 +1136,7 @@ class Win32Platform : Platform {
|
|||
|
||||
/// handle theme change: e.g. reload some themed resources
|
||||
override void onThemeChanged() {
|
||||
super.onThemeChanged();
|
||||
if (currentTheme)
|
||||
currentTheme.onThemeChanged();
|
||||
foreach(w; _windowMap)
|
||||
|
|
|
@ -1817,6 +1817,7 @@ class X11Platform : Platform {
|
|||
|
||||
/// handle theme change: e.g. reload some themed resources
|
||||
override void onThemeChanged() {
|
||||
super.onThemeChanged();
|
||||
foreach(w; _windowMap)
|
||||
w.dispatchThemeChanged();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue