- changed all color usage to use LDColor classes instead of color indices. Added support for direct colors.

Sat, 14 Jun 2014 09:05:29 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Sat, 14 Jun 2014 09:05:29 +0300
changeset 795
195fa1fff9c3
parent 794
c254ddc6618b
child 796
f23f4e4ed279

- changed all color usage to use LDColor classes instead of color indices. Added support for direct colors.

changelog.txt file | annotate | diff | comparison | revisions
src/actions.cc file | annotate | diff | comparison | revisions
src/actionsEdit.cc file | annotate | diff | comparison | revisions
src/addObjectDialog.cc file | annotate | diff | comparison | revisions
src/addObjectDialog.h file | annotate | diff | comparison | revisions
src/colorSelector.cc file | annotate | diff | comparison | revisions
src/colorSelector.h file | annotate | diff | comparison | revisions
src/colors.cc file | annotate | diff | comparison | revisions
src/colors.h file | annotate | diff | comparison | revisions
src/configDialog.cc file | annotate | diff | comparison | revisions
src/extPrograms.cc file | annotate | diff | comparison | revisions
src/format.h file | annotate | diff | comparison | revisions
src/glCompiler.cc file | annotate | diff | comparison | revisions
src/glRenderer.cc file | annotate | diff | comparison | revisions
src/ldConfig.cc file | annotate | diff | comparison | revisions
src/ldConfig.h file | annotate | diff | comparison | revisions
src/ldDocument.cc file | annotate | diff | comparison | revisions
src/ldObject.cc file | annotate | diff | comparison | revisions
src/ldObject.h file | annotate | diff | comparison | revisions
src/macros.h file | annotate | diff | comparison | revisions
src/mainWindow.cc file | annotate | diff | comparison | revisions
src/mainWindow.h file | annotate | diff | comparison | revisions
src/primitives.cc file | annotate | diff | comparison | revisions
ui/colorsel.ui file | annotate | diff | comparison | revisions
--- a/changelog.txt	Thu Jun 05 23:18:13 2014 +0300
+++ b/changelog.txt	Sat Jun 14 09:05:29 2014 +0300
@@ -39,6 +39,7 @@
 +	- Added a toolbox for primitives. These primitives can be dragged and dropped into the main viewport.
 +	- Primitive categories are now sorted alphabetically.
 +	- Added hi-res counterparts for various primitive categories.
++	- Added support for direct colors.
 
 -	- The camera is now changed to the top one if switching to draw mode while using the free camera instead of disabling the draw mode.
 -	- The color selector now uses the color's edge color for the borders instead of black.
--- a/src/actions.cc	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/actions.cc	Sat Jun 14 09:05:29 2014 +0300
@@ -299,7 +299,7 @@
 	if (selection().isEmpty())
 		return;
 
-	QList<int> colors;
+	QList<LDColor> colors;
 
 	for (LDObjectPtr obj : selection())
 	{
@@ -869,7 +869,7 @@
 
 		// Add a reference to the new subfile to where the selection was
 		LDSubfilePtr ref (spawn<LDSubfile>());
-		ref->setColor (maincolor);
+		ref->setColor (maincolor());
 		ref->setFileInfo (doc);
 		ref->setPosition (g_origin);
 		ref->setTransform (g_identity);
--- a/src/actionsEdit.cc	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/actionsEdit.cc	Sat Jun 14 09:05:29 2014 +0300
@@ -224,22 +224,20 @@
 	if (selection().isEmpty())
 		return;
 
-	int colnum;
-	int defcol = -1;
-
 	LDObjectList objs = selection();
 
 	// If all selected objects have the same color, said color is our default
 	// value to the color selection dialog.
-	defcol = getSelectedColor();
+	LDColor color;
+	LDColor defaultcol = getSelectedColor();
 
 	// Show the dialog to the user now and ask for a color.
-	if (ColorSelector::selectColor (colnum, defcol, g_win))
+	if (ColorSelector::selectColor (color, defaultcol, g_win))
 	{
 		for (LDObjectPtr obj : objs)
 		{
 			if (obj->isColored())
-				obj->setColor (colnum);
+				obj->setColor (color);
 		}
 
 		refresh();
@@ -284,7 +282,7 @@
 				continue;
 
 			long idx = obj->lineNumber() + i + 1;
-			lines[i]->setColor (edgecolor);
+			lines[i]->setColor (edgecolor());
 			getCurrentDocument()->insertObj (idx, lines[i]);
 		}
 
@@ -566,12 +564,7 @@
 		if (not obj->isColored())
 			continue;
 
-		int col = maincolor;
-
-		if (obj->type() == OBJ_Line || obj->type() == OBJ_CondLine)
-			col = edgecolor;
-
-		obj->setColor (col);
+		obj->setColor ((obj->type() == OBJ_Line || obj->type() == OBJ_CondLine) ? edgecolor() : maincolor());
 		num++;
 	}
 
@@ -689,11 +682,13 @@
 
 // =============================================================================
 //
-static bool isColorUsed (int colnum)
+static bool isColorUsed (LDColor color)
 {
 	for (LDObjectPtr obj : getCurrentDocument()->objects())
-		if (obj->isColored() && obj->color() == colnum)
+	{
+		if (obj->isColored() && obj->color() == color)
 			return true;
+	}
 
 	return false;
 }
@@ -703,11 +698,12 @@
 DEFINE_ACTION (Autocolor, 0)
 {
 	int colnum = 0;
+	LDColor color;
 
-	while (colnum < MAX_COLORS && (getColor (colnum) == null || isColorUsed (colnum)))
-		colnum++;
+	for (colnum = 0; colnum < numLDConfigColors() && ((color = LDColor::fromIndex (colnum)) == null || isColorUsed (color)); colnum++)
+		;
 
-	if (colnum >= MAX_COLORS)
+	if (colnum >= numLDConfigColors())
 	{
 		print (tr ("Cannot auto-color: all colors are in use!"));
 		return;
@@ -718,10 +714,10 @@
 		if (not obj->isColored())
 			continue;
 
-		obj->setColor (colnum);
+		obj->setColor (color);
 	}
 
-	print (tr ("Auto-colored: new color is [%1] %2"), colnum, getColor (colnum)->name);
+	print (tr ("Auto-colored: new color is [%1] %2"), colnum, color->name());
 	refresh();
 }
 
--- a/src/addObjectDialog.cc	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/addObjectDialog.cc	Sat Jun 14 09:05:29 2014 +0300
@@ -130,12 +130,12 @@
 	if (defaults->isColored())
 	{
 		if (obj != null)
-			colnum = obj->color();
+			_color = obj->color();
 		else
-			colnum = (type == OBJ_CondLine || type == OBJ_Line) ? edgecolor : maincolor;
+			_color = (type == OBJ_CondLine || type == OBJ_Line) ? edgecolor() : maincolor();
 
 		pb_color = new QPushButton;
-		setButtonBackground (pb_color, colnum);
+		setButtonBackground (pb_color, _color);
 		connect (pb_color, SIGNAL (clicked()), this, SLOT (slot_colorButtonClicked()));
 	}
 
@@ -234,15 +234,13 @@
 
 // =============================================================================
 // =============================================================================
-void AddObjectDialog::setButtonBackground (QPushButton* button, int colnum)
+void AddObjectDialog::setButtonBackground (QPushButton* button, LDColor color)
 {
-	LDColor* col = ::getColor (colnum);
-
 	button->setIcon (getIcon ("palette"));
 	button->setAutoFillBackground (true);
 
-	if (col)
-		button->setStyleSheet (format ("background-color: %1", col->hexcode));
+	if (color != null)
+		button->setStyleSheet (format ("background-color: %1", color->hexcode()));
 }
 
 // =============================================================================
@@ -261,8 +259,8 @@
 // =============================================================================
 void AddObjectDialog::slot_colorButtonClicked()
 {
-	ColorSelector::selectColor (colnum, colnum, this);
-	setButtonBackground (pb_color, colnum);
+	ColorSelector::selectColor (_color, _color, this);
+	setButtonBackground (pb_color, _color);
 }
 
 // =============================================================================
@@ -397,7 +395,7 @@
 	}
 
 	if (obj->isColored())
-		obj->setColor (dlg.colnum);
+		obj->setColor (dlg._color);
 
 	if (newObject)
 	{
--- a/src/addObjectDialog.h	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/addObjectDialog.h	Sat Jun 14 09:05:29 2014 +0300
@@ -58,10 +58,10 @@
 	QLineEdit* le_matrix;
 
 private:
-	void setButtonBackground (QPushButton* button, int color);
+	void setButtonBackground (QPushButton* button, LDColor color);
 	QString currentSubfileName();
 
-	int colnum;
+	LDColor _color;
 
 private slots:
 	void slot_colorButtonClicked();
--- a/src/colorSelector.cc	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/colorSelector.cc	Sat Jun 14 09:05:29 2014 +0300
@@ -23,7 +23,7 @@
 #include <QGraphicsItem>
 #include <QMouseEvent>
 #include <QScrollBar>
-
+#include <QColorDialog>
 #include "main.h"
 #include "mainWindow.h"
 #include "colorSelector.h"
@@ -39,20 +39,16 @@
 EXTERN_CFGENTRY (Float, mainColorAlpha);
 
 // =============================================================================
-// =============================================================================
-ColorSelector::ColorSelector (int defval, QWidget* parent) : QDialog (parent)
+//
+ColorSelector::ColorSelector (LDColor defval, QWidget* parent) : QDialog (parent)
 {
-	// Remove the default color if it's invalid
-	if (not getColor (defval))
-		defval = -1;
-
 	m_firstResize = true;
 	ui = new Ui_ColorSelUI;
 	ui->setupUi (this);
 
 	m_scene = new QGraphicsScene;
 	ui->viewport->setScene (m_scene);
-	setSelection (getColor (defval));
+	setSelection (defval);
 
 	// not really an icon but eh
 	m_scene->setBackgroundBrush (getIcon ("checkerboard"));
@@ -62,18 +58,21 @@
 	ui->viewport->setMinimumWidth (width);
 	ui->viewport->setMaximumWidth (width);
 
+	connect (ui->directColor, SIGNAL (clicked (bool)), this, SLOT (chooseDirectColor()));
+	connect (ui->transparentDirectColor, SIGNAL (clicked (bool)), this, SLOT (transparentCheckboxClicked()));
+
 	drawColorInfo();
 }
 
 // =============================================================================
-// =============================================================================
+//
 ColorSelector::~ColorSelector()
 {
 	delete ui;
 }
 
 // =============================================================================
-// =============================================================================
+//
 void ColorSelector::drawScene()
 {
 	const int numCols = g_numColumns;
@@ -89,33 +88,33 @@
 	// Draw the color rectangles.
 	m_scene->clear();
 
-	for (int i = 0; i < MAX_COLORS; ++i)
+	for (int i = 0; i < numLDConfigColors(); ++i)
 	{
-		LDColor* info = ::getColor (i);
+		LDColor info = LDColor::fromIndex (i);
 
-		if (not info)
+		if (info == null)
 			continue;
 
 		const double x = (i % numCols) * square;
 		const double y = (i / numCols) * square;
 		const double w = square - (penWidth / 2);
 
-		QColor col = info->faceColor;
+		QColor col (info->faceColor());
 
-		if (i == maincolor)
+		if (i == mainColorIndex)
 		{
 			// Use the user preferences for main color here
 			col = QColor (cfg::mainColor);
 			col.setAlpha (cfg::mainColorAlpha * 255.0f);
 		}
 
-		QPen pen (info->edgeColor, penWidth, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+		QPen pen (info->edgeColor(), penWidth, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
 		m_scene->addRect (x, y, w, w, pen, col);
 		QGraphicsTextItem* numtext = m_scene->addText (format ("%1", i));
-		numtext->setDefaultTextColor ( (luma (col) < 80) ? Qt::white : Qt::black);
+		numtext->setDefaultTextColor ((luma (col) < 80) ? Qt::white : Qt::black);
 		numtext->setPos (x, y);
 
-		if (selection() && i == selection()->index)
+		if (selection() && i == selection()->index())
 		{
 			auto curspic = m_scene->addPixmap (getIcon ("colorcursor"));
 			curspic->setPos (x, y);
@@ -124,58 +123,62 @@
 }
 
 // =============================================================================
-// =============================================================================
+//
 int ColorSelector::numRows() const
 {
-	return (MAX_COLORS / g_numColumns);
+	return (numLDConfigColors() / g_numColumns);
 }
 
 // =============================================================================
-// =============================================================================
+//
 int ColorSelector::viewportWidth() const
 {
 	return g_numColumns * g_squareSize + 21;
 }
 
 // =============================================================================
-// =============================================================================
+//
 void ColorSelector::drawColorInfo()
 {
-	if (not selection())
+	if (selection() == null)
 	{
 		ui->colorLabel->setText ("---");
+		ui->iconLabel->setPixmap (null);
+		ui->transparentDirectColor->setChecked (false);
 		return;
 	}
 
-	ui->colorLabel->setText (format ("%1 - %2", selection()->index, selection()->name));
+	ui->colorLabel->setText (format ("%1 - %2", selection()->indexString(),
+		(selection()->isDirect() ? "<direct color>" : selection()->name())));
+	ui->iconLabel->setPixmap (makeColorIcon (selection(), 16).pixmap (16, 16));
+	ui->transparentDirectColor->setChecked (selection()->isDirect() && selection()->faceColor().alphaF() < 1.0);
 }
 
 // =============================================================================
-// =============================================================================
-void ColorSelector::resizeEvent (QResizeEvent* ev)
+//
+void ColorSelector::resizeEvent (QResizeEvent*)
 {
 	// If this is the first resize, check if we need to scroll down to see the
 	// currently selected color. We cannot do this in the constructor because the
-	// height is not set properly there.
-	if (m_firstResize)
+	// height is not set properly there. Though don't do this if we selected a
+	// direct color.
+	if (m_firstResize && selection()->index() >= numLDConfigColors())
 	{
 		int visibleColors = (ui->viewport->height() / g_squareSize) * g_numColumns;
 
-		if (selection() && selection()->index >= visibleColors)
+		if (selection() && selection()->index() >= visibleColors)
 		{
-			int y = (selection()->index / g_numColumns) * g_squareSize;
+			int y = (selection()->index() / g_numColumns) * g_squareSize;
 			ui->viewport->verticalScrollBar()->setValue (y);
 		}
-
-		m_firstResize = false;
 	}
 
-	(void) ev;
+	m_firstResize = false;
 	drawScene();
 }
 
 // =============================================================================
-// =============================================================================
+//
 void ColorSelector::mousePressEvent (QMouseEvent* event)
 {
 	QPointF scenepos = ui->viewport->mapToScene (event->pos());
@@ -184,7 +187,7 @@
 	int y = (scenepos.y() - (g_squareSize / 2)) / g_squareSize;
 	int idx = (y * g_numColumns) + x;
 
-	LDColor* col = ::getColor (idx);
+	LDColor col = LDColor::fromIndex (idx);
 
 	if (not col)
 		return;
@@ -195,14 +198,47 @@
 }
 
 // =============================================================================
+//
+void ColorSelector::selectDirectColor (QColor col)
+{
+	int32 idx = (ui->transparentDirectColor->isChecked() ? 0x03000000 : 0x02000000);
+	idx |= (col.red() << 16) | (col.green() << 8) | (col.blue());
+	setSelection (LDColor::fromIndex (idx));
+	drawColorInfo();
+}
+
 // =============================================================================
-bool ColorSelector::selectColor (int& val, int defval, QWidget* parent)
+//
+void ColorSelector::chooseDirectColor()
+{
+	QColor defcolor = selection() != null ? selection()->faceColor() : Qt::white;
+	QColor newcolor = QColorDialog::getColor (defcolor);
+
+	if (not newcolor.isValid())
+		return; // canceled
+
+	selectDirectColor (newcolor);
+}
+
+// =============================================================================
+//
+void ColorSelector::transparentCheckboxClicked()
+{
+	if (selection() == null || not selection()->isDirect())
+		return;
+
+	selectDirectColor (selection()->faceColor());
+}
+
+// =============================================================================
+//
+bool ColorSelector::selectColor (LDColor& val, LDColor defval, QWidget* parent)
 {
 	ColorSelector dlg (defval, parent);
 
 	if (dlg.exec() && dlg.selection() != null)
 	{
-		val = dlg.selection()->index;
+		val = dlg.selection();
 		return true;
 	}
 
--- a/src/colorSelector.h	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/colorSelector.h	Sat Jun 14 09:05:29 2014 +0300
@@ -19,32 +19,37 @@
 #pragma once
 #include <QDialog>
 #include "main.h"
+#include "colors.h"
 
-class LDColor;
 class Ui_ColorSelUI;
 class QGraphicsScene;
 
 class ColorSelector : public QDialog
 {
 	Q_OBJECT
-	PROPERTY (private,	LDColor*,	selection,	setSelection,	STOCK_WRITE)
+	PROPERTY (private,	LDColor,	selection,	setSelection,	STOCK_WRITE)
 
 public:
-	explicit ColorSelector (int defval = -1, QWidget* parent = null);
+	explicit ColorSelector (LDColor defval = null, QWidget* parent = null);
 	virtual ~ColorSelector();
-	static bool selectColor (int& val, int defval = -1, QWidget* parent = null);
+	static bool selectColor (LDColor& val, LDColor defval = null, QWidget* parent = null);
 
 protected:
 	void mousePressEvent (QMouseEvent* event);
 	void resizeEvent (QResizeEvent* ev);
 
 private:
-	Ui_ColorSelUI* ui;
-	QGraphicsScene* m_scene;
-	bool m_firstResize;
+	Ui_ColorSelUI*	ui;
+	QGraphicsScene*	m_scene;
+	bool			m_firstResize;
 
 	int numRows() const;
 	int viewportWidth() const;
 	void drawScene();
 	void drawColorInfo();
+	void selectDirectColor (QColor col);
+
+private slots:
+	void chooseDirectColor();
+	void transparentCheckboxClicked();
 };
--- a/src/colors.cc	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/colors.cc	Sat Jun 14 09:05:29 2014 +0300
@@ -29,54 +29,94 @@
 #include "ldConfig.h"
 #include <QColor>
 
-static LDColor* g_LDColors[MAX_COLORS];
+static LDColor g_LDConfigColors[512];
 
-// =============================================================================
-// =============================================================================
 void initColors()
 {
-	LDColor* col;
+	LDColor col;
 	print ("Initializing color information.\n");
 
 	// Always make sure there's 16 and 24 available. They're special like that.
-	col = new LDColor;
-	col->faceColor = col->hexcode = "#AAAAAA";
-	col->edgeColor = Qt::black;
-	g_LDColors[maincolor] = col;
+	col = new LDColorData;
+	col->_faceColor =
+	col->_hexcode = "#AAAAAA";
+	col->_edgeColor = Qt::black;
+	g_LDConfigColors[16] = col;
+
+	col = new LDColorData;
+	col->_faceColor =
+	col->_edgeColor =
+	col->_hexcode = "#000000";
+	g_LDConfigColors[24] = col;
 
-	col = new LDColor;
-	col->faceColor = col->edgeColor = col->hexcode = "#000000";
-	g_LDColors[edgecolor] = col;
+	LDConfigParser::parseLDConfig();
+}
 
-	parseLDConfig();
+LDColor maincolor()
+{
+	return g_LDConfigColors[16];
+}
+
+LDColor edgecolor()
+{
+	return g_LDConfigColors[24];
 }
 
-// =============================================================================
-// =============================================================================
-LDColor* getColor (int colnum)
+void LDColor::addLDConfigColor (qint32 index, LDColor color)
 {
-	// Check bounds
-	if (colnum < 0 || colnum >= MAX_COLORS)
-		return null;
-
-	return g_LDColors[colnum];
+	assert (index >= 0 && index < countof (g_LDConfigColors));
+	g_LDConfigColors[index] = color;
 }
 
-// =============================================================================
-// =============================================================================
-void setColor (int colnum, LDColor* col)
+LDColor LDColor::fromIndex (qint32 index)
 {
-	if (colnum < 0 || colnum >= MAX_COLORS)
-		return;
+	if (index < countof (g_LDConfigColors) && g_LDConfigColors[index] != null)
+		return g_LDConfigColors[index];
+
+	if (index > 0x2000000)
+	{
+		// Direct color
+		QColor col;
+		col.setRed ((index & 0x0FF0000) >> 16);
+		col.setGreen ((index & 0x000FF00) >> 8);
+		col.setBlue (index & 0x00000FF);
 
-	g_LDColors[colnum] = col;
+		if (index > 0x3000000)
+			col.setAlpha (128);
+
+		LDColor color (new LDColorData);
+		color->_name = "0x" + QString::number (index, 16).toUpper();
+		color->_faceColor = col;
+		color->_edgeColor = luma(col) < 48 ? Qt::white : Qt::black;
+		color->_hexcode = col.name();
+		color->_index = index;
+		return color;
+	}
+
+	return null;
 }
 
-// =============================================================================
-// =============================================================================
 int luma (const QColor& col)
 {
 	return (0.2126f * col.red()) +
 		   (0.7152f * col.green()) +
 		   (0.0722f * col.blue());
 }
+
+int numLDConfigColors()
+{
+	return countof (g_LDConfigColors);
+}
+
+QString LDColorData::indexString() const
+{
+	if (isDirect())
+		return "0x" + QString::number (_index, 16).toUpper();
+
+	return QString::number (_index);
+}
+
+bool LDColorData::isDirect() const
+{
+	return _index >= 0x02000000;
+}
--- a/src/colors.h	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/colors.h	Sat Jun 14 09:05:29 2014 +0300
@@ -20,23 +20,74 @@
 #include <QColor>
 #include "main.h"
 
-#define MAX_COLORS 512
+class LDColor;
+
+class LDColorData
+{
+protected:
+	QString _name;
+	QString _hexcode;
+	QColor _faceColor;
+	QColor _edgeColor;
+	qint32 _index;
+	friend class LDConfigParser;
+	friend class LDColor;
+	friend void initColors();
 
-class LDColor
+public:
+	LDColorData(){}
+
+	readAccess (edgeColor)
+	readAccess (faceColor)
+	readAccess (hexcode)
+	readAccess (index)
+	QString		indexString() const;
+	bool		isDirect() const;
+	readAccess (name)
+};
+
+
+class LDColor : public QSharedPointer<LDColorData>
 {
 public:
-	QString name, hexcode;
-	QColor faceColor, edgeColor;
-	int index;
+	using Super = QSharedPointer<LDColorData>;
+	using Self = LDColor;
+
+	LDColor() : Super() {}
+	LDColor (LDColorData* data) : Super (data) {}
+	LDColor (Super const& other) : Super (other) {}
+	LDColor (QWeakPointer<LDColorData> const& other) : Super (other) {}
+
+	template <typename Deleter>
+	LDColor (LDColorData* data, Deleter dlt) : Super (data, dlt) {}
+
+	inline bool			operator== (Self const& other);
+	inline bool			operator== (decltype(nullptr)) { return data() == nullptr; }
+	inline bool			operator!= (decltype(nullptr)) { return data() != nullptr; }
+	inline LDColorData*	operator->() const { return data(); }
+
+	static void			addLDConfigColor (qint32 index, LDColor color);
+	static LDColor		fromIndex (qint32 index);
 };
 
 void initColors();
 int luma (const QColor& col);
+int numLDConfigColors();
 
-// Safely gets a color with the given number or null if no such color.
-LDColor* getColor (int colnum);
-void setColor (int colnum, LDColor* col);
+// Main and edge colors
+LDColor maincolor();
+LDColor edgecolor();
+static constexpr int mainColorIndex = 16;
+static constexpr int edgeColorIndex = 24;
 
-// Main and edge color identifiers
-static const int maincolor = 16;
-static const int edgecolor = 24;
+bool LDColor::operator== (LDColor const& other)
+{
+	if ((data() == nullptr) ^ (other == nullptr))
+		return false;
+
+	if (data() != nullptr)
+		return data()->index() == other->index();
+
+	// both are null
+	return true;
+}
--- a/src/configDialog.cc	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/configDialog.cc	Sat Jun 14 09:05:29 2014 +0300
@@ -384,7 +384,7 @@
 		}
 		else
 		{
-			LDColor* col = entry.color();
+			LDColor col (entry.color());
 
 			if (col == null)
 			{
@@ -393,7 +393,7 @@
 			}
 			else
 			{
-				item->setText (col->name);
+				item->setText (col->name());
 				item->setIcon (makeColorIcon (col, 16));
 			}
 		}
@@ -432,17 +432,17 @@
 			return; // don't color separators
 	}
 
-	int defval = entry ? entry->color()->index : -1;
-	int val;
+	LDColor defval = entry ? entry->color() : null;
+	LDColor val;
 
 	if (not ColorSelector::selectColor (val, defval, this))
 		return;
 
 	if (entry)
-		entry->setColor (getColor (val));
+		entry->setColor (val);
 	else
 	{
-		LDQuickColor entry (getColor (val), null);
+		LDQuickColor entry (val, null);
 
 		item = getSelectedQuickColor();
 		int idx = (item) ? getItemRow (item, quickColorItems) + 1 : quickColorItems.size();
@@ -711,7 +711,7 @@
 		if (entry.isSeparator())
 			val += '|';
 		else
-			val += format ("%1", entry.color()->index);
+			val += format ("%1", entry.color()->index());
 	}
 
 	return val;
--- a/src/extPrograms.cc	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/extPrograms.cc	Sat Jun 14 09:05:29 2014 +0300
@@ -215,13 +215,13 @@
 
 // =============================================================================
 //
-void writeColorGroup (const int colnum, QString fname)
+void writeColorGroup (LDColor color, QString fname)
 {
 	LDObjectList objects;
 
 	for (LDObjectPtr obj : getCurrentDocument()->objects())
 	{
-		if (not obj->isColored() || obj->color() != colnum)
+		if (not obj->isColored() || obj->color() != color)
 			continue;
 
 		objects << obj;
@@ -288,7 +288,7 @@
 
 // =============================================================================
 //
-static void insertOutput (QString fname, bool replace, QList<int> colorsToReplace)
+static void insertOutput (QString fname, bool replace, QList<LDColor> colorsToReplace)
 {
 #ifdef DEBUG
 	QFile::copy (fname, "./debug_lastOutput");
@@ -309,8 +309,8 @@
 	if (replace)
 		g_win->deleteSelection();
 
-	for (int colnum : colorsToReplace)
-		g_win->deleteByColor (colnum);
+	for (LDColor color : colorsToReplace)
+		g_win->deleteByColor (color);
 
 	// Insert the new objects
 	getCurrentDocument()->clearSelection();
@@ -452,7 +452,7 @@
 								" cutter group with the input group. Both groups are cut by the intersection.");
 	ui.cb_edges->setWhatsThis ("Makes " APPNAME " try run Isecalc to create edgelines for the intersection.");
 
-	int inCol, cutCol;
+	LDColor inCol, cutCol;
 	const bool repeatInverse = ui.cb_repeat->isChecked();
 
 	forever
@@ -460,8 +460,8 @@
 		if (not dlg->exec())
 			return;
 
-		inCol = ui.cmb_incol->itemData (ui.cmb_incol->currentIndex()).toInt();
-		cutCol =  ui.cmb_cutcol->itemData (ui.cmb_cutcol->currentIndex()).toInt();
+		inCol = LDColor::fromIndex (ui.cmb_incol->itemData (ui.cmb_incol->currentIndex()).toInt());
+		cutCol = LDColor::fromIndex (ui.cmb_cutcol->itemData (ui.cmb_cutcol->currentIndex()).toInt());
 
 		if (inCol == cutCol)
 		{
@@ -547,19 +547,19 @@
 	makeColorComboBox (ui.cmb_col1);
 	makeColorComboBox (ui.cmb_col2);
 
-	int in1Col, in2Col;
+	LDColor in1Col, in2Col;
 
 	forever
 	{
 		if (not dlg->exec())
 			return;
 
-		in1Col = ui.cmb_col1->itemData (ui.cmb_col1->currentIndex()).toInt();
-		in2Col = ui.cmb_col2->itemData (ui.cmb_col2->currentIndex()).toInt();
+		in1Col = LDColor::fromIndex (ui.cmb_col1->itemData (ui.cmb_col1->currentIndex()).toInt());
+		in2Col = LDColor::fromIndex (ui.cmb_col2->itemData (ui.cmb_col2->currentIndex()).toInt());
 
 		if (in1Col == in2Col)
 		{
-			critical ("Cannot use the same color group for both input and cutter!");
+			critical ("Cannot use the same color group for both inputs!");
 			continue;
 		}
 
@@ -612,7 +612,7 @@
 	makeColorComboBox (ui.cmb_col1);
 	makeColorComboBox (ui.cmb_col2);
 
-	int in1Col, in2Col;
+	LDColor in1Col, in2Col;
 
 	// Run the dialog and validate input
 	forever
@@ -620,8 +620,8 @@
 		if (not dlg->exec())
 			return;
 
-		in1Col = ui.cmb_col1->itemData (ui.cmb_col1->currentIndex()).toInt(),
-		in2Col = ui.cmb_col1->itemData (ui.cmb_col2->currentIndex()).toInt();
+		in1Col = LDColor::fromIndex (ui.cmb_col1->itemData (ui.cmb_col1->currentIndex()).toInt());
+		in2Col = LDColor::fromIndex (ui.cmb_col2->itemData (ui.cmb_col2->currentIndex()).toInt());
 
 		if (in1Col == in2Col)
 		{
--- a/src/format.h	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/format.h	Sat Jun 14 09:05:29 2014 +0300
@@ -18,6 +18,7 @@
 
 #pragma once
 #include "basics.h"
+#include "colors.h"
 
 //
 // Converts a given value into a string that can be retrieved with text().
@@ -37,6 +38,7 @@
 	StringFormatArg (const Vertex& a) : m_text (a.toString()) {}
 	StringFormatArg (const Matrix& a) : m_text (a.toString()) {}
 	StringFormatArg (const char* a) : m_text (a) {}
+	StringFormatArg (LDColor a) : m_text (a->indexString()) {}
 
 	StringFormatArg (const void* a)
 	{
--- a/src/glCompiler.cc	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/glCompiler.cc	Sat Jun 14 09:05:29 2014 +0300
@@ -155,23 +155,23 @@
 			break;
 
 		case VBOCM_NormalColors:
-			if (poly.color == maincolor)
+			if (poly.color == mainColorIndex)
 			{
-				if (topobj->color() == maincolor)
+				if (topobj->color() == maincolor())
 					qcol = GLRenderer::getMainColor();
 				else
-					qcol = getColor (topobj->color())->faceColor;
+					qcol = topobj->color()->faceColor();
 			}
-			elif (poly.color == edgecolor)
+			elif (poly.color == edgeColorIndex)
 			{
 				qcol = luma (QColor (cfg::backgroundColor)) > 40 ? Qt::black : Qt::white;
 			}
 			else
 			{
-				LDColor* col = getColor (poly.color);
+				LDColor col = LDColor::fromIndex (poly.color);
 
 				if (col)
-					qcol = col->faceColor;
+					qcol = col->faceColor();
 			}
 			break;
 	}
--- a/src/glRenderer.cc	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/glRenderer.cc	Sat Jun 14 09:05:29 2014 +0300
@@ -1452,7 +1452,7 @@
 				for (int i = 0; i < quad->numVertices(); ++i)
 					quad->setVertex (i, m_rectverts[i]);
 
-				quad->setColor (maincolor);
+				quad->setColor (maincolor());
 				objs << quad;
 			}
 			else
@@ -1464,7 +1464,7 @@
 						// 1 vertex - add a vertex object
 						LDVertexPtr obj = spawn<LDVertex>();
 						obj->pos = verts[0];
-						obj->setColor (maincolor);
+						obj->setColor (maincolor());
 						objs << obj;
 					} break;
 
@@ -1472,7 +1472,7 @@
 					{
 						// 2 verts - make a line
 						LDLinePtr obj = spawn<LDLine> (verts[0], verts[1]);
-						obj->setColor (edgecolor);
+						obj->setColor (edgecolor());
 						objs << obj;
 					} break;
 
@@ -1483,7 +1483,7 @@
 							  static_cast<LDObjectPtr> (spawn<LDTriangle>()) :
 							  static_cast<LDObjectPtr> (spawn<LDQuad>());
 
-						obj->setColor (maincolor);
+						obj->setColor (maincolor());
 
 						for (int i = 0; i < obj->numVertices(); ++i)
 							obj->setVertex (i, verts[i]);
@@ -1537,7 +1537,7 @@
 					ref->setFileInfo (refFile);
 					ref->setTransform (getCircleDrawMatrix (cmp.scale));
 					ref->setPosition (m_drawedVerts[0]);
-					ref->setColor (maincolor);
+					ref->setColor (maincolor());
 					objs << ref;
 				}
 			}
@@ -1574,7 +1574,7 @@
 					v3.setCoordinate (relY, v3[relY] + c1[i].y1());
 
 					LDQuadPtr quad (spawn<LDQuad> (v0, v1, v2, v3));
-					quad->setColor (maincolor);
+					quad->setColor (maincolor());
 
 					// Ensure the quads always are BFC-front towards the camera
 					if (camera() % 3 <= 0)
@@ -1590,7 +1590,7 @@
 				ref->setFileInfo (refFile);
 				ref->setTransform (transform);
 				ref->setPosition (m_drawedVerts[0]);
-				ref->setColor (maincolor);
+				ref->setColor (maincolor());
 				objs << ref;
 			}
 		} break;
@@ -2189,7 +2189,7 @@
 	{
 		QString primName = static_cast<SubfileListItem*> (g_win->getPrimitivesTree()->currentItem())->primitive()->name;
 		LDSubfilePtr ref = spawn<LDSubfile>();
-		ref->setColor (maincolor);
+		ref->setColor (maincolor());
 		ref->setFileInfo (getDocument (primName));
 		ref->setPosition (g_origin);
 		ref->setTransform (g_identity);
--- a/src/ldConfig.cc	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/ldConfig.cc	Sat Jun 14 09:05:29 2014 +0300
@@ -41,7 +41,7 @@
 
 // =============================================================================
 //
-void parseLDConfig()
+void LDConfigParser::parseLDConfig()
 {
 	QFile* fp = openLDrawFile ("LDConfig.ldr", false);
 
@@ -108,14 +108,14 @@
 		if (parseLDConfigTag (pars, "ALPHA", valuestr))
 			alpha = clamp (valuestr.toInt(), 0, 255);
 
-		LDColor* col = new LDColor;
-		col->name = name;
-		col->faceColor = faceColor;
-		col->edgeColor = edgeColor;
-		col->hexcode = facename;
-		col->faceColor.setAlpha (alpha);
-		col->index = code;
-		setColor (code, col);
+		LDColor col (new LDColorData);
+		col->_name = name;
+		col->_faceColor = faceColor;
+		col->_edgeColor = edgeColor;
+		col->_hexcode = facename;
+		col->_faceColor.setAlpha (alpha);
+		col->_index = code;
+		LDColor::addLDConfigColor (code, col);
 	}
 
 	fp->close();
--- a/src/ldConfig.h	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/ldConfig.h	Sat Jun 14 09:05:29 2014 +0300
@@ -26,28 +26,28 @@
 //
 class LDConfigParser
 {
-	public:
-		LDConfigParser (QString inText, char sep);
+public:
+	LDConfigParser (QString inText, char sep);
 
-		bool isAtEnd();
-		bool isAtBeginning();
-		bool getNextToken (QString& val);
-		bool peekNextToken (QString& val);
-		bool getToken (QString& val, const int pos);
-		bool findToken (int& result, char const* needle, int args);
-		int getSize();
-		void rewind();
-		void seek (int amount, bool rel);
-		bool tokenCompare (int inPos, const char* sOther);
+	bool isAtEnd();
+	bool isAtBeginning();
+	bool getNextToken (QString& val);
+	bool peekNextToken (QString& val);
+	bool getToken (QString& val, const int pos);
+	bool findToken (int& result, char const* needle, int args);
+	int getSize();
+	void rewind();
+	void seek (int amount, bool rel);
+	bool tokenCompare (int inPos, const char* sOther);
 
-		inline QString operator[] (const int idx)
-		{
-			return m_tokens[idx];
-		}
+	inline QString operator[] (const int idx)
+	{
+		return m_tokens[idx];
+	}
 
-	private:
-		QStringList m_tokens;
-		int m_pos;
+	static void parseLDConfig();
+
+private:
+	QStringList m_tokens;
+	int m_pos;
 };
-
-void parseLDConfig();
--- a/src/ldDocument.cc	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/ldDocument.cc	Sat Jun 14 09:05:29 2014 +0300
@@ -808,17 +808,27 @@
 {
 	bool ok;
 
-	// Check scientific notation, e.g. 7.99361e-15
 	QRegExp scient ("\\-?[0-9]+\\.[0-9]+e\\-[0-9]+");
 
 	for (int i = min; i <= max; ++i)
 	{
-		tokens[i].toDouble (&ok);
+		// Check hex
+		if (tokens[i].startsWith ("0x"))
+		{
+			tokens[i].mid (2).toInt (&ok, 16);
 
-		if (not ok && not scient.exactMatch (tokens[i]))
-		{
-			throw QString (format ("Token #%1 was `%2`, expected a number (matched length: %3)",
-				(i + 1), tokens[i], scient.matchedLength()));
+			if (not ok)
+			{
+				// Check for floating point
+				tokens[i].toDouble (&ok);
+
+				// Also check scientific notation, e.g. 7.99361e-15
+				if (not ok && not scient.exactMatch (tokens[i]))
+				{
+					throw QString (format ("Token #%1 was `%2`, expected a number (matched length: %3)",
+						(i + 1), tokens[i], scient.matchedLength()));
+				}
+			}
 		}
 	}
 }
@@ -832,6 +842,19 @@
 	return v;
 }
 
+static int32 stringToNumber (QString a)
+{
+	int base = 10;
+
+	if (a.startsWith ("0x"))
+	{
+		a.remove (0, 2);
+		base = 16;
+	}
+
+	return a.toLong (null, base);
+}
+
 // =============================================================================
 // This is the LDraw code parser function. It takes in a string containing LDraw
 // code and returns the object parsed from it. parseLine never returns null,
@@ -890,7 +913,7 @@
 						checkTokenNumbers (tokens, 3, 6);
 
 						LDVertexPtr obj = spawn<LDVertex>();
-						obj->setColor (tokens[3].toLong());
+						obj->setColor (LDColor::fromIndex (stringToNumber (tokens[3])));
 						obj->pos.apply ([&](Axis ax, double& value) { value = tokens[4 + ax].toDouble(); });
 						return obj;
 					}
@@ -939,7 +962,7 @@
 				}
 
 				LDSubfilePtr obj = spawn<LDSubfile>();
-				obj->setColor (tokens[1].toLong());
+				obj->setColor (LDColor::fromIndex (stringToNumber (tokens[1])));
 				obj->setPosition (parseVertex (tokens, 2));  // 2 - 4
 
 				Matrix transform;
@@ -959,7 +982,7 @@
 
 				// Line
 				LDLinePtr obj (spawn<LDLine>());
-				obj->setColor (tokens[1].toLong());
+				obj->setColor (LDColor::fromIndex (stringToNumber (tokens[1])));
 
 				for (int i = 0; i < 2; ++i)
 					obj->setVertex (i, parseVertex (tokens, 2 + (i * 3)));   // 2 - 7
@@ -974,7 +997,7 @@
 
 				// Triangle
 				LDTrianglePtr obj (spawn<LDTriangle>());
-				obj->setColor (tokens[1].toLong());
+				obj->setColor (LDColor::fromIndex (stringToNumber (tokens[1])));
 
 				for (int i = 0; i < 3; ++i)
 					obj->setVertex (i, parseVertex (tokens, 2 + (i * 3)));   // 2 - 10
@@ -996,7 +1019,7 @@
 				else
 					obj = spawn<LDCondLine>();
 
-				obj->setColor (tokens[1].toLong());
+				obj->setColor (LDColor::fromIndex (stringToNumber (tokens[1])));
 
 				for (int i = 0; i < 4; ++i)
 					obj->setVertex (i, parseVertex (tokens, 2 + (i * 3)));   // 2 - 13
--- a/src/ldObject.cc	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/ldObject.cc	Sat Jun 14 09:05:29 2014 +0300
@@ -325,7 +325,7 @@
 
 // =============================================================================
 //
-static void transformObject (LDObjectPtr obj, Matrix transform, Vertex pos, int parentcolor)
+static void transformObject (LDObjectPtr obj, Matrix transform, Vertex pos, LDColor parentcolor)
 {
 	switch (obj->type())
 	{
@@ -358,7 +358,7 @@
 			break;
 	}
 
-	if (obj->color() == maincolor)
+	if (obj->color() == maincolor())
 		obj->setColor (parentcolor);
 }
 
@@ -396,7 +396,7 @@
 	LDPolygon* data = new LDPolygon;
 	data->id = id();
 	data->num = num;
-	data->color = color();
+	data->color = color()->index();
 
 	for (int i = 0; i < data->numVertices(); ++i)
 		data->vertices[i] = vertex (i);
@@ -809,7 +809,7 @@
 
 // =============================================================================
 //
-void LDObject::setColor (const int& val)
+void LDObject::setColor (LDColor const& val)
 {
 	changeProperty (self(), &m_color, val);
 }
--- a/src/ldObject.h	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/ldObject.h	Sat Jun 14 09:05:29 2014 +0300
@@ -21,6 +21,7 @@
 #include "main.h"
 #include "basics.h"
 #include "glShared.h"
+#include "colors.h"
 
 #define LDOBJ(T)												\
 public:															\
@@ -93,7 +94,7 @@
 	PROPERTY (public,		LDObjectWeakPtr,	parent,			setParent,		STOCK_WRITE)
 	PROPERTY (public,		LDDocumentWeakPtr,	document,		setDocument,	STOCK_WRITE)
 	PROPERTY (private,		int32,				id,				setID,			STOCK_WRITE)
-	PROPERTY (public,		int,				color,			setColor,		CUSTOM_WRITE)
+	PROPERTY (public,		LDColor,			color,			setColor,		CUSTOM_WRITE)
 	PROPERTY (private,		QColor,				randomColor,	setRandomColor,	STOCK_WRITE)
 	PROPERTY (private,		LDObjectWeakPtr,	self,			setSelf,		STOCK_WRITE)
 
--- a/src/macros.h	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/macros.h	Sat Jun 14 09:05:29 2014 +0300
@@ -60,6 +60,9 @@
 #define PROPERTY_CUSTOM_WRITE(READ)								\
 	;
 
+#define readAccess(A) inline decltype(_##A) A() const { return _##A; }
+#define writeAccess(A,B) inline void B (decltype(_##A) const& a) const { _##A = a; }
+
 // =============================================================================
 //
 #define elif(A) else if (A)
--- a/src/mainWindow.cc	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/mainWindow.cc	Sat Jun 14 09:05:29 2014 +0300
@@ -203,7 +203,7 @@
 			colors << LDQuickColor::getSeparator();
 		else
 		{
-			LDColor* col = getColor (colorname.toLong());
+			LDColor col = LDColor::fromIndex (colorname.toLong());
 
 			if (col != null)
 				colors << LDQuickColor (col, null);
@@ -231,7 +231,7 @@
 			QToolButton* colorButton = new QToolButton;
 			colorButton->setIcon (makeColorIcon (entry.color(), 16));
 			colorButton->setIconSize (QSize (16, 16));
-			colorButton->setToolTip (entry.color()->name);
+			colorButton->setToolTip (entry.color()->name());
 
 			connect (colorButton, SIGNAL (clicked()), this, SLOT (slot_quickColor()));
 			ui->colorToolbar->addWidget (colorButton);
@@ -424,14 +424,11 @@
 			item->setForeground (QColor ("#FFAA00"));
 		}
 		elif (cfg::colorizeObjectsList && obj->isColored() &&
-			obj->color() != maincolor && obj->color() != edgecolor)
+			obj->color() != null && obj->color() != maincolor() && obj->color() != edgecolor())
 		{
 			// If the object isn't in the main or edge color, draw this
 			// list entry in said color.
-			LDColor* col = getColor (obj->color());
-
-			if (col)
-				item->setForeground (col->faceColor);
+			item->setForeground (obj->color()->faceColor());
 		}
 
 		obj->qObjListEntry = item;
@@ -506,7 +503,7 @@
 void MainWindow::slot_quickColor()
 {
 	QToolButton* button = static_cast<QToolButton*> (sender());
-	LDColor* col = null;
+	LDColor col = null;
 
 	for (const LDQuickColor& entry : m_quickColors)
 	{
@@ -520,14 +517,12 @@
 	if (col == null)
 		return;
 
-	int newColor = col->index;
-
 	for (LDObjectPtr obj : selection())
 	{
 		if (not obj->isColored())
 			continue; // uncolored object
 
-		obj->setColor (newColor);
+		obj->setColor (col);
 		R()->compileObject (obj);
 	}
 
@@ -584,19 +579,19 @@
 
 // =============================================================================
 //
-int MainWindow::getSelectedColor()
+LDColor MainWindow::getSelectedColor()
 {
-	int result = -1;
+	LDColor result;
 
 	for (LDObjectPtr obj : selection())
 	{
 		if (not obj->isColored())
 			continue; // doesn't use color
 
-		if (result != -1 && obj->color() != result)
-			return -1; // No consensus in object color
+		if (result != null && obj->color() != result)
+			return null; // No consensus in object color
 
-		if (result == -1)
+		if (result == null)
 			result = obj->color();
 	}
 
@@ -689,13 +684,13 @@
 
 // =============================================================================
 //
-void MainWindow::deleteByColor (int colnum)
+void MainWindow::deleteByColor (LDColor color)
 {
 	LDObjectList objs;
 
 	for (LDObjectPtr obj : getCurrentDocument()->objects())
 	{
-		if (not obj->isColored() || obj->color() != colnum)
+		if (not obj->isColored() || obj->color() != color)
 			continue;
 
 		objs << obj;
@@ -828,14 +823,14 @@
 
 // =============================================================================
 //
-QIcon makeColorIcon (LDColor* colinfo, const int size)
+QIcon makeColorIcon (LDColor colinfo, const int size)
 {
 	// Create an image object and link a painter to it.
 	QImage img (size, size, QImage::Format_ARGB32);
 	QPainter paint (&img);
-	QColor col = colinfo->faceColor;
+	QColor col = colinfo->faceColor();
 
-	if (colinfo->index == maincolor)
+	if (colinfo == maincolor())
 	{
 		// Use the user preferences for main color here
 		col = cfg::mainColor;
@@ -843,7 +838,7 @@
 	}
 
 	// Paint the icon border
-	paint.fillRect (QRect (0, 0, size, size), colinfo->edgeColor);
+	paint.fillRect (QRect (0, 0, size, size), colinfo->edgeColor());
 
 	// Paint the checkerboard background, visible with translucent icons
 	paint.drawPixmap (QRect (1, 1, size - 2, size - 2), getIcon ("checkerboard"), QRect (0, 0, 8, 8));
@@ -857,11 +852,11 @@
 //
 void makeColorComboBox (QComboBox* box)
 {
-	std::map<int, int> counts;
+	std::map<LDColor, int> counts;
 
 	for (LDObjectPtr obj : getCurrentDocument()->objects())
 	{
-		if (not obj->isColored())
+		if (not obj->isColored() || obj->color() == null)
 			continue;
 
 		if (counts.find (obj->color()) == counts.end())
@@ -875,13 +870,10 @@
 
 	for (const auto& pair : counts)
 	{
-		LDColor* col = getColor (pair.first);
-		assert (col != null);
-
-		QIcon ico = makeColorIcon (col, 16);
+		QIcon ico = makeColorIcon (pair.first, 16);
 		box->addItem (ico, format ("[%1] %2 (%3 object%4)",
-			pair.first, col->name, pair.second, plural (pair.second)));
-		box->setItemData (row, pair.first);
+			pair.first, pair.first->name(), pair.second, plural (pair.second)));
+		box->setItemData (row, pair.first->index());
 
 		++row;
 	}
@@ -1012,7 +1004,7 @@
 
 // =============================================================================
 //
-LDQuickColor::LDQuickColor (LDColor* color, QToolButton* toolButton) :
+LDQuickColor::LDQuickColor (LDColor color, QToolButton* toolButton) :
 	m_color (color),
 	m_toolButton (toolButton) {}
 
--- a/src/mainWindow.h	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/mainWindow.h	Sat Jun 14 09:05:29 2014 +0300
@@ -24,10 +24,11 @@
 #include "configuration.h"
 #include "ldObject.h"
 #include "ui_ldforge.h"
+#include "colors.h"
 
 class MessageManager;
 class MainWindow;
-class LDColor;
+class LDColorData;
 class QToolButton;
 class QDialogButtonBox;
 class GLRenderer;
@@ -58,11 +59,11 @@
 // =============================================================================
 class LDQuickColor
 {
-	PROPERTY (public,	LDColor*,		color,		setColor,		STOCK_WRITE)
+	PROPERTY (public,	LDColor,		color,		setColor,		STOCK_WRITE)
 	PROPERTY (public,	QToolButton*,	toolButton,	setToolButton,	STOCK_WRITE)
 
 	public:
-		LDQuickColor (LDColor* color, QToolButton* toolButton);
+		LDQuickColor (LDColor color, QToolButton* toolButton);
 		bool isSeparator() const;
 
 		static LDQuickColor getSeparator();
@@ -129,7 +130,7 @@
 
 	// Returns the uniform selected color (i.e. 4 if everything selected is
 	// red), -1 if there is no such consensus.
-	int getSelectedColor();
+	LDColor getSelectedColor();
 
 	// Automatically scrolls the object list so that it points to the first
 	// selected object.
@@ -142,7 +143,7 @@
 	int deleteSelection();
 
 	// Deletes all objects by the given color number.
-	void deleteByColor (int colnum);
+	void deleteByColor (LDColor color);
 
 	// Tries to save the given document.
 	bool save (LDDocumentPtr doc, bool saveAs);
@@ -331,7 +332,7 @@
 void critical (const QString& message);
 
 //! Makes an icon of \c size x \c size pixels to represent \c colinfo
-QIcon makeColorIcon (LDColor* colinfo, const int size);
+QIcon makeColorIcon (LDColor colinfo, const int size);
 
 //! Fills the given combo-box with color information
 void makeColorComboBox (QComboBox* box);
--- a/src/primitives.cc	Thu Jun 05 23:18:13 2014 +0300
+++ b/src/primitives.cc	Sat Jun 14 09:05:29 2014 +0300
@@ -420,7 +420,7 @@
 				LDLinePtr line (spawn<LDLine>());
 				line->setVertex (0, v0);
 				line->setVertex (1, v1);
-				line->setColor (edgecolor);
+				line->setColor (edgecolor());
 				objs << line;
 			} break;
 
@@ -468,7 +468,7 @@
 					   v3 (x3, y3, z3);
 
 				LDQuadPtr quad (spawn<LDQuad> (v0, v1, v2, v3));
-				quad->setColor (maincolor);
+				quad->setColor (maincolor());
 
 				if (type == Cylinder)
 					quad->invert();
@@ -499,7 +499,7 @@
 				// Disc negatives need to go the other way around, otherwise
 				// they'll end up upside-down.
 				LDTrianglePtr seg (spawn<LDTriangle>());
-				seg->setColor (maincolor);
+				seg->setColor (maincolor());
 				seg->setVertex (type == Disc ? 0 : 2, v0);
 				seg->setVertex (1, v1);
 				seg->setVertex (type == Disc ? 2 : 0, v2);
@@ -533,7 +533,7 @@
 		}
 
 		LDCondLinePtr line = (spawn<LDCondLine>());
-		line->setColor (edgecolor);
+		line->setColor (edgecolor());
 		line->setVertex (0, v0);
 		line->setVertex (1, v1);
 		line->setVertex (2, v2);
--- a/ui/colorsel.ui	Thu Jun 05 23:18:13 2014 +0300
+++ b/ui/colorsel.ui	Sat Jun 14 09:05:29 2014 +0300
@@ -6,14 +6,14 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>382</width>
-    <height>442</height>
+    <width>402</width>
+    <height>539</height>
    </rect>
   </property>
   <property name="windowTitle">
-   <string>Pick a Color</string>
+   <string>Select Color</string>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
+  <layout class="QVBoxLayout" name="verticalLayout_2">
    <item>
     <widget class="QGraphicsView" name="viewport">
      <property name="verticalScrollBarPolicy">
@@ -27,6 +27,13 @@
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
+      <widget class="QLabel" name="iconLabel">
+       <property name="text">
+        <string>[[ COLOR ICON HERE]]</string>
+       </property>
+      </widget>
+     </item>
+     <item>
       <widget class="QLabel" name="colorLabel">
        <property name="text">
         <string>[[ COLOR HERE ]]</string>
@@ -46,6 +53,27 @@
        </property>
       </spacer>
      </item>
+     <item>
+      <layout class="QVBoxLayout" name="verticalLayout">
+       <item>
+        <widget class="QPushButton" name="directColor">
+         <property name="toolTip">
+          <string>Direct Color...</string>
+         </property>
+         <property name="text">
+          <string>Direct Color...</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QCheckBox" name="transparentDirectColor">
+         <property name="text">
+          <string>Transparent</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
     </layout>
    </item>
    <item>
@@ -60,7 +88,9 @@
    </item>
   </layout>
  </widget>
- <resources/>
+ <resources>
+  <include location="../ldforge.qrc"/>
+ </resources>
  <connections>
   <connection>
    <sender>buttonBox</sender>

mercurial