Sat, 14 Jun 2014 09:05:29 +0300
- changed all color usage to use LDColor classes instead of color indices. Added support for direct colors.
--- 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>