-
-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Color enhance #104
Color enhance #104
Changes from 7 commits
4de8a95
291e77c
da5e955
a3a19f4
d745453
1cd7434
ea7252c
7a2ea46
d3bee93
bd0f884
1363d50
52acd14
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,18 +28,83 @@ | |
***************************************************************************/ | ||
#include "ColorButton.h" | ||
|
||
#include <QColorDialog> | ||
#include <QPalette> | ||
#include <QPushButton> | ||
#include <QHBoxLayout> | ||
#include <QFrame> | ||
|
||
const QColor ColorButton::colors[] = { | ||
QColor(Qt::black), | ||
QColor(Qt::red), | ||
QColor(Qt::green), | ||
QColor(Qt::blue), | ||
QColor(Qt::cyan), | ||
QColor(Qt::magenta), | ||
QColor(Qt::yellow), | ||
QColor(Qt::darkYellow), | ||
QColor(Qt::darkBlue), | ||
QColor(Qt::darkMagenta), | ||
QColor(Qt::darkRed), | ||
QColor(Qt::darkGreen), | ||
QColor(Qt::darkCyan), | ||
QColor("#0000A0"), | ||
QColor("#FF8000"), | ||
QColor("#8000FF"), | ||
QColor("#FF0080"), | ||
QColor(Qt::white), | ||
QColor(Qt::lightGray), | ||
QColor(Qt::gray), | ||
QColor("#FFFF80"), | ||
QColor("#80FFFF"), | ||
QColor("#FF80FF"), | ||
QColor(Qt::darkGray), | ||
// additional colors from figure 6 in doi:10.1016/j.csda.2008.11.033 | ||
QColor("#023fa5"), | ||
QColor("#4a6fe3"), | ||
QColor("#11c638"), | ||
QColor("#0fcfc0"), | ||
QColor("#8e063b"), | ||
QColor("#d33f6a"), | ||
QColor("#ef9708"), | ||
QColor("#f79cd4"), | ||
QColor("#7d87b9"), | ||
QColor("#8595e1"), | ||
QColor("#8dd593"), | ||
QColor("#9cded6"), | ||
QColor("#bb7784"), | ||
QColor("#e07b91"), | ||
QColor("#f0b98d"), | ||
QColor("#f6c4e1"), | ||
QColor("#bec1d4"), | ||
QColor("#b5bbe3"), | ||
QColor("#c6dec7"), | ||
QColor("#d5eae7"), | ||
QColor("#d6bcc0"), | ||
QColor("#e6afb9"), | ||
QColor("#ead3c6"), | ||
QColor("#f3e1eb"), | ||
}; | ||
|
||
const unsigned int ColorButton::colors_count=sizeof(colors)/sizeof(colors[0]); | ||
|
||
ColorButton::ColorButton(QWidget *parent) : QWidget(parent) | ||
{ | ||
init(); | ||
} | ||
|
||
void ColorButton::init() | ||
{ | ||
// QColorDialog has 48 basic colors in a 6x8 grid. Using: | ||
// for (int i=0; i < colors_count; i++) {QColorDialog::setStandardColor(i, colors[i].rgb());}; | ||
// arranges the colors in columns of 6. Instead arrange them in rows of 8 colors each. | ||
for (int i=0; i<8; i++) | ||
{ | ||
for (int j=0; j<6; j++) | ||
{ | ||
QColorDialog::setStandardColor(j+6*i, colors[i+8*j].rgb()); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The magic numbers 8 and 3 bother me a bit. I assume that maybe the dialog is perhaps 8x3 or something? At very least, there should be a static_assert that 8*3 <= colors_count. Also what happens to standard colours 3,4,5, 9,10,11, ...? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. QColorDialog has 48 basic colors in a 6x8 grid. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe a comment along the lines of rearranging the stand ard layout of standard colours might be useful. It puzzled me why you were only allocating half the colours. The static_assert might also be useful, in case someone decides to remove some from the list, or monkey around with the magic numbers. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm still keen on the static_assert: static_assert(8*6 <= colours_count, "not enough default colors"); Better still, name the 8 and the 6, and use the names both in the loop and the assert. That way, as soon as anyone touches this in an invalid way, it will thow up a compiler error. |
||
const int btn_size = 28; | ||
selectButton = new QPushButton(QPixmap(":/palette.xpm"), QString(), this); | ||
selectButton->setMinimumWidth(btn_size); | ||
|
@@ -61,22 +126,60 @@ void ColorButton::init() | |
setMaximumWidth(3*btn_size); | ||
setMaximumHeight(btn_size); | ||
|
||
connect(selectButton, SIGNAL(clicked()), this, SIGNAL(clicked())); | ||
connect(selectButton, SIGNAL(clicked()), this, SLOT(pickColor())); | ||
} | ||
|
||
void ColorButton::setColor(const QColor& c) | ||
{ | ||
QPalette pal; | ||
pal.setColor(QPalette::Window, c); | ||
display->setPalette(pal); | ||
emit changed(c); | ||
} | ||
|
||
QColor ColorButton::color() const | ||
{ | ||
return display->palette().color(QPalette::Window); | ||
} | ||
|
||
unsigned int ColorButton::colorIndex(const QColor& c) | ||
{ | ||
const QColor *ite = std::find(std::begin(colors), std::end(colors), c); | ||
if (ite->isValid()) | ||
return (ite - colors); | ||
else | ||
return c.rgba(); | ||
} | ||
highperformancecoder marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
QColor ColorButton::color(unsigned int colorIndex) | ||
{ | ||
if (colorIndex < colors_count) | ||
return colors[colorIndex]; | ||
else | ||
{ | ||
QColor qc = QColor::fromRgba(colorIndex); | ||
if (qc.isValid()) | ||
return qc; | ||
else | ||
return QColor(Qt::black); // default color is black. | ||
} | ||
} | ||
|
||
bool ColorButton::isValidColor(const QColor& c) | ||
{ | ||
const QColor *ite = std::find(std::begin(colors), std::end(colors), c); | ||
return (ite->isValid()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dereferencing the end of a sequence (as what happens if the colour is not found) has undefined behaviour, and could even cause a null dereference crash. The return test could be as simple as ite-color < colors_count, or to be more std libraryish ite!=std::end(colors) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Qt takes care of all that trouble. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think so. std::find returns an iterator pointing to the end of the sequence, which in this case will be a pointer to one past the end the colour array. ite->isValid() is completely undefined - the compiler could initialise the memory past the end of the array to zero, or some garbage pattern, or it may put a properly initialised default QColor, or it may remain uninitialised to some random value. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess Qt appends a properly initialised QColor(Invalid) at end of array at the constructor, because that is what I get when I test the code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not Qt. It's your compiler. Someone else's compiler may do it differently. Next year, your compiler may do it differently. It is not good to rely on it. |
||
} | ||
|
||
QSize ColorButton::sizeHint () const | ||
{ | ||
return QSize(4*btn_size, btn_size); | ||
} | ||
|
||
void ColorButton::pickColor() | ||
{ | ||
QColor c = QColorDialog::getColor(color(), this, "Select color", QColorDialog::DontUseNativeDialog | QColorDialog::ShowAlphaChannel); | ||
if ( !c.isValid() || c == color() ) | ||
return; | ||
setColor ( c ) ; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your comment is still slightly confusing - given a 6x8 grid, columns of 6 is the same thing as rows of 8.
You could simply say "transpose the 6x8 grid", which is what you're actually doing.