ImageList.cpp. #1

  • //
  • guest/
  • YourUncleBob/
  • p4win/
  • main/
  • gui/
  • ImageList.cpp.
  • View
  • Commits
  • Open Download .zip Download (9 KB)
#include "stdafx.h"
//#include "p4win.h"
#include "ImageList.h"
#include "P4Image.h"
#include "resource.h"

///////////////////////////////////////////////////////////////////////////
// CP4ToolBarImageList 

bool CP4WinToolBarImageList::Create()
{
	return CP4ToolBarImageList::Create(18, 16, 
		IDB_TOOLBAR4, IDB_BITMAPDIS, IDB_TOOLBAR32,
		RGB(255, 0, 255));
}

///////////////////////////////////////////////////////////////////////////
// CP4ViewIconsImageList 

// SrcImages represents the actual images in TreeIcons?.bmp
// it must be kept in sync with the bitmap.

// note: for built up images, base images are mixed in with badges, 
// but must precede badge images so that they will be drawn first 
// and badges drawn on top of them

enum SrcImages
{
	SI_LAST_SIMPLE = 19,

	// base images
	SI_CLIENT,
	SI_USER,
	SI_GHOST,
	SI_TEXT,
	SI_BINARY,

	// badge images
	SI_RED_DOC_BORDER,
	SI_YOUR_EDIT,
	SI_YOUR_DELETE,
	SI_YOUR_ADD,
	SI_THEIR_ADD,
	SI_THEIR_EDIT,
	SI_THEIR_DELETE,
	SI_YOUR_LOCK,
	SI_THEIR_LOCK,
	SI_SYNCED,
	SI_NOT_SYNCED,
	SI_CUR,
	SI_DEF,
	SI_BLANK,

	// more simple images
	SI_OPENFOLDER,
};

// convert from CUSB enum flag to image index
static int CUSBToImage(int badge)
{
	static int map[][2] =
	{
		{CP4ViewImageList::CUSB_USER, SI_USER},
		{CP4ViewImageList::CUSB_CLIENT, SI_CLIENT},
		{CP4ViewImageList::CUSB_DEF,	SI_DEF},
		{CP4ViewImageList::CUSB_CUR, SI_CUR},
		{-1,-1}
	};

	for(int i = 0; map[i][0] != -1; i++)
		if(map[i][0] == badge)
			return map[i][1];
	ASSERT(0);
	return 0;
}

// convert from FSB enum flag to image index
static int FSBToImage(int badge)
{
	static int map[][2] =
	{
		{CP4ViewImageList::FSB_GHOST,		SI_GHOST},
		{CP4ViewImageList::FSB_TEXT,		SI_TEXT},
		{CP4ViewImageList::FSB_BINARY,		SI_BINARY},
		{CP4ViewImageList::FSB_YOUR_EDIT,	SI_YOUR_EDIT},
		{CP4ViewImageList::FSB_YOUR_DELETE,	SI_YOUR_DELETE},
		{CP4ViewImageList::FSB_YOUR_ADD,	SI_YOUR_ADD},
		{CP4ViewImageList::FSB_THEIR_EDIT,	SI_THEIR_EDIT},
		{CP4ViewImageList::FSB_THEIR_DELETE,SI_THEIR_DELETE},
		{CP4ViewImageList::FSB_THEIR_ADD,	SI_THEIR_ADD},
		{CP4ViewImageList::FSB_YOUR_LOCK,	SI_YOUR_LOCK},
		{CP4ViewImageList::FSB_THEIR_LOCK,	SI_THEIR_LOCK},
		{CP4ViewImageList::FSB_SYNCED,		SI_SYNCED},
		{CP4ViewImageList::FSB_NOT_SYNCED,	SI_NOT_SYNCED},
		{-1,-1}
	};

	for(int i = 0; map[i][0] != -1; i++)
		if(map[i][0] == badge)
			return map[i][1];
	ASSERT(0);
	return 0;
}

// lookup tables for finding an icon given it's state mask
static unsigned short fileMap[2 << CP4ViewImageList::FSB_NUM_BITS];
static unsigned short cuMap[2 << CP4ViewImageList::CUSB_NUM_BITS];

// return composite image index for client/user (CUSB) state flags
int CP4ViewImageList::GetCUIndex(int state)
{
	int result = cuMap[state];
	ASSERT(result);	// illegal combination state bits
	return result;
}

// return image index for client with specified attributes
int CP4ViewImageList::GetClientIndex(bool isCurrent, bool isDefault)
{
	return GetCUIndex(CUSB_CLIENT |
		(isDefault ? CUSB_DEF : 0) |
		(isCurrent ? CUSB_CUR : 0));
}

// return image index for user with specified attributes
int CP4ViewImageList::GetUserIndex(bool isCurrent, bool isDefault)
{
	return GetCUIndex(CUSB_USER |
		(isDefault ? CUSB_DEF : 0) |
		(isCurrent ? CUSB_CUR : 0));
}

// return composite image index for file state (FSB) flags
int CP4ViewImageList::GetFileIndex(int state)
{
	int result = fileMap[state];
	ASSERT(result);	// illegal combination state bits
	return result;
}

// create a composite client or user image
static void AddCUImage(CP4Image &dst, CP4Image &src, int &x, int layers)
{
	ASSERT(layers);
	ASSERT(x/24 < 0x10000);
	cuMap[layers] = (unsigned short)(x / 24);
	int mask = 1;
	while(layers)
	{
		if(layers & 1)
		{
			int img = CUSBToImage(mask);
			dst.BlendImage(x/24, src, img);
		}
		layers >>= 1;
		mask <<= 1;
	}
	x += 24;
}

// create a composite file image
static void AddFileImage(CP4Image &dst, CP4Image &src, int &x, int layers)
{
	ASSERT(layers);
	ASSERT(x/24 < 0x10000);
	fileMap[layers] = (unsigned short)(x / 24);
	bool red = (layers & CP4ViewImageList::FSB_YOUR_ADD) && 
		(layers & CP4ViewImageList::FSB_THEIR_ADD);
	int mask = 1;
	while(layers)
	{
		if(layers & 1)
		{
			int img = FSBToImage(mask);
			dst.BlendImage(x/24, src, img);
			// special case to get red border when you're not the
			// only one to have a file open for add
			if(red)
				dst.BlendImage(x/24, src, SI_RED_DOC_BORDER);
			red = false;
		}
		layers >>= 1;
		mask <<= 1;
	}
	x += 24;
}

// add a group of file images with non-add actions

static void AddFileImageSync(CP4Image &dst, CP4Image &src, int &x, int base)
{
	AddFileImage(dst, src, x, base);
	AddFileImage(dst, src, x, base | CP4ViewImageList::FSB_SYNCED);
	AddFileImage(dst, src, x, base | CP4ViewImageList::FSB_NOT_SYNCED);
}

static void AddFileImageLock(CP4Image &dst, CP4Image &src, int &x, int base)
{
	AddFileImageSync(dst, src, x, base);
	AddFileImageSync(dst, src, x, base | CP4ViewImageList::FSB_YOUR_LOCK);
	AddFileImageSync(dst, src, x, base | CP4ViewImageList::FSB_THEIR_LOCK);
}

static void AddFileImageTheirAction(CP4Image &dst, CP4Image &src, int &x, int base)
{
	AddFileImageLock(dst, src, x, base);
	AddFileImageLock(dst, src, x, base | CP4ViewImageList::FSB_THEIR_DELETE);
	AddFileImageLock(dst, src, x, base | CP4ViewImageList::FSB_THEIR_ADD);
	AddFileImageLock(dst, src, x, base | CP4ViewImageList::FSB_THEIR_EDIT);
}

static void AddFileImageYourAction(CP4Image &dst, CP4Image &src, int &x, int base)
{
	AddFileImageTheirAction(dst, src, x, base);
	AddFileImageTheirAction(dst, src, x, base | CP4ViewImageList::FSB_YOUR_DELETE);
	AddFileImageTheirAction(dst, src, x, base | CP4ViewImageList::FSB_YOUR_ADD);
	AddFileImageTheirAction(dst, src, x, base | CP4ViewImageList::FSB_YOUR_EDIT);
}

static void AddFileImageType(CP4Image &dst, CP4Image &src, int &x, int base)
{
	AddFileImageYourAction(dst, src, x, base | CP4ViewImageList::FSB_BINARY);
	AddFileImageYourAction(dst, src, x, base | CP4ViewImageList::FSB_TEXT);
}

// create the bitmap containing both simple and composite images
void CP4ViewImageList::MakeBitmap(CP4Image &dst, CP4Image &src, COLORREF bg)
{
	// first, set the whole thing to the background color
	dst.FillImage(bg);

	// next, just copy over the first segment of simple images
	int i;
	for(i = 0; i <= SI_LAST_SIMPLE; i++)
		dst.BlendImage(i, src, i);

	// add open folder icon
	dst.BlendImage(i++, src, SI_OPENFOLDER);

	// create the unresolved pending chglist ones
	dst.BlendImage(i,   src, CP4ViewImageList::VI_YOURCHANGE);
	dst.BlendImage(i++, src, SI_NOT_SYNCED);
	dst.BlendImage(i,   src, CP4ViewImageList::VI_YOUROTHERCHANGE);
	dst.BlendImage(i++, src, SI_NOT_SYNCED);

	int x = i * 24;

	// copy client, plus badges
	AddCUImage(dst, src, x, CUSB_CLIENT);
	AddCUImage(dst, src, x, CUSB_CLIENT | CUSB_CUR);
	AddCUImage(dst, src, x, CUSB_CLIENT | CUSB_DEF);
	AddCUImage(dst, src, x, CUSB_CLIENT | CUSB_CUR | CUSB_DEF);

	// copy user, plus badges
	AddCUImage(dst, src, x, CUSB_USER);
	AddCUImage(dst, src, x, CUSB_USER | CUSB_CUR);
	AddCUImage(dst, src, x, CUSB_USER | CUSB_DEF);
	AddCUImage(dst, src, x, CUSB_USER | CUSB_CUR | CUSB_DEF);

	// create all file images except the wierd one
	AddFileImageType(dst, src, x, 0);

	// create the wierd file one
	AddFileImage(dst, src, x, FSB_GHOST | FSB_SYNCED);
}

bool CP4ViewImageList::Create()
{
	// determine width required for bitmap
	int w = 24 * 
		(SI_LAST_SIMPLE + 1 +	// simple (non-composite) images
		4 +			// user + cur/def
		4 +			// client + cur/def
		2 *			// file types: binary, text
		4 *			// your action: none, add, edit, delete
		4 *			// their action: none, add, edit, delete
		3 *			// lock states: none, yours, theirs
		3 +			// sync states: none, synced, not synced
		1 +			// wierd ghost combo
		1 +			// open folder
		2 );		// 2 unresolved pending chglists

	CDC dc;
	dc.CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
	m_colorDepth = dc.GetDeviceCaps(BITSPIXEL);
	if (m_colorDepth >= 16 && !m_use256ColorIcons)
	{
		// at least 16-bit color, so create a device dependent bitmap
		// using 32-bit rgba source bitmap
		if(!CImageList::Create(24, 16, ILC_COLOR32|ILC_MASK, 5, 0))
			return false;


		CP4ImageDib src(24);
		CP4ImageDib dst(24);
		if(src.Load(IDB_VIEWICONS32))
		{
			src.PreMultiplyAlpha();
			dst.Create(w, 16);

			MakeBitmap(dst, src, GetSysColor(COLOR_WINDOW));
			CBitmap *bmp = dst.CreateDDB(dc);
			if(bmp)
				Add(bmp, GetSysColor(COLOR_WINDOW));
			return true;
		}
		// something didn't work out, so fall through and use 16 colors
	}

	// 256 or fewer colors device, so use 16 color bitmap
	if(!CImageList::Create(24, 16, ILC_COLOR4|ILC_MASK, 5, 0))
		return false;

	// use magenta for background; it will be transparent
	// (using non-transparent COLOR_WINDOW background fails 
	// sometimes in 256 color mode)
	COLORREF magenta = RGB(255,0,255);
	CP4Image16 src(magenta, 24);
	CP4Image16 dst(magenta, 24);
	if(src.Load(IDB_VIEWICONS4) && dst.Create(dc, w, 16))
	{
		src.StartBlendingSource();
		dst.StartBlendingDest(dc);

		MakeBitmap(dst, src, magenta);

		dst.EndBlendingDest();
		src.EndBlendingSource();

		CBitmap *bmp = dst.CreateDDB(dc);
		if(bmp)
			Add(bmp, magenta);
		m_colorDepth = 4;
		return true;
	}
	return false;
}
# Change User Description Committed
#1 19924 YourUncleBob Populate -o //guest/perforce_software/p4win/...
//guest/YourUncleBob/p4win/.....
//guest/perforce_software/p4win/main/gui/ImageList.cpp
#1 16169 perforce_software Move files to follow new path scheme for branches.
//guest/perforce_software/p4win/gui/ImageList.cpp
#1 8562 Matt Attaway These feet never stop running.

Initial commit of the P4Win source code.  To the best of our knowledge this
compiles and runs using the 2013.3 P4 API and VS 2010. Expect a few changes
as we refine the build process. Please post any build issues to the forums.