wxWidgets is a great portable GUI library. Here are some various wxWidgets Contributions

Contributions

These contributions are published under wxWindows licence (based on L-GPL).

wxRectTracker

This is a tracker similar to the MFC CRectTracker. It is basically a selection rectangle with dragging capabilites, to set its size and position.

Documentation generated by Doxygen is provided.

Thus this class needs a little refactoring, it can be derivated easily, by example in another class wxLineTracker, which does the same thing, but with a line instead of a rectangle.

Download source zip

wxRectTracker is used in RPhoto and in wxCommander

wxConfigDialog

wxConfigDialog is a basic configuration system, for developer who does not want to spend much time in building configuration dialogs.
wxConfigDialog handles automatically :

  • save / restore of settings with wxConfig
  • build a default dialog with tabs, according to the wxConfig settings

Code example :

m_pConfig = new wxConfig(wxT("RPhoto"));
m_pConfigDialog = new wxConfigDialog(*m_pConfig, 
                      this, -1, _("Preferences"), 
                      wxDefaultPosition, wxDefaultSize, 
                      wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
new wxConfigDialog_EntryCheck(*m_pConfigDialog, 
                              wxT("Main"), wxT("AutoSave"), 
                              _("Main"), _("Auto Save"), FALSE);
new wxConfigDialog_EntryTextEdit(*m_pConfigDialog, 
                                 wxT("JPEG"), wxT("JPEGTran"),
                                 _("JPEG"), _("JPEGTran's path"), wxT("jpegtran"));
m_pConfigDialog->doLayout();

Download source zip

wxStringBase64

wxStr64 is a extension to wxString, to help using strings encoded in base64. It does not use the wxEncodingConverter style, because it was mainly developped to store data buffers which may contain the null char in wxString objects.

class wxStringBase64 : public wxString
{
public:
	wxStringBase64() : wxString() {};
	wxStringBase64(wxString str) : wxString(str) {};
	wxStringBase64(unsigned char * src, int size);
	void setBase64Data(unsigned char * src, int size);
	int getDataLength();
	unsigned char * getBase64Data();
};

For instance, I use wxStringBase64 to store Exif data in wxString, which may contain null char. Storing these data in wxString avoid subclassing wxImage, what would be rather complicated.

Download source zip

Patches

Here are some “patches”. Note : it is not regular patch, but more code snippets to solve the problem. I will probably soon submit them as regular patches to wxWidgets.

wxGenericDirCtrl

Bug #866387 : wxGenericDirCtrl does not accept multiple wildcards

wxGenericDirCtrl did not accept multiple wildcards as in “Images (*.jpg;*.png;*.tif)”.

Replace the existing code in wxGenericDirCtrl::ExpandDir

if (d.IsOpened())
{
  wxStringTokenizer strTok;
  wxString curFilter;
  strTok.SetString(m_currentFilterStr,wxT(";"));
  while(strTok.HasMoreTokens())
  {
    curFilter = strTok.GetNextToken();
    if (d.GetFirst(& eachFilename, curFilter, wxDIR_FILES))
    {
     do {
       if ((eachFilename != wxT(".")) && (eachFilename != wxT("..")))
       {
         filenames.Add(eachFilename);
       }
     } while (d.GetNext(& eachFilename));
    }
  }
}

This patch has been incorporated in wx2.6. If you use wx2.4 and do not want to recompile it, you can use wxFixedDirCtrl (and #define it) instead.

Bug # : display drive labels name in wxGenericDirCtrl on wxMSW

This is to display the drive label in the tree “(C:) WinXP” instead of only the drive letter “(C:)”.

Insert the following snippet after the switch(driveType) in wxGenericDirCtrl::SetupSections()

TCHAR FileSysNameBuf[MAX_PATH];
if ((driveType == DRIVE_FIXED) || (driveType == DRIVE_REMOTE))
{
  GetVolumeInformation(path.c_str(), FileSysNameBuf, MAX_PATH, NULL, NULL,  NULL, NULL, 0);
  name.Printf(wxT("(%c:) %s"), driveBuffer[i], FileSysNameBuf);
}

Bug # : option to have wildcard not case sensitive

Currently, wxGenericDirCtrl would not show IMG0001.JPG with the filter *.jpg .

wxJPEGHandler

If you load and save a jpeg file with the current JPEG handler, you will lose all additionnal informations like Exif, IPTC, comments…
A solution is to store these additionnal info in options (see wxImage::SetOption()). The options will be name “APP1” for Exif, “COM” for comments, and “APP2”..“APP15” for other info.Here are code snippets to solve this :

In wxJPEGHandler::LoadFile between jpeg_create_decompress and jpeg_read_header :

jpeg_save_markers(&cinfo, M_APP0, 32000);
[...]
jpeg_save_markers(&cinfo, M_APP15, 32000);
jpeg_save_markers(&cinfo, M_COM, 32000);

and after jpeg_destroy_decompress :

jpeg_saved_marker_ptr curMarker;
wxString markerName, markerValue;
curMarker = cinfo.marker_list;
while(curMarker != NULL)
{
	switch(curMarker->marker)
	{
	case M_APP0: markerName = "APP0";	break;
	case M_APP1: markerName = "APP1";	break;
        [...]
	case M_APP15: markerName = "APP15";	break;
	case M_COM: markerName = "COM";		break;
	default: markerName = "UNKNOWN";	break;
	}
	markerValue = wxStringBase64(curMarker->data, curMarker->data_length);
	image->SetOption(markerName, markerValue);
	wxLogDebug("n%s = %s", markerName, image->GetOption(markerName));
	curMarker = curMarker->next;
}

In wxJPEGHandler::SaveFile after jpeg_start_compress :

wxStringBase64 str64;
unsigned char * buf;

#define SAVE_OPTION(name, index) 
	if (image->HasOption((name))) 
	{ 
		wxLogDebug("%s", name); 
		str64 = image->GetOption((name)); 
		buf = str64.getBase64Data(); 
		jpeg_write_marker(&cinfo, (index), buf, str64.getDataLength()); 
		if (buf) free(buf); 
	}

SAVE_OPTION("APP0", M_APP0);
SAVE_OPTION("APP1", M_APP1);
[...]
SAVE_OPTION("APP15", M_APP15);
SAVE_OPTION("COM", M_COM);

#undef SAVE_OPTION

You will need wxStringBase64. To help integration, I made a new handler wxEJPGHandler. Juste put the two files, and register it in your application OnInit() :

wxInitAllImageHandlers();
wxImage::RemoveHandler("JPEG file");
wxImage::InsertHandler(new wxEJPGHandler());

Download source zip

wxImage

Bug # : Options not copied when copying o wxImage

When copying or creating a new image from another, the current implementation of wxImage does not copy the options strings. Thus, all options will be lost when rotating, getting a sub image, and so on.

As wxImage is very hard to subclass (because of m_refData), I prefer a simple helper class (included in wxEJPGHandler::wxImageOpt), to use in applications. I will provide a wxImage patch later.

To use it, define somewhere in your application

static wxImageOpt imageOpts;
#define BEGIN_IMAGE_MANIP(img) imageOpts.getImageOptions(img);
#define END_IMAGE_MANIP(img) imageOpts.setImageOptions(img);

And before / after each image operation :

BEGIN_IMAGE_MANIP(img)
// Image Operation : img = img.GetSubImage(...);
END_IMAGE_MANIP(img)

Header :

class WXDLLEXPORT wxImageOpt
{
public:
	wxImageOpt();
	wxImageOpt(const wxImage & img);

	getImageOptions(const wxImage & img);
	setImageOptions(wxImage & img, bool overwrite = false);

public:
	wxArrayString idsToSave;
protected:
	wxArrayString ids;
	wxArrayString values;
};

Code :

wxImageOpt::wxImageOpt()
{
	idsToSave.Add("APP0");
	idsToSave.Add("APP1");
	idsToSave.Add("APP2");
	idsToSave.Add("APP3");
	idsToSave.Add("APP4");
	idsToSave.Add("APP5");
	idsToSave.Add("APP6");
	idsToSave.Add("APP7");
	idsToSave.Add("APP8");
	idsToSave.Add("APP9");
	idsToSave.Add("APP10");
	idsToSave.Add("APP11");
	idsToSave.Add("APP12");
	idsToSave.Add("APP13");
	idsToSave.Add("APP14");
	idsToSave.Add("APP15");
	idsToSave.Add("COM");
}

wxImageOpt::wxImageOpt(const wxImage & img)
{
	wxImageOpt();
	getImageOptions(img);
}


wxImageOpt::getImageOptions(const wxImage & img)
{
	unsigned int i;
	ids.Clear();
	values.Clear();

	for (i = 0 ; i < idsToSave.Count() ; i++)
	{
		if (img.HasOption(idsToSave[i]))
		{
			ids.Add(idsToSave[i]);
			values.Add(img.GetOption(idsToSave[i]));
		}
	}
}

wxImageOpt::setImageOptions(wxImage & img, bool overwrite)
{
	unsigned int i;
	for (i = 0 ; i < ids.Count() ; i++)
	{
		if ( (!img.HasOption(ids[i])) || overwrite )
		{
			img.SetOption(ids[i], values[i]);
		}
	}
}

Bug # : Difficult access to wxImage options

These properties are in private scope (Grrr, use protected instead, to allow easy patch-subclassing !).
It is so impossible to know which options are defined.

Patch TODO : add GetOptions() which returns the wxList of keys.

Useful informations