From b6713e570a22f49f296f28095a541c802a31ed14 Mon Sep 17 00:00:00 2001 From: Serge Ziryukin Date: Fri, 2 Apr 2010 21:52:17 +0300 Subject: [PATCH] color scheme, randomizing, state saving/restore --- colorflood/src/CMakeLists.txt | 1 + colorflood/src/colorscheme.cpp | 87 +++++++++++++++++++++++++++++++++++ colorflood/src/colorscheme.hpp | 45 +++++++++++++++++++ colorflood/src/field.cpp | 97 +++++++++++++++++++++++++++++----------- colorflood/src/field.hpp | 20 ++++----- colorflood/src/window.cpp | 40 +++++++---------- colorflood/src/window.hpp | 3 ++ 7 files changed, 233 insertions(+), 60 deletions(-) create mode 100644 colorflood/src/colorscheme.cpp create mode 100644 colorflood/src/colorscheme.hpp diff --git a/colorflood/src/CMakeLists.txt b/colorflood/src/CMakeLists.txt index e3d2778..719fbf0 100644 --- a/colorflood/src/CMakeLists.txt +++ b/colorflood/src/CMakeLists.txt @@ -13,6 +13,7 @@ set(src field.cpp main.cpp window.cpp + colorscheme.cpp ) set(moc diff --git a/colorflood/src/colorscheme.cpp b/colorflood/src/colorscheme.cpp new file mode 100644 index 0000000..c7cd4be --- /dev/null +++ b/colorflood/src/colorscheme.cpp @@ -0,0 +1,87 @@ +/* + Copyright 2010 Serge Ziryukin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +*/ + +#include +#include "colorscheme.hpp" + +static int currentScheme = 0; +static QVector > > schemes; + +ColorScheme::ColorScheme () +{ + schemes.clear(); + + QVector s; + + s << QColor(0x00, 0x00, 0xff); // blue + s << QColor(0xff, 0x00, 0x00); // red + s << QColor(0x00, 0xff, 0x00); // green + s << QColor(0xff, 0xff, 0x00); // yellow + s << QColor(0xff, 0x00, 0xff); // magenta + s << QColor(0x80, 0x00, 0x80); // purple + schemes << QPair >(QObject::tr("Default"), s); + + s.clear(); + s << QBrush(QColor(0x00, 0x00, 0x00), Qt::SolidPattern); + s << QBrush(QColor(0x33, 0x33, 0x33), Qt::Dense3Pattern); + s << QBrush(QColor(0x66, 0x66, 0x66), Qt::Dense1Pattern); + s << QBrush(QColor(0x99, 0x99, 0x99), Qt::SolidPattern); + s << QBrush(QColor(0xcc, 0xcc, 0xcc), Qt::CrossPattern); + s << QBrush(QColor(0xff, 0xff, 0xff), Qt::SolidPattern); + schemes << QPair >(QObject::tr("Black-and-white"), s); + + QSettings settings; + currentScheme = settings.value("colorScheme", 0).toInt(); + + if (currentScheme < 0 || currentScheme > s.size()) + currentScheme = 0; +} + +ColorScheme::~ColorScheme () +{ + QSettings settings; + settings.setValue("colorScheme", currentScheme); +} + +int ColorScheme::getNumSchemes () +{ + return schemes.size(); +} + +QString ColorScheme::getSchemeName (int scheme) +{ + Q_ASSERT(scheme > 0 && scheme < getNumSchemes()); + return schemes.at(scheme).first; +} + +const QVector &ColorScheme::getScheme (int scheme) +{ + Q_ASSERT(scheme > 0 && scheme < getNumSchemes()); + return schemes.at(scheme).second; +} + +QString ColorScheme::getSchemeName () +{ + return schemes.at(currentScheme).first; +} + +const QVector &ColorScheme::getScheme () +{ + return schemes.at(currentScheme).second; +} + +void ColorScheme::setScheme (int scheme) +{ + Q_ASSERT(scheme >= 0 && scheme < getNumSchemes()); + currentScheme = scheme; +} diff --git a/colorflood/src/colorscheme.hpp b/colorflood/src/colorscheme.hpp new file mode 100644 index 0000000..c366def --- /dev/null +++ b/colorflood/src/colorscheme.hpp @@ -0,0 +1,45 @@ +/* + Copyright 2010 Serge Ziryukin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +*/ + +#ifndef _COLORSCHEME_HPP +#define _COLORSCHEME_HPP + +#include +#include +#include +#include + +class ColorScheme +{ +public: + static ColorScheme & instance () + { + static ColorScheme instance; + return instance; + } + + static int getNumSchemes (); + static QString getSchemeName (int scheme); + const QVector &getScheme (int scheme); + static QString getSchemeName (); + const QVector &getScheme (); + static void setScheme (int scheme); + +private: + ColorScheme (); + ~ColorScheme (); + ColorScheme (const ColorScheme &); + ColorScheme & operator= (const ColorScheme &); +}; + +#endif /* !_COLORSCHEME_HPP */ diff --git a/colorflood/src/field.cpp b/colorflood/src/field.cpp index d47250a..3465e78 100644 --- a/colorflood/src/field.cpp +++ b/colorflood/src/field.cpp @@ -13,27 +13,82 @@ #include #include "field.hpp" +#include "colorscheme.hpp" static const int fieldWidth = 420; const int Field::rects[Field::NUM_SIZES] = { 14, 21, 28 }; const int Field::turns[Field::NUM_SIZES] = { 25, 35, 50 }; -Field::Field (QWidget *parent) - : QWidget (parent) +// we declare out QVector metatype +// and stream operators to save whole field to settings +Q_DECLARE_METATYPE(Field::RectVector); + +static QDataStream &operator<< (QDataStream &out, const Field::RectVector &rv) { - // FIXME -- restore saved state + for (QVector::const_iterator rect = rv.begin(); + rect != rv.end(); + rect++) + { + out << (*rect).brush; + out << (*rect).flood; + } + + return out; } -Field::Field (QWidget *parent, const QVector &brushes, FieldSize size) +static QDataStream &operator>> (QDataStream &in, Field::RectVector &rv) +{ + Field::FieldRect r; + + rv.clear(); + + for (; !in.atEnd() ;) + { + in >> r.brush >> r.flood; + rv << r; + } + + rv.pop_back(); + + return in; +} + +Field::Field (QWidget *parent) : QWidget (parent) { - init(brushes, size); + setFixedSize(fieldWidth, fieldWidth); + + // restore field size and field itself from settings + + qRegisterMetaType("Field::RectVector"); + qRegisterMetaTypeStreamOperators("Field::RectVector"); + + QSettings settings; + + int size = settings.value("field/fieldSize", SIZE_SMALL).toInt(); + + if (size < SIZE_SMALL || size >= NUM_SIZES) + size = SIZE_SMALL; + + this->size = (FieldSize)size; + + if (settings.contains("field/data")) + data = settings.value("field/data").value(); + + if (data.size() != rects[size] * rects[size]) + randomize(); } Field::~Field () { - // FIXME -- save state + QSettings settings; + + settings.setValue("field/size", size); + + QVariant v; + v.setValue(data); + settings.setValue("field/data", v); } Field::FieldSize Field::getSize () const @@ -41,27 +96,26 @@ Field::FieldSize Field::getSize () const return size; } -/* -================= -randomize -================= -*/ void Field::randomize () { - Field::FieldRect rect; + FieldRect rect; rect.flood = false; data.clear(); - data = QVector (rects[size] * rects[size], rect); + data = RectVector(rects[size] * rects[size], rect); qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime())); - for (QVector::iterator rect = data.begin(); + int numBrushes = ColorScheme::instance().getScheme().size(); + + for (QVector::iterator rect = data.begin(); rect != data.end(); rect++) { - (*rect).brush = qrand() % brushes.size(); + (*rect).brush = qrand() % numBrushes; } + + update(); } int Field::getNumRectsOfSize (FieldSize size) @@ -74,15 +128,6 @@ int Field::getNumTurnsOfSize (FieldSize size) return turns[size]; } -void Field::init (const QVector &brushes, FieldSize size) -{ - this->size = size; - this->brushes = brushes; - - setFixedSize(fieldWidth, fieldWidth); - randomize(); -} - int Field::getRectSize (FieldSize size) { return fieldWidth / rects[size]; @@ -95,6 +140,8 @@ void Field::paintEvent (QPaintEvent *event) QRect rect = QRect(0, 0, getRectSize(size), getRectSize(size)); + const QVector &scheme = ColorScheme::instance().getScheme(); + for (int y = 0; y < rects[size] ;y++) { int n = y * rects[size]; @@ -104,7 +151,7 @@ void Field::paintEvent (QPaintEvent *event) rect.moveTo(x * rect.width(), y * rect.height()); if (rect.intersects(event->rect())) - painter.fillRect(rect, brushes.at(data[n].brush)); + painter.fillRect(rect, scheme.at(data[n].brush)); } } diff --git a/colorflood/src/field.hpp b/colorflood/src/field.hpp index 06ccf28..0d78d34 100644 --- a/colorflood/src/field.hpp +++ b/colorflood/src/field.hpp @@ -33,7 +33,14 @@ public: NUM_SIZES }FieldSize; - Field (QWidget *parent, const QVector &brushes, FieldSize size); + typedef struct + { + quint8 brush; + bool flood; + }FieldRect; + + typedef QVector RectVector; + Field (QWidget *parent); ~Field (); @@ -44,21 +51,14 @@ public: static int getNumTurnsOfSize (FieldSize size); private: - typedef struct - { - char brush; - bool flood; - }FieldRect; - static const int rects[NUM_SIZES]; static const int turns[NUM_SIZES]; void init (const QVector &brushes, FieldSize size); static int getRectSize (FieldSize size); - FieldSize size; - QVector brushes; - QVector data; + FieldSize size; + RectVector data; protected: void paintEvent (QPaintEvent *event); diff --git a/colorflood/src/window.cpp b/colorflood/src/window.cpp index 0ee5554..a189dcf 100644 --- a/colorflood/src/window.cpp +++ b/colorflood/src/window.cpp @@ -18,34 +18,24 @@ Window::Window () : QWidget() { - setWindowTitle(tr("Color flood")); - - setWindowState(windowState() | Qt::WindowFullScreen); - - QVector brushes; - -#if 1 - // standart color scheme - brushes << QBrush(QColor(0x00, 0x00, 0xff)); // blue - brushes << QBrush(QColor(0xff, 0x00, 0x00)); // red - brushes << QBrush(QColor(0x00, 0xff, 0x00)); // green - brushes << QBrush(QColor(0xff, 0xff, 0x00)); // yellow - brushes << QBrush(QColor(0xff, 0x00, 0xff)); // magenta - brushes << QBrush(QColor(0x80, 0x00, 0x80)); // purple -#else - // color-blind color scheme - brushes << QBrush(QColor(0x00, 0x00, 0x00)); - brushes << QBrush(QColor(0x31, 0x31, 0x31), Qt::Dense1Pattern); - brushes << QBrush(QColor(0x62, 0x62, 0x62), Qt::Dense3Pattern); - brushes << QBrush(QColor(0x93, 0x93, 0x93), Qt::CrossPattern); - brushes << QBrush(QColor(0xc4, 0xc4, 0xc4)); - brushes << QBrush(QColor(0xff, 0xff, 0xff)); -#endif - - field = new Field(this, brushes, Field::SIZE_LARGE); + setWindowTitle(tr("Color Flood")); + + //setWindowState(windowState() | Qt::WindowFullScreen); + + QPushButton *button = new QPushButton("randomize", this); + field = new Field(this); + + QObject::connect(button, SIGNAL(pressed()), this, SLOT(randomize())); QHBoxLayout *layout = new QHBoxLayout; + layout->addWidget(button); + layout->setAlignment(button, Qt::AlignLeft); layout->addWidget(field); layout->setAlignment(field, Qt::AlignRight); setLayout(layout); } + +void Window::randomize () +{ + field->randomize(); +} diff --git a/colorflood/src/window.hpp b/colorflood/src/window.hpp index b76d9b1..808b89f 100644 --- a/colorflood/src/window.hpp +++ b/colorflood/src/window.hpp @@ -25,6 +25,9 @@ class Window : public QWidget public: Window (); +public slots: + void randomize (); + private: Field *field; }; -- 1.7.9.5