Fixes to the way custom icons are handled in Aurora.

This commit is contained in:
hyatt 1998-04-30 22:11:34 +00:00
parent 6403a164b4
commit ae3f334a3f
3 changed files with 183 additions and 19 deletions

View File

@ -20,22 +20,22 @@
#include "cxicon.h"
#include "feimage.h"
#include "winproto.h"
#include "helper.h"
HBITMAP NSNavCenterImage::m_hBadImageBitmap = NULL;
int NSNavCenterImage::refCount = 0;
NSNavCenterImage::NSNavCenterImage(char * url, CIconCallbackInfo* iconCallbackInfo)
NSNavCenterImage::NSNavCenterImage(const char * url)
{
m_nRefCount = 0;
pUrl = _strdup( url);
bmpInfo = NULL;
m_bCompletelyLoaded = FALSE;
bits = 0;
maskbits = 0;
m_BadImage = FALSE;
resourceList.AddHead(iconCallbackInfo); // list to store all the resources waiting on this image
NSNavCenterImage::refCount++;
iconContext = NULL;
ProcessIcon();
}
NSNavCenterImage::~NSNavCenterImage()
@ -53,23 +53,70 @@ NSNavCenterImage::~NSNavCenterImage()
}
}
void NSNavCenterImage::AddListener(CCustomImageObject* pObject, HT_Resource r)
{
// We only want to have one copy of the same image in this list.
for (POSITION pos = resourceList.GetHeadPosition();
pos != NULL; )
{
// Enumerate over the list and call remove listener on each image.
CIconCallbackInfo* pInfo = (CIconCallbackInfo*)resourceList.GetNext(pos);
if (pInfo->pObject == pObject &&
pInfo->pResource == r)
return; // We're already listening for this resource.
}
// Add a listener.
CIconCallbackInfo* iconCallbackInfo = new CIconCallbackInfo(pObject, r);
resourceList.AddHead(iconCallbackInfo);
pObject->AddLoadingImage(this);
m_nRefCount++;
if (iconContext == NULL)
{
// Kick off the load.
ProcessIcon();
}
}
void NSNavCenterImage::RemoveListener(CCustomImageObject *pObject)
{
// Listener has been destroyed. Need to get all references to it out of the list.
// Just do this by NULLing out the pObject field of the iconcallbackinfo structs.
for (POSITION pos = resourceList.GetHeadPosition();
pos != NULL; )
{
CIconCallbackInfo* pInfo = (CIconCallbackInfo*)resourceList.GetNext(pos);
if (pInfo->pObject == pObject)
{
pInfo->pObject = NULL;
m_nRefCount--;
if (m_nRefCount == 0 && iconContext)
{
iconContext->Interrupt();
DestroyContext();
return;
}
}
}
}
void NSNavCenterImage::DestroyContext()
{
iconContext->DeleteContextDC();
iconContext->DestroyContext(); // now destroy self.
iconContext->NiceDestruction();
iconContext = NULL;
resourceList.RemoveAll();
}
BOOL NSNavCenterImage::CompletelyLoaded()
{
if (m_bCompletelyLoaded)
{
if (iconContext)
DestroyContext();
return TRUE;
}
return (m_bCompletelyLoaded);
}
return FALSE;
BOOL NSNavCenterImage::SuccessfullyLoaded()
{
return (m_bCompletelyLoaded && bits);
}
void Icon_GetUrlExitRoutine(URL_Struct *pUrl, int iStatus, MWContext *pContext)
@ -94,13 +141,9 @@ void Icon_GetUrlExitRoutine(URL_Struct *pUrl, int iStatus, MWContext *pContext)
}
}
static BOOL ValidNSBitmapFormat(char* extension)
static BOOL IsImageMimeType(const CString& theFormat)
{
BOOL val = FALSE;
CString theFormat = "image/";
if(!extension)
return val;
theFormat += &extension[1];
if (theFormat.CompareNoCase(IMAGE_GIF) == 0)
val = TRUE;
else if (theFormat.CompareNoCase(IMAGE_JPG) == 0)
@ -120,6 +163,31 @@ static BOOL ValidNSBitmapFormat(char* extension)
return val;
}
static BOOL ValidNSBitmapFormat(char* extension)
{
CPtrList* allHelpers = &(CHelperApp::m_cplHelpers);
for (POSITION pos = allHelpers->GetHeadPosition(); pos != NULL;)
{
CHelperApp* app = (CHelperApp*)allHelpers->GetNext(pos);
CString helperMime(app->cd_item->ci.type);
if (IsImageMimeType(helperMime))
{
if (app->cd_item->num_exts > 0)
{
for (int i = 0; i < app->cd_item->num_exts; i++)
{
CString extString(app->cd_item->exts[i]);
if (extString == &extension[1])
return TRUE;
}
}
}
}
return FALSE;
}
void NSNavCenterImage::ProcessIcon()
{
char *ext = FE_FindFileExt(pUrl);
@ -162,9 +230,15 @@ void NSNavCenterImage::CompleteCallback()
while (!resourceList.IsEmpty())
{
CIconCallbackInfo* callback = (CIconCallbackInfo*)(resourceList.RemoveHead());
callback->pObject->LoadComplete(callback->pResource);
if (callback->pObject)
{
callback->pObject->LoadComplete(callback->pResource);
callback->pObject->RemoveLoadingImage(this);
}
delete callback;
}
DestroyContext();
}
CXIcon::CXIcon(NSNavCenterImage* theImage)
@ -247,3 +321,76 @@ void CXIcon::AllConnectionsComplete(MWContext *pContext)
{
CDCCX::AllConnectionsComplete(pContext);
}
void CXIcon::NiceDestruction()
{
m_bIdleDestroy = TRUE;
FEU_RequestIdleProcessing(GetContext());
}
// ========================= CCustomImageObject Helpers =============================
NSNavCenterImage* CCustomImageObject::LookupImage(const char* url, HT_Resource r)
{
// Find the image.
void* pData;
NSNavCenterImage* pImage = NULL;
if (CHTFEData::m_CustomURLCache.Lookup(url, pData))
{
pImage = (NSNavCenterImage*)pData;
// Add ourselves to the callback list if the image hasn't completely loaded.
if (!pImage->CompletelyLoaded())
{
// The image is currently loading. Register ourselves with the image so that we will get called
// when the image finishes loading.
pImage->AddListener(this, r);
}
}
else
{
// Create a new NavCenter image.
pImage = new NSNavCenterImage(url);
pImage->AddListener(this, r);
CHTFEData::m_CustomURLCache.SetAt(url, pImage);
}
return pImage;
}
CCustomImageObject::~CCustomImageObject()
{
// The displayer of the image is being destroyed. It should be removed as a listener from all
// images.
for (POSITION pos = loadingImagesList.GetHeadPosition();
pos != NULL; )
{
// Enumerate over the list and call remove listener on each image.
NSNavCenterImage* pImage = (NSNavCenterImage*)loadingImagesList.GetNext(pos);
pImage->RemoveListener(this);
}
}
void CCustomImageObject::AddLoadingImage(NSNavCenterImage* pImage)
{
// We only want to have one copy of the same image in this list.
for (POSITION pos = loadingImagesList.GetHeadPosition();
pos != NULL; )
{
// Enumerate over the list and call remove listener on each image.
NSNavCenterImage* pNavImage = (NSNavCenterImage*)loadingImagesList.GetNext(pos);
if (pNavImage == pImage)
return;
}
// Add the image to the list.
loadingImagesList.AddHead(pImage);
}
void CCustomImageObject::RemoveLoadingImage(NSNavCenterImage* pImage)
{
// Should only occur once in our list. Find and remove.
POSITION pos = loadingImagesList.Find(pImage);
if (pos)
loadingImagesList.RemoveAt(pos);
}

View File

@ -24,8 +24,18 @@ class CXIcon;
class CCustomImageObject
{
private:
CPtrList loadingImagesList; // A list of images that this window is still waiting for.
public:
virtual void LoadComplete(HT_Resource r) = 0;
virtual NSNavCenterImage* LookupImage(const char* url, HT_Resource r);
virtual ~CCustomImageObject();
virtual void AddLoadingImage(NSNavCenterImage* pImage);
virtual void RemoveLoadingImage(NSNavCenterImage* pImage);
};
struct CIconCallbackInfo
@ -56,14 +66,19 @@ public:
CPtrList resourceList;
HT_Resource m_HTResource;
NSNavCenterImage(char * pUrl, CIconCallbackInfo* iconCallbackInfo);
int m_nRefCount;
NSNavCenterImage(const char * pUrl);
virtual ~NSNavCenterImage();
void ProcessIcon();
void CompleteCallback();
BOOL CompletelyLoaded();
BOOL SuccessfullyLoaded();
void DestroyContext();
void RemoveListener(CCustomImageObject* pObject);
void AddListener(CCustomImageObject* pObject, HT_Resource r);
};
class CXIcon : public CDCCX {
@ -92,5 +107,6 @@ public:
virtual void ImageComplete(NI_Pixmap* image);
// Don't display partial images.
virtual void AllConnectionsComplete(MWContext *pContext);
void NiceDestruction();
};
#endif

View File

@ -26,7 +26,6 @@ private:
friend class COwnedAndLostList;
friend class COwnedLostItem;
static CPtrList m_cplHelpers;
POSITION m_rIndex;
public:
CHelperApp() {
@ -47,6 +46,8 @@ public:
CString strFileClass; // Windows registry file type class
CString csMimePrefPrefix; //Prefix of the mime type - if this helper is associated with a MIME type specd. thru' prefs...CRN_MIME
static CPtrList m_cplHelpers;
};